Skip to content

Repair lockfile pins corrupted by the release version bump - #174

Merged
Sev7eNup merged 1 commit into
mainfrom
fix/corrupt-lockfile-pins
Aug 9, 2026
Merged

Repair lockfile pins corrupted by the release version bump#174
Sev7eNup merged 1 commit into
mainfrom
fix/corrupt-lockfile-pins

Conversation

@Sev7eNup

@Sev7eNup Sev7eNup commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Cutting 1.1.2 replaced every "version": "1.1.1" in the tree instead of just the top-level one, so six transitive entries across the three lockfiles declare a version that does not exist and does not match the tarball they resolve to:

Lockfile Entries
nodepilot-desktop abbrev, object-keys, picocolors
nodepilot-docs-ui picocolors
nodepilot-ui cookie, picocolors

npm ci rebuilds the tree from the lockfile and cross-checks each tarball's own version, so this breaks reproducible installs on any clean install.

The six pins are restored by hand rather than by regenerating — a regeneration would drag unrelated transitive updates into the same commit and hide the actual repair.

Guard against the cause. The corruption comes from a blanket text replace during the release bump; nothing would have stopped it recurring on the next version that collides with a real dependency version. Test-DeploymentTemplates.ps1 (already run on both PowerShell 5.1 and 7 in CI) now asserts that every entry resolving to a registry tarball carries the version that tarball's filename states. It renames npm's empty-string root key before parsing, because Windows PowerShell 5.1 cannot build a PSCustomObject with an empty property name and fails the whole document otherwise.

Also restores two em dashes in TopBar.tsx committed as double-encoded UTF-8 (â€"). Comments only, so nothing behaved differently — but the same round-trip would silently mangle a translated string.

Verification

  • Contract script passes on PS 5.1, and fails with the exact entry named when the corruption is reintroduced.
  • Repo-wide scan finds no other double-encoded source.

Closes #119
Closes #112

Cutting 1.1.2 replaced every `"version": "1.1.1"` in the tree rather than
just the top-level one, so six transitive entries across the three
lockfiles ended up declaring a version that does not exist and does not
match the tarball they resolve to:

  nodepilot-desktop  abbrev, object-keys, picocolors
  nodepilot-docs-ui  picocolors
  nodepilot-ui       cookie, picocolors

`npm ci` rebuilds the tree from the lockfile and cross-checks each
tarball's own version, so this breaks reproducible installs on any
machine that does a clean install. Restore the six pins to 1.1.1 by hand
instead of regenerating - a regeneration would drag unrelated transitive
updates into the same commit and hide the actual repair.

Add a lockfile-integrity contract to the deployment checks, which already
run on both PowerShell 5.1 and 7 in CI: every entry resolving to a
registry tarball must carry the version that tarball's filename states.
Without it the same blanket replace corrupts the locks again on the next
release whose version happens to collide with a real dependency version.
The check renames npm's empty-string root key before parsing because
Windows PowerShell 5.1 cannot build a PSCustomObject with an empty
property name and fails the whole document otherwise.

Also restore two em dashes in TopBar.tsx that were committed as
double-encoded UTF-8 (`â€"`). Comments only, so nothing behaved
differently, but the same round-trip would silently mangle a translated
string.

Closes #119
Closes #112
@Sev7eNup
Sev7eNup merged commit c8bd610 into main Aug 9, 2026
8 checks passed
@Sev7eNup
Sev7eNup deleted the fix/corrupt-lockfile-pins branch August 9, 2026 22:41
@Sev7eNup
Sev7eNup restored the fix/corrupt-lockfile-pins branch August 9, 2026 22:42
@Sev7eNup
Sev7eNup deleted the fix/corrupt-lockfile-pins branch August 9, 2026 22:43
@Sev7eNup Sev7eNup mentioned this pull request Aug 9, 2026
hshalab pushed a commit to hshalab/NodePilot that referenced this pull request Aug 14, 2026
Bumped through `npm version --no-git-tag-version` per package rather than
a text replace over the tree, so only the top-level version and its
lockfile root entry move - six lines total, no transitive pin touched.
The blanket replace is what corrupted three lockfiles on 1.1.2; the
integrity contract added in Sev7eNup#174 now guards the result.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant