Skip to content

chore(cli): read --version from package.json via prebuild generator#139

Merged
naorsabag merged 2 commits into
masterfrom
chore/cli-version-from-package-json
May 11, 2026
Merged

chore(cli): read --version from package.json via prebuild generator#139
naorsabag merged 2 commits into
masterfrom
chore/cli-version-from-package-json

Conversation

@naorsabag
Copy link
Copy Markdown
Owner

@naorsabag naorsabag commented May 11, 2026

Summary

The CLI's --version output is rendered from a string literal in packages/cli/src/index.ts (Commander's .version('0.x.y')). Past two bumps had to fix the same desync — package.json got bumped, the literal didn't, the contract test caught it in CI only after a wasted publish run. PR #138's first commit needed a one-line follow-up for exactly this reason.

Solution: a tiny prebuild generator that writes the version into a single-purpose file, so the literal vanishes from the source tree entirely.

How it works

  1. packages/cli/scripts/sync-version.mjs reads package.json and writes src/version.ts:
    // Auto-generated by scripts/sync-version.mjs from package.json. Do not edit.
    export const VERSION = "0.2.0"
  2. packages/cli/package.json gains a prebuild script that runs the generator. npm runs this automatically before build, including under prepack on publish.
  3. src/index.ts imports VERSION and passes it to .version().
  4. src/version.ts is gitignored — the generator is the only writer. Fresh clones get the file on first npm run build.

End-to-end check

Locally bumped package.json to 0.2.1-test, ran npm run build, confirmed node dist/index.js --version printed 0.2.1-test. Reverted to 0.2.0, rebuilt, confirmed clean roll-back.

What this fixes for future releases

Bumping a new version is now a single edit to each package.json. The CLI binary's --version follows automatically. The contract test that asserts --version matches package.json will keep enforcing this, but it should never trip again.

Test plan

  • CI green (build, test, audit, gitleaks).
  • After merge, verify the next release's npm-published CLI prints the correct --version without any code edit beyond the package.json bump.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • CLI --version output is now automatically synchronized with the package version at build time, eliminating manual version updates and ensuring consistency between the published package and CLI metadata.

Review Change Stack

Past two release bumps had to fix the same desync: package.json
version was 0.2.0 but src/index.ts had a hard-coded `.version('0.1.0')`
literal that nobody remembered to update. The contract test caught it
in CI but only after a wasted publish run.

Fix:
- New scripts/sync-version.mjs reads package.json's version and writes
  src/version.ts (a single `export const VERSION = "..."`).
- package.json's `build` script gains a `prebuild` that runs the
  generator, so every build (incl. prepack-on-publish) regenerates
  the constant in lockstep with the package version.
- src/index.ts now imports VERSION from ./version.js and passes it to
  Commander's .version().
- src/version.ts is gitignored - the generator is the only writer; a
  fresh clone will get a fresh file on first `npm run build`.

End-to-end check: bumped package.json to 0.2.1-test, ran build,
confirmed `node dist/index.js --version` printed 0.2.1-test. Reverted.

Future bumps now only need to touch package.json files - the CLI's
runtime version follows automatically.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 11, 2026

Warning

Rate limit exceeded

@naorsabag has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 54 minutes and 8 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: c14ac087-7ec9-4bd4-8772-7161aaab8271

📥 Commits

Reviewing files that changed from the base of the PR and between d2fd53e and 8a317f2.

📒 Files selected for processing (1)
  • packages/cli/package.json

Walkthrough

The PR introduces a build-time version synchronization mechanism for the CLI. A new sync-version.mjs script reads the version from package.json and generates src/version.ts with a VERSION export. A prebuild npm hook runs this script before the build step. The CLI now imports and uses this generated VERSION instead of a hardcoded version string, and src/version.ts is gitignored to prevent committing generated code.

Changes

Version Synchronization System

Layer / File(s) Summary
Version Sync Script & Prebuild Hook
packages/cli/scripts/sync-version.mjs, packages/cli/package.json
New sync-version.mjs script reads version from package.json, generates src/version.ts exporting the VERSION constant with an auto-generated banner, and is executed by a new prebuild npm script before the build step.
CLI Version Import & Registration
packages/cli/src/index.ts
CLI now imports VERSION from the generated version.js and passes it to Commander's version() method instead of the hardcoded '0.2.0' string.
Generated File Gitignore
.gitignore
Gitignore rule prevents committing the generated src/version.ts file, as it is produced by the prebuild script and should not be version-controlled.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • naorsabag/openhop#73: Both PRs modify how the CLI's displayed version is provided—this PR replaces the hardcoded version with a generated export via sync script, while PR #73 directly updates the hardcoded version value.
  • naorsabag/openhop#102: Both PRs update the CLI version reporting in packages/cli/src/index.ts—this PR introduces a generated VERSION import, while PR #102 directly updates the hardcoded version string.
  • naorsabag/openhop#98: Both PRs modify the CLI version in packages/cli/src/index.ts—this PR replaces hardcoded version with a generated import from sync-version.mjs, while PR #98 directly updates that hardcoded value.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: making the CLI read its version from package.json via a prebuild script instead of hardcoding it.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/cli-version-from-package-json

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/cli/package.json`:
- Around line 39-40: The typecheck fails because the generated version module is
only created in the "prebuild" hook; update package.json to run the version
generator before typecheck as well by extracting the generator command (node
scripts/sync-version.mjs) into a shared script name (e.g., "sync:version") and
invoke that script from both "prebuild" and "typecheck" entries so the
./version.js module exists when running the "typecheck" (watch for the existing
"build" and "prebuild" scripts and reuse the same "sync-version.mjs"
invocation).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 110588c2-3c74-45ad-9252-f6e76ace5e16

📥 Commits

Reviewing files that changed from the base of the PR and between c006a94 and d2fd53e.

📒 Files selected for processing (4)
  • .gitignore
  • packages/cli/package.json
  • packages/cli/scripts/sync-version.mjs
  • packages/cli/src/index.ts

Comment thread packages/cli/package.json Outdated
CI failed on PR #139 with TS2307 because the workflow runs
typecheck (`tsc --noEmit`) BEFORE build, but only `prebuild`
generated the gitignored src/version.ts. tsc had nothing to resolve.

Same finding raised by CodeRabbit (one inline comment, packages/cli/
package.json:40). Resolved per their suggested patch: extract a
shared `sync:version` script and run it from `pretypecheck`,
`prebuild`, and `prestart` so every consumer that traces src/index.ts
gets version.ts first.

Local repro: `rm src/version.ts && npm run typecheck` succeeds.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@naorsabag naorsabag merged commit d4fce83 into master May 11, 2026
8 checks passed
@naorsabag naorsabag deleted the chore/cli-version-from-package-json branch May 15, 2026 16:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant