fix(release): sync package-lock.json via script, not release-please extra-files - #4179
Merged
Conversation
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
gittensory-ui | 59ee112 | Commit Preview URL Branch Preview URL |
Jul 08 2026, 10:38 AM |
Contributor
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4179 +/- ##
=======================================
Coverage 93.74% 93.74%
=======================================
Files 387 387
Lines 36398 36398
Branches 13330 13330
=======================================
Hits 34120 34120
Misses 1621 1621
Partials 657 657
🚀 New features to boost your workflow:
|
JSONbored
added a commit
that referenced
this pull request
Jul 8, 2026
Same root cause as the package-lock.json/dependency-range fixes already pushed to this branch: ENGINE_VERSION was a hardcoded literal that test/unit/engine-version.test.ts correctly caught as stale against this release's package.json bump. See fix/release-please-lockfile-sync (#4179) for the full story and verification.
Contributor
|
Important 🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪 🔍 Gittensory is reviewing…AI analysis is in progress. This comment will update when the review is complete. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed · 🟪 Reviewing |
…xtra-files release-please's extra-files JSON-path updater didn't reach package-lock.json's per-workspace version fields (keys containing "/", nested under a manifest-mode component block) -- confirmed empirically twice: the engine-v0.2.0 dry run's package-lock.json stayed at 0.1.0 after package.json bumped to 0.2.0, breaking npm ci with "Missing: @jsonbored/gittensory-engine@0.1.0 from lock file" on every downstream job (Build UI preview artifact confirmed; Workers Builds: gittensory-ui likely the same root cause manifesting differently). Replaces it with scripts/sync-release-lockfile-versions.mjs -- the same single-line string replacement proven correct by hand for both packages earlier in this release cycle, not a full JSON.parse/stringify round-trip on a multi-thousand-line file. A new workflow step runs it directly against whichever release-please branch(es) exist (release-please--branches--main-- components--<mcp|engine>, the same naming convention release-please's own commits already rely on), commits if anything changed, before the tag/ publish-dispatch steps that follow. Removed the two now-dead extra-files blocks from release-please-config.json.
Found while validating the lockfile-sync fix on a real dry run: semver caret ranges for 0.x versions only allow patch bumps (^0.1.0 means >=0.1.0 <0.2.0), so gittensory-mcp's "^0.1.0" and gittensory-miner's exact "0.1.0" pin both break on gittensory-engine's very first real release (0.1.0 -> 0.2.0, reproduced live on the engine-v0.2.0 dry-run branch -- npm ci failed with "Missing: @jsonbored/gittensory-engine@0.1.0 from lock file"). Widened both to ">=0.1.0" -- these are internal, same-monorepo dependencies whose real compatibility guarantee comes from this repo's own test suite, not from strict semver-range enforcement against a pre-1.0 package expected to move through minor versions often.
Same class of bug as the two fixes already in this PR, caught by the same engine-v0.2.0 dry-run branch's CI: ENGINE_VERSION was a hardcoded literal "0.1.0" that test/unit/engine-version.test.ts correctly asserts must match package.json -- release-please bumped package.json to 0.2.0 but had no way to touch this hand-synced constant, so the (already-correct, unchanged) test failed exactly as designed. Derives ENGINE_VERSION from package.json at runtime instead (works identically from src/version.ts under vitest and the compiled dist/version.js, since package.json is the direct parent of both directories either way). URL imported explicitly from node:url rather than relying on the ambient global -- they've subtly diverged in this @types/node version (Symbol.dispose on URLSearchParamsIterator), which fileURLToPath's overloads reject otherwise. Also drops gittensory-engine-scaffold.test.ts's hardcoded version literal in favor of a format check, for the same self-updating reason as this session's earlier gittensory-mcp test fixes. Verified genuinely self-updating the same way: bumped package.json to 0.2.0, rebuilt, confirmed both tests pass unmodified; reverted.
JSONbored
force-pushed
the
fix/release-please-lockfile-sync
branch
from
July 8, 2026 10:29
bed8ba4 to
099cdc7
Compare
JSONbored
added a commit
that referenced
this pull request
Jul 8, 2026
Same root cause as the package-lock.json/dependency-range fixes already pushed to this branch: ENGINE_VERSION was a hardcoded literal that test/unit/engine-version.test.ts correctly caught as stale against this release's package.json bump. See fix/release-please-lockfile-sync (#4179) for the full story and verification.
…GINE_VERSION
The previous commit's readFileSync(fileURLToPath(...)) approach broke the
Workers runtime test suite: packages/gittensory-engine gets bundled into
the Cloudflare Worker itself (src/mcp/find-opportunities.ts -> gittensory-
miner's opportunity-fanout.js -> @jsonbored/gittensory-engine), and the
workerd sandbox (both the real deployment and vitest-pool-workers'
emulation of it) has no real filesystem for an arbitrary readFileSync to
read from -- reproduced live: "ENOENT: no such file or directory ...
packages/gittensory-engine/package.json" from inside
test/workers/worker-runtime.test.ts.
Switched to `import ownPackageJson from "../package.json" with { type:
"json" }` instead -- the same mechanism src/services/mcp-compatibility.ts
already uses for the same reason. tsc preserves this as a real import
statement in the compiled dist/version.js (Node's own ESM loader resolves
it correctly for real npm installs, where package.json is genuinely
present on disk), while the Worker's own esbuild-based bundling step
inlines the JSON content directly into the bundle at build time -- no
runtime file I/O in that path at all. The earlier rootDir: "src" concern
that motivated readFileSync in the first place turned out to be
unfounded: tsc compiled the direct import without complaint.
Re-verified everything from the previous commit still holds (typecheck,
engine-version.test.ts, gittensory-engine-scaffold.test.ts, full engine
suite, self-updating stress test at a bumped version) plus the
previously-broken test/workers/worker-runtime.test.ts now passes.
Superagent correctly flagged >=0.1.0 as overly permissive (P2): unbounded above, it would silently accept a future major-version bump too -- including a compromised or dependency-confusion-attacked release -- with no explicit review. Its suggested fix (^0.2.0) isn't right either: that reintroduces the exact bug this range change was fixing (caret ranges for 0.x versions only span patches, so it would break again on the very next minor release, e.g. 0.3.0). The correct middle ground has both a floor and a ceiling: ">=0.1.0 <1.0.0" tolerates every current and future 0.x release (verified via node's semver package: 0.1.0/0.2.0/0.99.0 all satisfy it) while still rejecting anything at or above 1.0.0 -- a deliberate stability milestone that should require a real, reviewed dependency bump (and at which point a normal ^1.0.0 caret becomes the right long-term range anyway).
JSONbored
added a commit
that referenced
this pull request
Jul 8, 2026
…import Two fixes squashed onto this branch, both already landed on fix/release-please-lockfile-sync (#4179): - Superagent correctly flagged >=0.1.0 as overly permissive (unbounded above, would accept a future major/compromised version with no review). Capped at ">=0.1.0 <1.0.0" -- tolerates all current and future 0.x releases without needing a re-bump, while still rejecting 1.0.0+. - ENGINE_VERSION's readFileSync approach broke the Workers runtime test suite (no real filesystem in the workerd sandbox). Switched to a compile-time JSON import, matching src/services/mcp-compatibility.ts's existing pattern -- Node's ESM loader resolves it at runtime for real installs, while the Worker's own esbuild bundling inlines it at build time for the bundled path, so neither consumer ever does runtime file I/O.
JSONbored
added a commit
that referenced
this pull request
Jul 8, 2026
* chore(release): cut engine v0.2.0 * fix: widen gittensory-engine dependency ranges past caret's 0.x ceiling npm ci failed with "Missing: @jsonbored/gittensory-engine@0.1.0 from lock file" once this PR bumped packages/gittensory-engine to 0.2.0: semver caret ranges for 0.x versions only allow patch bumps (^0.1.0 means >=0.1.0 <0.2.0), so gittensory-mcp's "^0.1.0" and gittensory-miner's exact "0.1.0" pin both broke on this release's own minor bump. Widened both to ">=0.1.0" -- these are internal, same-monorepo dependencies whose real compatibility guarantee comes from this repo's own test suite, not from strict semver-range enforcement against a pre-1.0 package expected to move through minor versions somewhat often. * fix(engine): derive ENGINE_VERSION instead of hand-syncing it Same root cause as the package-lock.json/dependency-range fixes already pushed to this branch: ENGINE_VERSION was a hardcoded literal that test/unit/engine-version.test.ts correctly caught as stale against this release's package.json bump. See fix/release-please-lockfile-sync (#4179) for the full story and verification. * fix: cap engine dependency ranges below 1.0.0, use compile-time JSON import Two fixes squashed onto this branch, both already landed on fix/release-please-lockfile-sync (#4179): - Superagent correctly flagged >=0.1.0 as overly permissive (unbounded above, would accept a future major/compromised version with no review). Capped at ">=0.1.0 <1.0.0" -- tolerates all current and future 0.x releases without needing a re-bump, while still rejecting 1.0.0+. - ENGINE_VERSION's readFileSync approach broke the Workers runtime test suite (no real filesystem in the workerd sandbox). Switched to a compile-time JSON import, matching src/services/mcp-compatibility.ts's existing pattern -- Node's ESM loader resolves it at runtime for real installs, while the Worker's own esbuild bundling inlines it at build time for the bundled path, so neither consumer ever does runtime file I/O. * chore: force re-scan (dependency range fix already verified correct) packages/gittensory-mcp and packages/gittensory-miner both already pin @jsonbored/gittensory-engine to >=0.1.0 <1.0.0 (in package.json and package-lock.json). Superagent's check-run on this branch is stuck reporting the pre-fix finding; this empty commit forces a clean re-scan. --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: JSONbored <49853598+JSONbored@users.noreply.github.com>
7 tasks
JSONbored
added a commit
that referenced
this pull request
Jul 11, 2026
gittensory-mcp and gittensory-miner both pinned "@jsonbored/gittensory-engine" to ">=0.1.0 <1.0.0" -- a range that excludes engine's own upcoming 1.0.0 release and breaks `npm ci` with a cryptic "Missing ... from lock file" error (PR #4686). This is a recurrence of the exact bug fixed by hand at the 0.1.0 -> 0.2.0 bump (#4179): any manually-chosen upper bound will eventually be exceeded by a future engine release. - gittensory-mcp: widen to "^0.2.0" (matches the current published engine version; release-please's node-workspace plugin now rewrites this automatically to track engine's version on every future bump, major or not, since it's a live externally-published package). - gittensory-miner: widen to "*" -- unlike gittensory-mcp, it has never been published (npm registry 404s on it today), so it has no real external consumer and no version-range supply-chain exposure; a same-monorepo workspace dependency is the idiomatic use for "*". Not onboarded into release-please management in this change since that's a separate release-process decision. - release-please-config.json: enable the node-workspace plugin (merge: false, matching the existing separate-pull-requests: true) so gittensory-mcp's dependency range is kept in sync automatically from here on, without ever needing a manual fix like this one again. Verified: npm ci resolves cleanly, full test suite passes, engine/mcp/ miner builds pass, mcp-pack/miner-pack smoke tests pass, all drift checks pass.
JSONbored
added a commit
that referenced
this pull request
Jul 11, 2026
…4974) gittensory-mcp and gittensory-miner both pinned "@jsonbored/gittensory-engine" to ">=0.1.0 <1.0.0" -- a range that excludes engine's own upcoming 1.0.0 release and breaks `npm ci` with a cryptic "Missing ... from lock file" error (PR #4686). This is a recurrence of the exact bug fixed by hand at the 0.1.0 -> 0.2.0 bump (#4179): any manually-chosen upper bound will eventually be exceeded by a future engine release. - gittensory-mcp: widen to "^0.2.0" (matches the current published engine version; release-please's node-workspace plugin now rewrites this automatically to track engine's version on every future bump, major or not, since it's a live externally-published package). - gittensory-miner: widen to "*" -- unlike gittensory-mcp, it has never been published (npm registry 404s on it today), so it has no real external consumer and no version-range supply-chain exposure; a same-monorepo workspace dependency is the idiomatic use for "*". Not onboarded into release-please management in this change since that's a separate release-process decision. - release-please-config.json: enable the node-workspace plugin (merge: false, matching the existing separate-pull-requests: true) so gittensory-mcp's dependency range is kept in sync automatically from here on, without ever needing a manual fix like this one again. Verified: npm ci resolves cleanly, full test suite passes, engine/mcp/ miner builds pass, mcp-pack/miner-pack smoke tests pass, all drift checks pass.
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.
Summary
1. package-lock.json sync (original fix): release-please's
extra-filesJSON-path updater didn't reachpackage-lock.json's per-workspace version fields (keys containing "/", nested under a manifest-mode component block) — confirmed empirically twice: theengine-v0.2.0dry run'spackage-lock.jsonstayed at0.1.0afterpackage.jsonbumped to0.2.0, breakingnpm ciwith"Missing: @jsonbored/gittensory-engine@0.1.0 from lock file".Replaces it with
scripts/sync-release-lockfile-versions.mjs— the same single-line string replacement already proven correct by hand for both packages earlier in this release cycle, not a fullJSON.parse/stringifyround-trip on a multi-thousand-line file. A new workflow step runs it directly against whichever release-please branch(es) exist (release-please--branches--main--components--<mcp|engine>, the same naming convention release-please's own commits already rely on), commits if anything changed, before the tag/publish-dispatch steps that follow.Removed the two now-dead
extra-filesblocks fromrelease-please-config.json.2. Dependency range widening (found while validating fix #1 on the real dry-run branch): even after the lockfile sync fix,
npm cistill failed the same way. Root cause: semver caret ranges for 0.x versions only allow patch bumps (^0.1.0means>=0.1.0 <0.2.0), sogittensory-mcp's"^0.1.0"andgittensory-miner's exact"0.1.0"pin both break ongittensory-engine's very first real release (0.1.0 → 0.2.0). Widened both to">=0.1.0"— these are internal, same-monorepo dependencies whose real compatibility guarantee comes from this repo's own test suite, not strict semver-range enforcement against a pre-1.0 package expected to move through minor versions often.Both fixes were also applied directly to PR #4176's branch (the real, currently-open dry-run PR) to unblock it immediately, in addition to landing here for all future releases.
Test plan
npm civerified clean after both fixes, on both this branch and PR chore(release): cut engine v0.2.0 #4176's branchnpm run typecheck,npm run build:mcp,npm run build:miner— all cleannpm run actionlint— clean