Repository navigation
ci(docs): make the generated API reference reproducible and gate it - #1479
Conversation
docs/api is 3236 generated files checked into the repo, and nothing kept them
current. Release had drifted 756 files behind its own source and still carried
five duplicate filenames. The regeneration that just fixed that would have
started rotting again the same day, because the output was never reproducible
in the first place.
Typedoc baked two moving values into every page. The current commit SHA went
into every "Defined in:" source link, so all 3224 files carrying a link changed
on every single commit. The package version went into every page header, so all
3236 changed on every release — and semantic-release bumps the version on every
merge. That is why the reference was unmaintainable as checked-in content and
why nobody could add a drift check: it would have failed on every PR.
typedoc.json now pins gitRevision to the release branch and drops
includeVersion, so source links read blob/release and no page carries a version
string. Measured across two different commits: 3224 files of churn before, 0
after. The regenerated tree in this commit reflects both settings.
The trade-off is deliberate. Source links now point at the branch tip rather
than an immutable SHA, so a link can drift if a file moves between
regenerations — but the docs are regenerated from the same tree that ships, and
the alternative is a reference nobody can keep current. The version is still in
package.json.
With the output stable, CI can enforce it: regenerate, format, and fail on any
difference. About 12s.
`git status --porcelain`, not `git diff`: typedoc runs with cleanOutputDir, so
real drift can be a file it newly emits or stops emitting, and only status
reports untracked additions.
Proven non-vacuous by mutation, and the first mutation was wrong in an
instructive way. Hand-editing a generated file does NOT trip the gate, because
cleanOutputDir wipes the edit before the comparison — that tests whether
hand-edits survive regeneration, not whether the gate works. Adding an exported
type to src/lib/index.ts does trip it:
M docs/api/README.md
?? docs/api/type-aliases/DocsDriftGateProbe.md
which is also the case `git diff` would have missed.
✅ Single Commit Policy - COMPLIANTStatus: Policy requirements met • 1 commit • Valid format • Ready for merge 📊 View validation details📝 Commit Details
✅ Validation Results
🤖 Automated validation by NeuroLink Single Commit Enforcement |
|
Important Review skippedToo many files! This PR contains 3000 files, which is 2900 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. Usage-priced reviews support at most 300 files. ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3000)
You can disable this status message by setting the |
🤖 AI Review & Build Compliance ✅Status: AI analysis complete • Build rules validated • Ready for review 📊 View detailed analysis results🛡️ Analysis Complete
📋 Ready for Merge When
🤖 AI analysis complete - check individual code comments for specific feedback |
Documentation Validation Results🚀 Documentation validation passed!
📦 Build artifact uploaded successfully. Ready for deployment preview. Commit: |
Tara-ag
left a comment
There was a problem hiding this comment.
Reviewing PR #1479 - ci(docs): make the generated API reference reproducible and gate it
This PR adds a CI gate to ensure the generated API documentation (docs/api) stays in sync with the source code. It also updates all 300+ generated markdown files to use stable branch references instead of commit SHAs.
Review Summary
Decision: APPROVED
Findings:
- MINOR: Documentation consistency improvement - The changes correctly make docs/api reproducible across releases
- SUGGESTION: Consider adding timeout for docs regeneration step
Impact on existing code:
- No functional changes to the SDK or CLI
- Purely infrastructure/documentation improvements
- CI jobs will now be ~12s slower due to docs regeneration check
- Documentation will now properly point to
releasebranch instead of specific commits
Scope:
.github/workflows/ci.yml- Added new CI check stepdocs/api/**- Updated 300+ generated files to remove version numbers and use stable refs
All changes are safe and improve the maintainability of the project's documentation.
📋 PR Review SummaryDecision: ✅ APPROVED FindingsThis PR contains zero code changes - all modifications are to generated documentation files. No issues found requiring inline comments. Changes breakdown:
Impact AnalysisScope: Documentation-only PR
Risk Level: 🟢 LOW
CI Change ReviewThe added CI step is well-designed: # Regenerate docs and verify no drift
pnpm run docs:api
npx prettier --write docs/api
git status --porcelain docs/api # exits non-zero if any changesWhy this matters:
Cost: ~12s per CI run - acceptable for the safety gained Compliance Checklist✅ Security: No secrets, no injection risks, no auth changes RecommendationApprove this PR. It's a safe, necessary change that:
No code review needed - all changes are either workflow configuration or auto-generated documentation. |
|
🎉 This PR is included in version 11.18.2 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Follow-up to #1478, and it corrects a claim I made there.
What I got wrong in #1478
I said the generate+format cycle was reproducible, having run it twice and seen zero changes. That was true only because I ran both passes at the same commit. Immediately after #1478 merged I re-ran it on
releaseand got 3224 changed files. The cause:Typedoc bakes the current commit SHA into every source link. So every commit rewrites all 3224 files carrying one. And
includeVersion: trueputs the package version in every page header (**NeuroLink API Reference v11.2.3**), so every release rewrites all 3236 — and semantic-release bumps the version on every merge torelease.That is why this reference was unmaintainable, and why nobody could add a drift check: it would have failed on every PR. The 756-file staleness wasn't neglect, it was structural.
The fix
typedoc.jsonpinsgitRevisionto the release branch and dropsincludeVersion. Source links now readblob/release; no page carries a version string. Measured across two genuinely different commits:Trade-off, stated plainly: source links now point at the branch tip rather than an immutable SHA, so a link can drift if a file moves between regenerations. I think that's clearly worth it — the docs are regenerated from the same tree that ships, and the alternative is a reference nobody can keep current. The version is still in
package.json.The gate
With the output stable, CI can enforce it — regenerate, format, fail on any difference. ~12s (6s typedoc, 6s prettier), so no paths filter.
The prettier pass is part of the pipeline, not a tidy-up:
docs/apiisn't in.prettierignoreand raw typedoc output failsformat:check.git status --porcelain, notgit diff— typedoc runs withcleanOutputDir, so real drift can be a file it newly emits or stops emitting, and only status reports untracked additions.Proven non-vacuous, and the first attempt was wrong
Hand-editing a generated file does not trip the gate —
cleanOutputDirwipes the edit before the comparison, so that mutation tests whether hand-edits survive regeneration, not whether the gate works. It reported a false pass and I nearly recorded the gate as verified on it.Changing the source trips it. Adding an exported type to
src/lib/index.ts:which is also exactly the case
git diffwould have missed.Contents
typedoc.jsongitRevision: "release",includeVersion: false.github/workflows/ci.ymldocs/api(3236 files)The docs churn is unavoidable here — both settings change every page. Reviewing it is the same as #1478: re-run
pnpm run docs:api && npx prettier --write docs/apiand confirmgit status --porcelain docs/apiis empty.