ci: gate the docs build on docs/**, and openapi.json on js - #35
Merged
Conversation
Closes #34. `docs/**` matched no filter, so a documentation change ran no documentation build. `packages/docs` is a renderer rather than a container -- DOCS_BASE points its Astro loader at `../../docs` -- so the markdown outside that package is an input to its build, and `astro check` never saw a change to it. First failure would have been on a `docs-v*` tag, at the moment the intent is to publish rather than to fix. Two things came out of auditing the rest of the block, as the issue suggested. `docs/openapi.json` is the more serious one, and it is not documentation for this purpose. It is generated from the Hono router, and BOTH things that compare it to the router -- `openapi:check` and packages/app/test/http/openapi.test.ts inside `test:js` -- run in js-check. Editing the file alone therefore reached main with nothing checking it against the surface it claims to describe. It joins the `js` filter, which also means an API-surface change now reaches e2e through the `*js` splice, where it belongs. The content filter is deliberately NOT folded into `js`. `e2e` splices `*js`, so a markdown typo would have queued the browser suite behind it -- five minutes of runners for a word. It gets its own filter, its own job, and one task. Everything else in the block audited clean, and one candidate was rejected on the evidence: `.npmrc` looks like it governs installs, but its own header records that pnpm 11 silently ignores pnpm settings there and that the whole supply-chain policy lives in pnpm-workspace.yaml -- which the `js` filter already carries. `assets/` and `screenshots/` are not build inputs, and the prose files need no filter because `lint:typos` and `lint:loc` run in the unconditional `workflows` job. `lint:docs` is a mise task rather than a `pnpm --filter` invocation in the workflow, because ci.yml states that every step it runs is a task so the JS toolchain can be repointed without touching CI. It overlaps `typecheck` on purpose, the same trade lint:svelte documents. Verified by parsing the filters block and asserting the resolved graph rather than reading the anchors: `docs` carries `docs/**`, `js` carries `docs/openapi.json` and not `docs/**`, and `e2e` does not pick up `docs/**`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #34.
The reported gap
docs/**matched no filter, so a documentation change ran no documentation build.packages/docsis a renderer rather than a container —DOCS_BASE = "../../docs"points its Astro loader at the repository's owndocs/directory — so the markdown outside that package is an input to its build, andastro checknever saw a change to it. Becausedocs-release.ymlis tag-triggered, the first failure would land on adocs-v*tag, at the moment the intent is to publish rather than to fix.What the audit turned up
The issue suggested a look at the remaining top-level paths. Two results.
docs/openapi.jsonis the more serious one, and it is not documentation for this purpose. It's generated from the Hono router, and both things that compare it to the router —openapi:checkandpackages/app/test/http/openapi.test.tsinsidetest:js— run injs-check. So editing that file alone (the hand-edit the docs forbid, or a bad merge resolving it) reachedmainwith nothing checking it against the surface it claims to describe. It joins thejsfilter, which also means an API-surface change now reachese2ethrough the*jssplice, where it arguably belongs.One candidate was rejected on the evidence.
.npmrclooks like it governs installs, but its own header records that pnpm 11 silently ignores pnpm settings written there and that the entire supply-chain policy lives inpnpm-workspace.yaml— which thejsfilter already carries. Adding it would have been cargo-culting.Everything else audited clean:
assets/andscreenshots/are not build inputs (brand-mark.sveltedocuments itself as holding a copy of the brand mark),.dev.vars.exampleis asserted by nothing,.editorconfigdoesn't govern the formatter —vite.config.tsstates its ownprintWidthprecisely so the two can't disagree silently —lefthook.ymlis local hooks only, and the prose files need no filter becauselint:typosandlint:locrun in theworkflowsjob, which has noif:at all.Why a separate filter and job rather than adding to
jse2esplices*js. Foldingdocs/**intojswould have queued the browser suite behind a markdown typo — roughly five minutes of runners for a word. The content gets its own filter, its own job, and one task.lint:docsis a mise task rather than apnpm --filterinvocation in the workflow, because ci.yml states that every step it runs is a task so the JS toolchain can be repointed without touching CI. It overlapstypecheckdeliberately, the same tradelint:sveltealready documents.Verification
The anchors are the part that fails silently, so I parsed the filters block and asserted the resolved graph rather than reading it:
ci-okchecks every entry inneeds, sodocs-checkis listed there — an unlisted job cannot block a merge.Also green:
lint:actions,lint:zizmor,lint:docs,lint:typos,lint:loc,fmt:check.This PR is its own test case. It touches
ci.ymlandmise.toml, which are in*commonand therefore in every filter, so the whole graph runs here — including the newdocs-check. What it does not demonstrate is the skip path; a docs-only PR after this merges is what showsdocs-checkrunning whilejs-checkande2estay skipped.🤖 Generated with Claude Code