Skip to content

chore: make generate:assets idempotent - #450

Merged
jonaslagoni merged 1 commit into
mainfrom
chore/idempotent-generate-assets
Aug 1, 2026
Merged

chore: make generate:assets idempotent#450
jonaslagoni merged 1 commit into
mainfrom
chore/idempotent-generate-assets

Conversation

@jonaslagoni

Copy link
Copy Markdown
Contributor

What

npm run generate:assets was not idempotent. Every run mutated the docs again, so prepare:pr never left a clean tree — and because the version-bump workflow runs generate:assets and commits the result on every release, the churn was being committed on each version bump.

Why it happened

Two upstream tools produce non-deterministic output:

1. markdown-toc -i appends one blank line every time it rewrites a file.

This compounded across releases. Before this PR:

File Trailing blank lines
docs/contributing.md 92
docs/README.md 42
docs/migrations/v0.md 32

(README.md was spared only because it has no <!-- toc --> marker, so markdown-toc no-ops and never writes it.)

2. oclif readme bakes the build machine into the sample codegen --version output.

@the-codegen-project/cli/0.81.1 linux-x64 node-v22.23.1

That flips between contributors (linux-x64darwin-arm64), but it is not only a local-platform issue: engines.node is >=22.0.0 with no .nvmrc, so CI resolves to whatever the latest 22.x is and the line churns on every Node 22 patch release too.

The fix

Adds scripts/normalizeGeneratedDocs.js, wired in as generate:docs:normalize immediately after generate:commands (the last step that touches these docs). It:

  • trims each generated doc to exactly one trailing newline, and
  • replaces the machine-specific segments of the sample version line with placeholders:
@the-codegen-project/cli/0.81.1 <platform> node-<version>

The package version is preserved, so the release version bump still updates it meaningfully.

Verification

  • Ran generate:assets four times. Run 1 produced the one-time cleanup; runs 2, 3 and 4 produced a byte-identical diff. Idempotent.
  • npm run lint — clean.
  • npm test — 64 suites, 772 passed, 1 skipped, 80 snapshots passed.
  • Working tree after generation contains only the intended changes; no schema or example churn.

The 164 deletions in this diff are the one-time sweep of the 163 accumulated blank lines plus the version line.

Notes for the reviewer

  • runtime:typescript:generate (part of prepare:pr) was deliberately skipped: it is blocked by pre-existing lockfile drift in test/runtime/typescript, unrelated to this change, and this PR touches no generator code so regenerated runtime output cannot be affected.
  • Judgment call worth a look: I chose placeholders over pinning linux-x64 plus a fixed Node version, because pinning would still drift as Node 22 patches land. If you would rather the docs show a concrete sample, the alternative is adding an .nvmrc and normalizing to those exact values.
  • Typed as chore: so it does not trigger a release — this is tooling only.

🤖 Generated with Claude Code

`npm run generate:assets` was not idempotent, so `prepare:pr` never left a
clean tree and the release workflow committed churn on every version bump.

Two upstream tools produced non-deterministic output:

- `markdown-toc -i` appends one blank line every time it rewrites a file.
  Because the version-bump workflow runs `generate:assets` and commits the
  result on every release, this compounded across releases: 92 trailing
  blank lines had accumulated in docs/contributing.md, 42 in docs/README.md
  and 32 in docs/migrations/v0.md.
- `oclif readme` renders the sample `codegen --version` output using the
  platform and Node.js version of the machine that ran it. That flipped
  between contributors (linux-x64 vs darwin-arm64), and also churned on CI
  whenever a new Node 22 patch landed, since engines only pins ">=22.0.0".

Add scripts/normalizeGeneratedDocs.js, wired in as `generate:docs:normalize`
directly after `generate:commands` (the last step that touches these docs).
It trims each generated doc to exactly one trailing newline and replaces the
machine-specific segments of the sample version line with placeholders,
keeping the package version so version bumps still update it.

Running `generate:assets` four times in a row now produces a byte-identical
result; the diff here includes the one-time cleanup of the 163 accumulated
blank lines.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jonaslagoni
jonaslagoni requested a review from ALagoni97 as a code owner August 1, 2026 18:47
@vercel

vercel Bot commented Aug 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
the-codegen-project Ready Ready Preview Aug 1, 2026 6:47pm
the-codegen-project-mcp Ready Ready Preview Aug 1, 2026 6:47pm

@jonaslagoni

Copy link
Copy Markdown
Contributor Author

🎉 This PR is included in version 0.82.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant