name: Release Gates (GitHub-hosted runner) # This workflow CANNOT PUBLISH ANYTHING. It is a gate bench, nothing else. # # History, so nobody "restores" what was deliberately removed: # INFRA-F71 (2026-07-28) removed the tag trigger — publishing moved to the # self-hosted .gitea/workflows/publish.yml, because private-repo Actions billing # kept blocking releases here (v1.1.0: every job unstarted, "payments failed / # spending limit"). # INFRA-F73 (2026-07-29) deleted the publish job outright and renamed this file # from publish.yml, because the registry itself moved to Gitea. GitHub Packages # is retired for this package — there is no longer anything here to publish TO. # ⚠️ Do not add a publish job back. One registry, one publish path, by design. # # Why it still exists: render-gate needs a root-capable runner to # `playwright install --with-deps` chromium. The Gitea act_runner is unprivileged # and cannot (INFRA-F40), so this is the only CI place the numeric # render-verification can run. The gate is otherwise enforced at tag-cut time by # scripts/release.mjs, which has no skip flag — this bench is a convenience for # investigating drift, not the enforcement point. # # Caveat: dispatching this needs GitHub Actions minutes, which is exactly the # constraint that pushed publishing off GitHub in the first place. Expect it to be # unavailable when the quota is exhausted. on: workflow_dispatch: # Read-only. `packages: write` was dropped with the publish job — this workflow # has no business touching any registry. permissions: contents: read jobs: # F34-A: validate all prepublishOnly gates on Node 20 + 22. The real release path # runs the same gates on the Gitea runner; this is the root-capable rehearsal. # Catches Node-version-specific stdlib mismatches (e.g. globSync added in Node 22) # that local dev (Node 22+) would miss but CI runner Node 20 would hit at import time. audit-matrix: runs-on: ubuntu-latest strategy: fail-fast: false matrix: node-version: ['20', '22'] steps: - name: Checkout uses: actions/checkout@v5 - name: Setup pnpm uses: pnpm/action-setup@v4 with: version: 10.28.2 - name: Setup Node ${{ matrix.node-version }} uses: actions/setup-node@v5 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' - name: Install run: pnpm install --frozen-lockfile - name: Run prepublishOnly gates run: pnpm run prepublishOnly # INFRA-F40 track A: numeric render-verification gate (env-independent # getComputedStyle vs Figma). Runs here (GitHub-hosted runner = root-capable, # `--with-deps` works) rather than Gitea pr-checks (non-root runner, no system # libs). Release-time gate: a true Figma-drift (A_TRUE_DRIFT_CANDIDATE > # baseline) is a real regression. Enforcement lives in scripts/release.mjs at # tag-cut time, not here. Single Node (browser test is not Node-version # sensitive), separate job so it doesn't double-run on the 20/22 matrix. render-gate: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v5 - name: Setup pnpm uses: pnpm/action-setup@v4 with: version: 10.28.2 - name: Setup Node 20 uses: actions/setup-node@v5 with: node-version: '20' cache: 'pnpm' - name: Install run: pnpm install --frozen-lockfile - name: Install Playwright chromium (+ system deps) run: pnpm exec playwright install --with-deps chromium - name: Render verification (numeric Figma-conformance) run: pnpm run test:render-verification - name: Render drift gate (A drift must be ≤ baseline) run: pnpm run audit:render-drift-gate # P1-06 (system-review-2026-06-10): release-time a11y run for v1.0 DoD (d). # # ── 2026-08-31: this stopped being non-blocking (backlog INFRA-F86 残余③) ──── # It carried `continue-on-error: true` from 2026-06-10 to 2026-08-31 because # `test:a11y` was red on every page by construction: it asserted every axe rule at # zero while color-contrast was simultaneously Owner-accepted. The Owner replaced # that on 2026-08-31 with a named, dated, shrink-only table # (tests/a11y/color-contrast-exemptions.json), so the suite is green and can block. # # ⚠️ The old wording here named two follow-ups. Neither survived contact: # - "once `audit:token-contrast` reports 0 fails" — NOT the condition that was # met. That report still lists failing token pairs (20 non-text ones as of # 2026-08-31) and always exits 0; it is a report, not a gate. What changed is # the Owner decision, not that number. # ── 2026-09-07 (Owner decision, ai-ds-lab decision-queue Q2, branch `ratchet`): # that number is now RATCHETED — but ⚠️ NOT by this step. `audit:token-contrast` # still exits 0 and this step is still non-blocking, deliberately: the script # rewrites two git-tracked artifacts, so it must not be what blocks a commit. # The teeth are in tests/a11y-non-text-contrast-ratchet.test.ts, which runs under # `pnpm test` (.husky/pre-commit L8-9 + .gitea/workflows/pr-checks.yml "Unit tests # (vitest)") and judges the pure computation that script exports. It freezes # today's 20 pairs as a named, dated, shrink-only table # (tests/a11y/non-text-contrast-exemptions.json — sibling of the text-contrast one # landed 2026-08-31) and forbids all four directions of growth: a new failing pair, # a stale row, a ratio regression, and a `fail`→`same` degradation. # ⛔ Don't "simplify" this by making the report exit 1 — that dirties the tree on # every commit. ⛔ And don't read "20" as a budget: it is the measured steady state. # - "add the equivalent job to .gitea/workflows/publish.yml `needs`" — cannot # work: the Gitea runner is unprivileged and cannot install chromium # (INFRA-F40/F71), which is why every browser-driven gate in this repo lives in # scripts/release.mjs instead. The real release-path binding is release.mjs # step 1f (Owner decision 2026-08-31). This job is the GitHub-side copy; # ⚠️ gates.yml is dispatch-only and cannot publish, so it is not the binding one. a11y-report: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v5 - name: Setup pnpm uses: pnpm/action-setup@v4 with: version: 10.28.2 - name: Setup Node 20 uses: actions/setup-node@v5 with: node-version: '20' cache: 'pnpm' - name: Install run: pnpm install --frozen-lockfile - name: Token contrast report (non-blocking) run: pnpm run audit:token-contrast - name: Install Playwright chromium (+ system deps) run: pnpm exec playwright install --with-deps chromium - name: Axe-core a11y suite (non-blocking) run: pnpm run test:a11y