fix(nix): move the bun packages to bun2nix — no more hand-bumped deps hash

`nix build .#punktfunk-web` has been broken since 1e9957d9 re-resolved
web/bun.lock: the console's node_modules came from a fixed-output derivation
whose single aggregate `outputHash` was last refreshed in 4094f620, so every
lockfile change silently invalidated it and the fix required a round-trip on a
Linux nix box (build, read the `got:` hash, paste it back). The runner
(sdk/bun.lock) had the same latent trap.

Replace both FODs with bun2nix (github:nix-community/bun2nix, pinned to 2.1.2).
`fetchBunDeps` turns a generated, committed `bun.nix` into bun's global install
cache — ONE `fetchurl` per package, keyed by the integrity hash already in the
lockfile — and the setup hook then runs a fully offline `bun install` in
`bunRoot`. There is no aggregate hash left to go stale. The `@unom` scope needs
no special handling: bun.lock records those tarballs' full git.unom.io URLs and
the registry is read-public.

`bun.nix` keeps itself in step: `bun2nix` is now a devDependency of both
packages and regenerates the file on every `bun install` — web via
`postinstall`, the SDK via `prepare`, because sdk/ is the published
@punktfunk/host package and a postinstall would fire on consumers' installs.
Both the flake input and the npm devDependency are pinned to the same exact
version; `bun.nix` has no schema stability guarantee across bun2nix releases, so
they move together (README documents this).

Dropped along the way: the manual `cp -R ${deps}/node_modules` + `chmod -R u+w`
+ `patchShebangs web/node_modules` dance, since bun2nix patches shebangs inside
the cache. `dontUseBunPatch` keeps the hook from running `patchShebangs .` over
the whole repo checkout (it would rewrite scripts/web-init.sh, which we ship
verbatim); `dontRunLifecycleScripts` preserves the old `--ignore-scripts`
behaviour, so playwright still never tries to download browsers.

Verified on a Linux nix box (Determinate Nix 3.21.5): `.#punktfunk-web` and
`.#punktfunk-scripting` both build green, offline; the i18n guard reports its
421 compiled messages, the `Bun.serve` bundle guard passes, and
`nix run .#punktfunk-scripting -- --list` discovers an installed plugin.
`nix flake show --all-systems` evaluates every output.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 4cfe7f05ee608868857be9e7eec079044448a965)
This commit is contained in:
2026-07-28 17:01:59 +02:00
parent 0d8862457b
commit 1db8f7631b
10 changed files with 5529 additions and 190 deletions
+13 -2
View File
@@ -8,6 +8,15 @@
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
# The bun packages' node_modules (punktfunk-web, punktfunk-scripting): one fetchurl per package,
# straight out of `bun.lock`'s integrity hashes — no hand-maintained aggregate deps hash to bump.
# PIN THE TAG. `bun.nix` has no schema stability guarantee across bun2nix versions, so this ref
# must move together with the `bun2nix` devDependency in web/package.json + sdk/package.json
# (which regenerates the file on every `bun install`). See packaging/nix/README.md.
bun2nix = {
url = "github:nix-community/bun2nix?ref=2.1.2";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
@@ -16,6 +25,7 @@
nixpkgs,
crane,
rust-overlay,
bun2nix,
}:
let
# Linux/x86_64 only — the host encodes with desktop NVENC and CI publishes no aarch64 leg
@@ -49,6 +59,8 @@
craneLib = craneLibFor pkgs;
src = self;
inherit version;
# `.hook` + `.fetchBunDeps` (bun2nix v2 API) — see packages.nix.
bun2nix = bun2nix.packages.${system}.default;
};
in
{
@@ -99,8 +111,7 @@
}
);
# `nix flake check` builds every package (web included — needs its deps hash filled in, see
# packaging/nix/README.md).
# `nix flake check` builds every package.
checks = forAllSystems (
system:
let