From 521e3b243f68c873487fa8693e167b1102f5b98a Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 31 Aug 2026 20:23:07 +0000 Subject: [PATCH 1/2] ci: gate manual staging on verified main --- .github/workflows/staging-e2e.yml | 15 +++++++++++++++ src/test/runtime-contracts.test.ts | 3 +++ 2 files changed, 18 insertions(+) diff --git a/.github/workflows/staging-e2e.yml b/.github/workflows/staging-e2e.yml index a15d4f7d5..dbfedf9c3 100644 --- a/.github/workflows/staging-e2e.yml +++ b/.github/workflows/staging-e2e.yml @@ -7,6 +7,7 @@ on: workflow_dispatch: permissions: + actions: read contents: read concurrency: @@ -32,6 +33,20 @@ jobs: persist-credentials: false ref: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.head_sha || github.sha }} + - name: Verify selected commit passed the quality workflow + if: github.event_name == 'workflow_dispatch' + env: + GH_TOKEN: ${{ github.token }} + shell: bash + run: | + successful_runs="$(gh api \ + "repos/${GITHUB_REPOSITORY}/actions/workflows/deploy.yml/runs?head_sha=${GITHUB_SHA}&event=push&status=success&per_page=1" \ + --jq '.workflow_runs | length')" + if [ "$successful_runs" -ne 1 ]; then + echo "::error::The selected main commit has no successful push run of Build and Push Docker Image" + exit 1 + fi + - name: Set up Node uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: diff --git a/src/test/runtime-contracts.test.ts b/src/test/runtime-contracts.test.ts index 198176dd3..ed73a939a 100644 --- a/src/test/runtime-contracts.test.ts +++ b/src/test/runtime-contracts.test.ts @@ -25,6 +25,9 @@ describe('runtime integration contracts', () => { const workflow = readProjectFile('.github/workflows/staging-e2e.yml'); expect(workflow).not.toContain('actions/upload-artifact'); expect(workflow).not.toContain('test-results/**/*.webm'); + expect(workflow).toContain('actions: read'); + expect(workflow).toContain('Verify selected commit passed the quality workflow'); + expect(workflow).toContain('head_sha=${GITHUB_SHA}&event=push&status=success'); }); it('keeps pull-request browser checks separate from Docker publication', () => { From dc939b010ee2b9b6a02af31fd0d754be298a5212 Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 31 Aug 2026 20:32:15 +0000 Subject: [PATCH 2/2] test: harden staging gate contract --- .github/workflows/staging-e2e.yml | 1 + src/test/runtime-contracts.test.ts | 3 +++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/staging-e2e.yml b/.github/workflows/staging-e2e.yml index dbfedf9c3..d48f99b82 100644 --- a/.github/workflows/staging-e2e.yml +++ b/.github/workflows/staging-e2e.yml @@ -7,6 +7,7 @@ on: workflow_dispatch: permissions: + # Manual dispatch queries workflow runs for the selected main commit. actions: read contents: read diff --git a/src/test/runtime-contracts.test.ts b/src/test/runtime-contracts.test.ts index ed73a939a..892da0ad7 100644 --- a/src/test/runtime-contracts.test.ts +++ b/src/test/runtime-contracts.test.ts @@ -27,7 +27,10 @@ describe('runtime integration contracts', () => { expect(workflow).not.toContain('test-results/**/*.webm'); expect(workflow).toContain('actions: read'); expect(workflow).toContain('Verify selected commit passed the quality workflow'); + expect(workflow).toContain("if: github.event_name == 'workflow_dispatch'"); expect(workflow).toContain('head_sha=${GITHUB_SHA}&event=push&status=success'); + expect(workflow).toContain('if [ "$successful_runs" -ne 1 ]'); + expect(workflow).toContain('exit 1'); }); it('keeps pull-request browser checks separate from Docker publication', () => {