Deploy Vector Preview Sites #11094
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 Vector Preview Sites | |
| on: | |
| workflow_run: | |
| workflows: ["Call Build Preview"] | |
| types: | |
| - completed | |
| permissions: | |
| contents: read # Restrictive default | |
| jobs: | |
| # Reads which "preview: <app>" labels were present on the PR at trigger time (captured into | |
| # the artifact by preview_site_trigger.yml) so each deploy job below can be gated individually. | |
| read_requested_apps: | |
| if: ${{ github.event.workflow_run.conclusion == 'success' }} | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 5 | |
| permissions: | |
| contents: read # Required for repository context | |
| actions: read # Required to download artifacts | |
| outputs: | |
| website: ${{ steps.read.outputs.website }} | |
| playground: ${{ steps.read.outputs.playground }} | |
| rust_doc: ${{ steps.read.outputs.rust_doc }} | |
| steps: | |
| - name: Read requested preview apps from artifact | |
| id: read | |
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const { execSync } = require('child_process'); | |
| const artifacts = await github.rest.actions.listWorkflowRunArtifacts({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| run_id: ${{ github.event.workflow_run.id }}, | |
| }); | |
| const matchArtifact = artifacts.data.artifacts.find(a => a.name === 'pr'); | |
| const download = await github.rest.actions.downloadArtifact({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| artifact_id: matchArtifact.id, | |
| archive_format: 'zip', | |
| }); | |
| fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/pr.zip`, Buffer.from(download.data)); | |
| execSync(`unzip -o pr.zip -d pr`); | |
| const apps = JSON.parse(fs.readFileSync('pr/apps', 'utf8')); | |
| core.setOutput('website', apps.website === true); | |
| core.setOutput('playground', apps.playground === true); | |
| core.setOutput('rust_doc', apps.rustDoc === true); | |
| deploy_vector_preview_site: | |
| needs: read_requested_apps | |
| if: ${{ needs.read_requested_apps.outputs.website == 'true' }} | |
| permissions: | |
| contents: read # Required by the reusable workflow | |
| actions: read # Required to download artifacts | |
| statuses: write # Required to update commit status | |
| uses: ./.github/workflows/create_preview_sites.yml | |
| with: | |
| APP_ID: "d1a7j77663uxsc" | |
| APP_NAME: "vector.dev" | |
| secrets: | |
| REQUEST_TOKEN: ${{ secrets.REQUEST_TOKEN }} | |
| REQUEST_MESSAGE: ${{ secrets.REQUEST_MESSAGE }} | |
| ENDPOINT: ${{ secrets.BUILDER_ENDPOINT }} | |
| deploy_rust_doc_preview_site: | |
| needs: read_requested_apps | |
| if: ${{ needs.read_requested_apps.outputs.rust_doc == 'true' }} | |
| permissions: | |
| contents: read # Required by the reusable workflow | |
| actions: read # Required to download artifacts | |
| statuses: write # Required to update commit status | |
| uses: ./.github/workflows/create_preview_sites.yml | |
| with: | |
| APP_ID: "d1hoyoksbulg25" | |
| APP_NAME: "Rust Doc" | |
| secrets: | |
| REQUEST_TOKEN: ${{ secrets.REQUEST_TOKEN }} | |
| REQUEST_MESSAGE: ${{ secrets.REQUEST_MESSAGE }} | |
| ENDPOINT: ${{ secrets.BUILDER_ENDPOINT }} | |
| deploy_vrl_playground_preview_site: | |
| needs: read_requested_apps | |
| if: ${{ needs.read_requested_apps.outputs.playground == 'true' }} | |
| permissions: | |
| contents: read # Required by the reusable workflow | |
| actions: read # Required to download artifacts | |
| statuses: write # Required to update commit status | |
| uses: ./.github/workflows/create_preview_sites.yml | |
| with: | |
| APP_ID: "d2lr4eds605rpz" | |
| APP_NAME: "VRL Playground" | |
| secrets: | |
| REQUEST_TOKEN: ${{ secrets.REQUEST_TOKEN }} | |
| REQUEST_MESSAGE: ${{ secrets.REQUEST_MESSAGE }} | |
| ENDPOINT: ${{ secrets.BUILDER_ENDPOINT }} | |
| # Single writer for the sticky preview-links comment: the 3 deploy jobs above only kick off the | |
| # Amplify builds and report their outcome via outputs, so there is never more than one job racing | |
| # to read-modify-write the PR comment. | |
| comment_preview_links: | |
| if: ${{ always() && github.event.workflow_run.conclusion == 'success' }} | |
| needs: | |
| - read_requested_apps | |
| - deploy_vector_preview_site | |
| - deploy_rust_doc_preview_site | |
| - deploy_vrl_playground_preview_site | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 5 | |
| # Since this is now the only job that writes the comment (no sibling fan-out), a concurrency | |
| # group per branch safely de-races overlapping workflow runs for rapid successive pushes. | |
| concurrency: | |
| group: preview-comment-${{ github.event.workflow_run.head_branch }} | |
| cancel-in-progress: true | |
| permissions: | |
| issues: write # Required to post the preview link comment | |
| pull-requests: write # Required to post the preview link comment | |
| steps: | |
| - name: Post preview links comment | |
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| VECTOR_DEV_RESULT: ${{ needs.deploy_vector_preview_site.result }} | |
| VECTOR_DEV_BRANCH: ${{ needs.deploy_vector_preview_site.outputs.sanitized_branch_name }} | |
| RUST_DOC_RESULT: ${{ needs.deploy_rust_doc_preview_site.result }} | |
| RUST_DOC_BRANCH: ${{ needs.deploy_rust_doc_preview_site.outputs.sanitized_branch_name }} | |
| VRL_PLAYGROUND_RESULT: ${{ needs.deploy_vrl_playground_preview_site.result }} | |
| VRL_PLAYGROUND_BRANCH: ${{ needs.deploy_vrl_playground_preview_site.outputs.sanitized_branch_name }} | |
| PR_NUMBER: ${{ needs.deploy_vector_preview_site.outputs.pr_number || needs.deploy_rust_doc_preview_site.outputs.pr_number || needs.deploy_vrl_playground_preview_site.outputs.pr_number }} | |
| WORKFLOW_RUN_ID: ${{ github.event.workflow_run.id }} | |
| with: | |
| script: | | |
| const APPS = [ | |
| { name: 'vector.dev', appId: 'd1a7j77663uxsc', result: process.env.VECTOR_DEV_RESULT, branch: process.env.VECTOR_DEV_BRANCH }, | |
| { name: 'Rust Doc', appId: 'd1hoyoksbulg25', result: process.env.RUST_DOC_RESULT, branch: process.env.RUST_DOC_BRANCH }, | |
| { name: 'VRL Playground', appId: 'd2lr4eds605rpz', result: process.env.VRL_PLAYGROUND_RESULT, branch: process.env.VRL_PLAYGROUND_BRANCH }, | |
| ]; | |
| const prNumber = parseInt(process.env.PR_NUMBER, 10); | |
| if (isNaN(prNumber)) { | |
| core.setFailed('No successful preview deploy produced a PR number'); | |
| return; | |
| } | |
| const lines = APPS | |
| .filter(app => app.result === 'success') | |
| .map(app => `- [${app.name} preview](https://${app.branch}.${app.appId}.amplifyapp.com)`); | |
| if (lines.length === 0) { | |
| core.info('No successful preview deploys, skipping comment'); | |
| return; | |
| } | |
| const STICKY_MARKER = '<!-- preview-sites-comment -->'; | |
| // Job-level concurrency only de-races runs that are queued/running at the same time. | |
| // A run whose deploy jobs are still pending (e.g. a slow build) can finish and post | |
| // here *after* a newer run already commented. Stamp the triggering run id so a late | |
| // straggler can detect it's stale and skip clobbering the newer comment. | |
| const RUN_ID_MARKER = `<!-- preview-sites-run:${process.env.WORKFLOW_RUN_ID} -->`; | |
| const body = [ | |
| STICKY_MARKER, | |
| RUN_ID_MARKER, | |
| 'Your preview sites will be ready in a few minutes, please allow time for them to build.', | |
| '', | |
| ...lines, | |
| ].join('\n'); | |
| const comments = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: prNumber, | |
| per_page: 100, | |
| }); | |
| const existing = comments.data.find(c => c.body.includes(STICKY_MARKER)); | |
| if (existing) { | |
| const existingRunMatch = existing.body.match(/<!-- preview-sites-run:(\d+) -->/); | |
| const existingRunId = existingRunMatch ? parseInt(existingRunMatch[1], 10) : 0; | |
| if (existingRunId > parseInt(process.env.WORKFLOW_RUN_ID, 10)) { | |
| core.info(`Comment already reflects newer run ${existingRunId}, skipping stale update from run ${process.env.WORKFLOW_RUN_ID}`); | |
| return; | |
| } | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: existing.id, | |
| body, | |
| }); | |
| } else { | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: prNumber, | |
| body, | |
| }); | |
| } |