Deploy docs preview and staging #906
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Deploy docs preview and staging | |
| on: | |
| workflow_run: | |
| workflows: [Build docs] | |
| types: [completed] | |
| permissions: | |
| actions: read | |
| contents: read | |
| issues: write | |
| pull-requests: write | |
| concurrency: | |
| group: docs-deploy-${{ github.event.workflow_run.head_branch }} | |
| cancel-in-progress: true | |
| jobs: | |
| preview: | |
| name: Deploy PR preview | |
| if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Resolve preview action | |
| id: preview | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| RUN_ID: ${{ github.event.workflow_run.id }} | |
| HEAD_SHA: ${{ github.event.workflow_run.head_sha }} | |
| run: | | |
| set -euo pipefail | |
| control_name="$(gh api "repos/${GITHUB_REPOSITORY}/actions/runs/${RUN_ID}/artifacts" \ | |
| --jq '[.artifacts[] | select(.expired == false) | .name | select(startswith("docs-control-pr-"))] | if length == 1 then .[0] else error("expected exactly one docs control artifact") end')" | |
| [[ "${control_name}" =~ ^docs-control-pr-([0-9]+)-(opened|synchronize|reopened|closed)$ ]] | |
| pr_number="${BASH_REMATCH[1]}" | |
| action="${BASH_REMATCH[2]}" | |
| mode=cleanup | |
| if [ "${action}" != closed ]; then | |
| pr_json="$(gh api "repos/${GITHUB_REPOSITORY}/pulls/${pr_number}")" | |
| if [ "$(jq -r .state <<< "${pr_json}")" != open ]; then | |
| mode=cleanup | |
| elif [ "$(jq -r .head.sha <<< "${pr_json}")" != "${HEAD_SHA}" ]; then | |
| echo "mode=stale" >> "${GITHUB_OUTPUT}" | |
| exit 0 | |
| else | |
| mode=deploy | |
| fi | |
| fi | |
| { | |
| echo "mode=${mode}" | |
| echo "pr-number=${pr_number}" | |
| echo "path=preview/pr-${pr_number}/" | |
| echo "url=https://vide.pascal-lab.net/preview/pr-${pr_number}/" | |
| } >> "${GITHUB_OUTPUT}" | |
| - name: Download PR documentation | |
| if: steps.preview.outputs.mode == 'deploy' | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: docs-site-pr-${{ steps.preview.outputs.pr-number }} | |
| run-id: ${{ github.event.workflow_run.id }} | |
| github-token: ${{ github.token }} | |
| path: docs-dist | |
| - name: Setup ossutil | |
| if: steps.preview.outputs.mode != 'stale' | |
| uses: ./.github/actions/setup-ossutil | |
| with: | |
| endpoint: ${{ secrets.endpoint }} | |
| access-key-id: ${{ secrets.accessKeyId }} | |
| access-key-secret: ${{ secrets.accessKeySecret }} | |
| - name: Deploy PR documentation | |
| if: steps.preview.outputs.mode == 'deploy' | |
| env: | |
| BUCKET: ${{ secrets.bucketName }} | |
| PREVIEW_PATH: ${{ steps.preview.outputs.path }} | |
| run: ossutil sync docs-dist/ "oss://${BUCKET}/${PREVIEW_PATH}" --delete -f --disable-ignore-error | |
| - name: Remove PR documentation | |
| if: steps.preview.outputs.mode == 'cleanup' | |
| env: | |
| BUCKET: ${{ secrets.bucketName }} | |
| PREVIEW_PATH: ${{ steps.preview.outputs.path }} | |
| run: ossutil rm "oss://${BUCKET}/${PREVIEW_PATH}" -rf | |
| - name: Publish preview URL | |
| if: steps.preview.outputs.mode == 'deploy' | |
| uses: actions/github-script@v8 | |
| env: | |
| PR_NUMBER: ${{ steps.preview.outputs.pr-number }} | |
| PREVIEW_URL: ${{ steps.preview.outputs.url }} | |
| with: | |
| script: | | |
| const issue_number = Number(process.env.PR_NUMBER); | |
| const marker = `<!-- vide-docs-preview:${issue_number} -->`; | |
| const body = `${marker}\nDocs preview: ${process.env.PREVIEW_URL}`; | |
| const comments = await github.paginate(github.rest.issues.listComments, { | |
| ...context.repo, | |
| issue_number, | |
| per_page: 100, | |
| }); | |
| const existing = comments.find((comment) => comment.body?.includes(marker)); | |
| if (existing) { | |
| await github.rest.issues.updateComment({ | |
| ...context.repo, | |
| comment_id: existing.id, | |
| body, | |
| }); | |
| } else { | |
| await github.rest.issues.createComment({ ...context.repo, issue_number, body }); | |
| } | |
| staging: | |
| name: Deploy master staging docs | |
| if: github.event.workflow_run.event == 'push' && github.event.workflow_run.head_branch == 'master' && github.event.workflow_run.conclusion == 'success' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.event.workflow_run.head_sha }} | |
| - name: Download master documentation | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: docs-site-master | |
| run-id: ${{ github.event.workflow_run.id }} | |
| github-token: ${{ github.token }} | |
| path: docs-dist | |
| - name: Setup ossutil | |
| uses: ./.github/actions/setup-ossutil | |
| with: | |
| endpoint: ${{ secrets.endpoint }} | |
| access-key-id: ${{ secrets.accessKeyId }} | |
| access-key-secret: ${{ secrets.accessKeySecret }} | |
| - name: Deploy staging documentation | |
| env: | |
| BUCKET: ${{ secrets.bucketName }} | |
| run: ossutil sync docs-dist/ "oss://${BUCKET}/staging/" --delete -f --disable-ignore-error |