Skip to content

Commit 0face22

Browse files
committed
feat(ci): tag-blocking release QA gate — server-type matrix + invariants (Spec 081 T1)
Wire the Spec 081 stage-1/2 gate driver + fixtures into CI as a single reusable workflow that qualifies a release tag before any artifact is published. ## Workflow (.github/workflows/release-qa-gate.yml) - workflow_call (publishers) + workflow_dispatch (dry run, publishes nothing — FR-001a); TEMP push trigger on the T1 branch for real CI. - build-candidate: frontend build + embed + go build of the candidate core, fixtures and release-gate driver, shared as one artifact. - suite-api-e2e: scripts/test-api-e2e.sh UNMODIFIED (FR-003). - suite-race: go test -race ./internal/... + server edition. - suite-scan-eval: scan-eval --gate --min-recall 0.90 --max-fp 0.05 on every tag regardless of changed paths (FR-015). The bare FR-003 command omits the required --corpus flag; the full eval.yml invocation is used so the gate actually runs. - matrix-invariants: five fixture upstreams (stdio/http/sse/docker/oauth, connect→list→call→kill/reconnect) + activity-request-id / counters / quarantine-flow / upgrade-in-place invariants; matrix + invariants run in one shell so the state-file'd core survives between them. - verdict (if: always()): merges fragments against the hardcoded gatereport manifest, uploads gate-report.json, exits per verdict. A missing blocking fragment is a FAIL (fail-closed, FR-004). Every job has an explicit timeout (FR-005). ## Publishers wired (FR-002) - release.yml: qa-gate job (reusable workflow) added; release.needs gains qa-gate so every public job cascading from release is gated. Guarded to the same stable-only condition so a skipped gate skips release too (never un-gates) and RC tags don't double-run the gate here. - prerelease.yml: same, guarded to prerelease TAG refs only (skips on the next branch). ## Audit (FR-022 / SC-004) - cmd/release-gate/workflow_audit_test.go parses both publisher workflows with yaml.v3 and asserts every artifact-publishing job's transitive needs closure includes the qa-gate job; statically disabled (if: false) jobs are excluded. ## Docs - docs/development/release-gate.md: what runs, how to dry-run, the T2/T3/T4 reserved extension slots + macOS-smoke promotion criterion, the FR-003 -short fallback note, and the FR-011 request-id correlation finding (X-Request-Id is not persisted on tool_call records today; correlation falls back to argument nonces + core-recorded ids).
1 parent 578f533 commit 0face22

5 files changed

Lines changed: 780 additions & 2 deletions

File tree

.github/workflows/prerelease.yml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -757,8 +757,19 @@ jobs:
757757
name: installers-${{ matrix.goos }}-${{ matrix.goarch }}
758758
path: installers-artifact/*
759759

760+
# Spec 081: release qualification gate (same reusable workflow as release.yml).
761+
# Guarded to prerelease TAG refs only — skipped on `next` branch pushes,
762+
# consistent with the `release` job's own tag condition, so branch CI is not
763+
# burdened with the full gate. A red gate blocks the prerelease publish
764+
# (FR-002); a skipped gate (branch push) skips `release` too (never un-gated).
765+
qa-gate:
766+
uses: ./.github/workflows/release-qa-gate.yml
767+
permissions:
768+
contents: read
769+
if: startsWith(github.ref, 'refs/tags/v') && (contains(github.ref, '-rc.') || contains(github.ref, '-next.'))
770+
760771
release:
761-
needs: build
772+
needs: [build, qa-gate]
762773
runs-on: ubuntu-latest
763774
environment: staging
764775
# Only create releases for tag pushes, not branch pushes

0 commit comments

Comments
 (0)