Release · v3.14.29
Verify on the pull request, deploy on main, and get…
chore(ci): verify on the pull request, deploy on main, and get off Node 20
Details
Three things: the deprecation warnings, the duplicated CI, and an audit of what is actually wired up. ## Node 20 deprecation GitHub is retiring Node 20 on the runners, and three actions still targeted it, so every run printed a warning and was force-migrated: pnpm/action-setup v4 -> v6 actions/setup-python v5 -> v7 actions/github-script v7 -> v9 astral-sh/setup-uv v8.1.0 -> v10.0.1 (already node24; two majors stale) Every action in the repo now declares `using: node24`, checked against each action's own `action.yml` at the pinned ref. `FORCE_JAVASCRIPT_ACTIONS_TO_NODE24` is gone from ci.yml — it was the flag doing the forcing the warning described, and nothing needs forcing any more. ## One place where things are checked The same suites ran twice: once on the pull request, then again on the merge commit — the same tree, the same result, twice the minutes. Branch protection will not merge a PR whose checks failed, so a commit reaching `main` has already passed. tests.yml drops `push: [main]`; pull requests only ci.yml drops `verify-python` and `verify-supabase` (already on the PR) ci.yml drops the `tests` job entirely The link crawl and the GA4 browser test were the one thing genuinely unique to the post-merge run, so they are not deleted — they move to the PR, as a separate `links-and-analytics` job so they do not slow the fast checks. Both already tested the locally built `_site` rather than the deployed site, so running them after merge bought nothing except finding breakage after it shipped. `ci.yml` is now build -> deploy -> gist sync, plus GA4 live metrics as a `continue-on-error` report. That last one reads the GA4 Data API, so it can only speak about production and can never gate a PR — but it must also never fail a deploy that has already happened. ## Netlify `netlify.toml` is correct as it stands: it skips `main` (production deploys are the only metered context), and its Node 24 / Ruby 3.2 match `.nvmrc` and `.ruby-version`. What it lacks is any tie to the GitHub chain — Netlify cannot call a composite action, so the build steps are written twice, and adding one to only the GitHub side has already shipped a preview of placeholder content that stayed broken for hours while CI was green. `pnpm run check:build-chains` now asserts the two agree: every build-affecting step present in both, and the TypeScript compile after the Jekyll build in each (Jekyll wipes `_site`). It compares the executable parts only — matching command names inside netlify.toml's own explanatory comment made the first version report the rule as broken in the file that documents it. Confirmed to fail when a generator is removed from either side. ## Audited and deliberately kept `preview-v3.yml` (misnamed — it previews any ref as a downloadable artifact), `deploy-vercel.yml`, `agent.yml`, `cleanup-merged-branches.yml`, `seed-sections.yml` and `prune-documents.yml` are all `workflow_dispatch`-only and cost nothing idle. Vercel and the artifact preview overlap with Netlify's automatic PR previews, and the agent last ran in June, but "unused lately" is not the same as "not required" and none of them is mine to delete. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DAJJ63FFnLoD5XLpu6yJaG
Files changed (11)
| .github/actions/build-site/action.yml | +1 | −1 |
| .github/workflows/agent.yml | +2 | −2 |
| .github/workflows/ci.yml | +56 | −119 |
| .github/workflows/cleanup-merged-branches.yml | +1 | −1 |
| .github/workflows/deploy-vercel.yml | +1 | −1 |
| .github/workflows/pr-validation.yml | +97 | −10 |
| .github/workflows/tests.yml | +10 | −8 |
| .github/workflows/version-tag.yml | +1 | −1 |
| CLAUDE.md | +15 | −7 |
| package.json | +1 | −0 |
| tools/check-build-chain-sync.mjs | +99 | −0 |