The drafter block and the register: /profile/, rebuilt (§16) #35
Workflow file for this run
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
| # Everything the deploy workflow will do, before it is allowed to do it. | |
| # | |
| # `push: main` is not redundant with `pull_request`, and its absence was a real | |
| # gap: `deploy.yml` fires on every push to main and does not depend on this | |
| # workflow, so nothing re-ran the tests against the commit that actually ships. | |
| # A squash-merge produces a commit no CI run has ever seen — usually identical in | |
| # content to the branch tip, but not necessarily, and a direct push is not | |
| # identical to anything. Twenty runs of this workflow existed before this line | |
| # and every one of them was a `pull_request`. | |
| # | |
| # Running here does not by itself stop a red commit from deploying: `deploy.yml` | |
| # does not depend on this workflow, so what stops one is main's ruleset naming | |
| # the job below as a required status check. It does — which means the job's | |
| # `name:` is part of the repository's configuration and not free to edit: change | |
| # it without changing the ruleset and the required check simply never reports, | |
| # leaving every pull request unmergeable rather than failing loudly. | |
| name: CI | |
| on: | |
| pull_request: | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| jobs: | |
| site: | |
| name: Build and test | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| # §11.26: REVISION is each file's last-touching commit. | |
| fetch-depth: 0 | |
| # v5 added automatic caching driven by a `packageManager` field in | |
| # package.json, and v6 narrowed it to npm. `package.json` declares no such | |
| # field, so nothing here is cached twice or cached differently; the | |
| # explicit `cache`/`cache-dependency-path` below is still what runs. | |
| - uses: actions/setup-node@v7 | |
| with: | |
| node-version: "24" | |
| cache: npm | |
| cache-dependency-path: package-lock.json | |
| - run: npm ci | |
| - run: npm run typecheck | |
| # Includes the B9 contrast check (§10.1): a token edited so that a pair | |
| # drops under its floor fails here, not in an audit six months later. | |
| - run: npm test | |
| - run: npm run build | |
| # §15.1.2 — the corpus link test fails the build on a dead `.md` link, but | |
| # nothing caught a MOVED ROUTE: a static export ships an internal href | |
| # that resolves to nothing without erroring. This gate reads the export | |
| # itself, which is the only place that question can be answered. | |
| - run: node scripts/check-links-out.mjs out | |
| # The gate's whole reason for existing is a root-relative link that lacks | |
| # the base path, and that link cannot exist in the build above: GitHub | |
| # Pages serves from a sub-path, so the export the deploy publishes is the | |
| # only one where the question is real. Running it once, base-path-less, | |
| # would have been a gate for the case that cannot fail. | |
| - run: SITE_BASE_PATH=/ai-engineering-bazaar npm run build | |
| - run: node scripts/check-links-out.mjs out | |
| # `chrome`, not `chromium`: playwright.config.ts runs the suite on real | |
| # Google Chrome via `channel: 'chrome'`, and installing the bundled | |
| # Chromium instead only passes because the runner image happens to ship | |
| # Chrome already. | |
| - run: npx playwright install --with-deps chrome | |
| - run: npm run test:e2e | |
| - uses: actions/upload-artifact@v7 | |
| if: failure() | |
| with: | |
| name: playwright-report | |
| path: playwright-report/ | |
| retention-days: 7 |