Skip to content

fix(release): sync package-lock.json via script, not release-please extra-files - #4179

Merged
JSONbored merged 5 commits into
mainfrom
fix/release-please-lockfile-sync
Jul 8, 2026
Merged

fix(release): sync package-lock.json via script, not release-please extra-files#4179
JSONbored merged 5 commits into
mainfrom
fix/release-please-lockfile-sync

Conversation

@JSONbored

@JSONbored JSONbored commented Jul 8, 2026

Copy link
Copy Markdown
Owner

Summary

1. package-lock.json sync (original fix): 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".

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 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.

2. Dependency range widening (found while validating fix #1 on the real dry-run branch): even after the lockfile sync fix, npm ci still failed the same way. Root cause: 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). 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

  • Script tested against a simulated broken state (engine bumped to 0.2.0, lockfile left at 0.1.0) — correctly produces a single-line diff
  • Script tested against the current, already-in-sync state — correctly no-ops for both packages
  • npm ci verified clean after both fixes, on both this branch and PR chore(release): cut engine v0.2.0 #4176's branch
  • npm run typecheck, npm run build:mcp, npm run build:miner — all clean
  • npm run actionlint — clean
  • Valid JSON

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 8, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

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

@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@codecov

codecov Bot commented Jul 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.74%. Comparing base (f46aa4a) to head (59ee112).
⚠️ Report is 5 commits behind head on main.
✅ All tests successful. No failed tests found.

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           
Files with missing lines Coverage Δ
packages/gittensory-engine/src/version.ts 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.
@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 8, 2026
@loopover-orb

loopover-orb Bot commented Jul 8, 2026

Copy link
Copy Markdown
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

JSONbored added 3 commits July 8, 2026 03:29
…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
JSONbored force-pushed the fix/release-please-lockfile-sync branch from bed8ba4 to 099cdc7 Compare July 8, 2026 10:29
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.
JSONbored added 2 commits July 8, 2026 03:33
…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
JSONbored merged commit b614317 into main Jul 8, 2026
12 checks passed
@JSONbored
JSONbored deleted the fix/release-please-lockfile-sync branch July 8, 2026 10:48
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>
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant