Skip to content

pin @machine0/cli@1.0.164, drop the npm builder - #3

Merged
barnaby merged 2 commits into
mainfrom
bump-1.0.164
Aug 21, 2026
Merged

pin @machine0/cli@1.0.164, drop the npm builder#3
barnaby merged 2 commits into
mainfrom
bump-1.0.164

Conversation

@barnaby

@barnaby barnaby commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

What

Pins @machine0/cli 1.0.155 → 1.0.164 and replaces buildNpmPackage with a plain unpack-and-wrap, removing the vendored package-lock.json, the npmDepsHash pin, and the postPatch.

Why the pin was stuck

The daily cron has been reporting success while changing nothingmain still said 1.0.155 seventeen hours after the last green run.

./update.sh was aborting halfway. It printed the new tarball hash, then exited non-zero before rewriting flake.nix:

pinning @machine0/cli@1.0.164
  hash: sha256-7BLWBUZcV7l4KTwf0RvIn2+z7P1w5Q4KWAwsiA1jHdw=
error: could not compute npmDepsHash

1.0.164 has no runtime dependencies, and buildNpmPackage cannot express that. Regenerating the lockfile now yields a single empty root package, and prefetch-npm-deps rejects it outright:

Error: No cacheable dependencies were found.

npmDepsHash came back empty, the script's own guard exited 1, and the workflow's 5× retry loop would have failed identically on every future release.

Why the dependencies disappeared

fdmtl/machine0#626 externalised open and update-notifier out of the CLI bundle to fix a Windows crash, which made the tarball non-self-contained from 1.0.147. fdmtl/machine0#733 re-bundled both and returned them to devDependencies, keeping the --format=esm flag that is the part of #626 actually responsible for the Windows fix. (CJS output erases import.meta.url, which open uses to locate its vendored xdg-open helper; ESM preserves it. The externalisation was not load-bearing.) machine0's CLI Package (Windows, Node 20.12) job passes on #733.

The trade, and how it's guarded

Rather than set forceEmptyCache to keep an npm builder that installs nothing, this drops the builder. The risk that introduces: a future release reintroducing runtime dependencies would build fine and then die on the user's first invocation with ERR_MODULE_NOT_FOUND — invisible at build time. That exact failure shipped to every consumer packaging the tarball directly (fdmtl/machine0-nixos#31).

Guarded in two places:

  • ./update.sh inspects the tarball's package.json and refuses to pin a release with a non-empty dependency tree, naming the offenders.
  • The derivation runs the same assertion as an installCheckPhase, so a hand-edited pin fails at build time.

Verification

Check Result
./update.sh 1.0.163 (known-bad release) refused, named open + update-notifier, flake.nix untouched
nix build .#default ok
nix run .#default -- --version 1.0.164
./update.sh re-run idempotent, no diff

Also

update-pin.yml referenced package-lock.json in its diff check and its git add. Left as-is, git add flake.nix package-lock.json would fail on a deleted path and break the workflow — both references removed. README updated to describe the packaging accurately.

The pin was stuck at 1.0.155 even though the daily cron reported success.
`./update.sh` was aborting halfway: it printed the new tarball hash, then
exited non-zero before rewriting flake.nix, leaving the pins stale.

Cause: 1.0.164 has no runtime dependencies, and `buildNpmPackage` cannot
express that. Regenerating the lockfile now produces a single empty root
package, and `prefetch-npm-deps` refuses it:

    Error: No cacheable dependencies were found.

So `npmDepsHash` came back empty and the script's own guard exited 1. The
GitHub workflow retried five times and would have failed the same way on
every future release.

The dependencies existed because fdmtl/machine0#626 externalised `open`
and `update-notifier` out of the CLI bundle to fix a Windows crash.
fdmtl/machine0#733 re-bundled them and returned them to devDependencies,
keeping the `--format=esm` flag that was the part of #626 actually
responsible for the Windows fix. From 1.0.164 the tarball is
self-contained again.

Rather than set `forceEmptyCache` to keep an npm builder that installs
nothing, drop the builder: unpack the tarball and wrap bin/entry.cjs with
node. That removes the vendored package-lock.json, the npmDepsHash pin,
and the postPatch that stripped bun `workspace:*` devDependencies npm
could not parse.

The risk this trades into is that a future release reintroducing runtime
dependencies would build fine and fail on the user's first invocation
with ERR_MODULE_NOT_FOUND. Guarded twice:

  - `./update.sh` inspects the tarball's package.json and refuses to pin a
    release with a non-empty dependency tree, naming the offenders.
  - The derivation runs the same assertion as an installCheckPhase, so a
    hand-edited pin fails at build time rather than at runtime.

Verified: `./update.sh 1.0.163` (the known-bad release) is rejected with
both package names and leaves flake.nix untouched; `nix build` succeeds
on 1.0.164 and `--version` reports 1.0.164; re-running `./update.sh` is
idempotent.
@greptile-apps

greptile-apps Bot commented Aug 21, 2026

Copy link
Copy Markdown

Greptile Summary

Pins @machine0/cli to 1.0.164 and replaces the npm builder with a direct unpack-and-wrap derivation.

  • Adds matching update-time and build-time checks that reject runtime dependencies, including optional dependencies.
  • Updates the pin workflow to track and commit only flake.nix.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains; the previously reported optional-dependency gap is addressed consistently in both the updater and build-time validation.

Important Files Changed

Filename Overview
update.sh Replaces lockfile and npm dependency-hash generation with a dependency-free package assertion that now covers both regular and optional dependencies.
flake.nix Pins CLI 1.0.164, installs the bundled package directly, wraps its entry point, and verifies that the package declares no runtime dependencies.
.github/workflows/update-pin.yml Removes deleted lockfile references from change detection and automated commits.

Reviews (2): Last reviewed commit: "guard optionalDependencies too" | Re-trigger Greptile

Comment thread update.sh Outdated
Greptile flagged that both the updater check and the installCheckPhase
only inspected `.dependencies`. npm installs `optionalDependencies` on a
normal `npm i -g` as well, so a release moving a package there would slip
past the guard and reintroduce exactly the ERR_MODULE_NOT_FOUND failure
this packaging is trying to prevent.

Both checks now inspect the union. `peerDependencies` is deliberately
excluded — supplying those is the consumer's job, not the tarball's.

Verified: 1.0.163 is still rejected (open, update-notifier), a synthetic
package.json with only optionalDependencies is now counted, and
`nix build` + `--version` still pass on 1.0.164.
@barnaby
barnaby merged commit 4fb7859 into main Aug 21, 2026
3 checks passed
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