Skip to content

Deploy Vector Preview Sites #11094

Deploy Vector Preview Sites

Deploy Vector Preview Sites #11094

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,
});
}