Merge pull request 'The Steam Deck updater kept sabotaging its own next update, and hand-deleting a file was the only way through' (#122) from worktree-steamdeck-update-bunnix-dirt into main
ci / docs-site (push) Successful in 1m8s
ci / web (push) Successful in 1m17s
docker / builders (--build-arg FEDORA_VERSION=44, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm, -f44) (push) Successful in 16s
ci / bun-nix (push) Successful in 20s
docker / builders (ci/android-ci.Dockerfile, punktfunk-android-ci) (push) Successful in 9s
docker / builders (ci/arch-ci.Dockerfile, punktfunk-arch-ci) (push) Successful in 8s
docker / builders (ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 6s
docker / builders (ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 5s
docker / builders (ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 6s
docker / apps (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 10s
docker / builders-arm64cross (push) Successful in 7s
ci / rust-arm64 (push) Successful in 2m36s
docker / apps (., web/Dockerfile, punktfunk-web) (push) Successful in 48s
docker / deploy-docs (push) Successful in 28s
ci / rust (push) Successful in 12m23s

Reviewed-on: #122
This commit was merged in pull request #122.
This commit is contained in:
2026-08-08 21:17:27 +00:00
2 changed files with 34 additions and 3 deletions
+4 -1
View File
@@ -154,7 +154,10 @@ if [ "$WITH_WEB" = 1 ]; then
distrobox enter "$BOX" -- bash -lc "
set -e
export PATH=\$HOME/.bun/bin:\$PATH
cd '$SRC/web' && bun install --frozen-lockfile && bun run build
# --ignore-scripts + explicit codegen: keep in step with scripts/steamdeck/update.sh, which
# explains why (web's `postinstall` writes the COMMITTED web/bun.nix; its `prepare`/codegen is
# required because src/api/gen, src/paraglide and src/routeTree.gen.ts are gitignored).
cd '$SRC/web' && bun install --frozen-lockfile --ignore-scripts && bun run codegen && bun run build
"
[ -f "$SRC/web/.output/server/index.mjs" ] || die "web build did not produce web/.output/server/index.mjs"
ok "web console built"
+30 -2
View File
@@ -27,7 +27,28 @@ TARGET_DIR="$SRC/target-steamos"
WEB=0; [ -f "$HOME/.config/systemd/user/punktfunk-web.service" ] && WEB=1
if [ "${1:-}" = "--pull" ]; then
if [ -d "$SRC/.git" ]; then log "git pull"; git -C "$SRC" pull --ff-only; ok "pulled"; else die "$SRC is not a git checkout — rsync new source then run without --pull"; fi
[ -d "$SRC/.git" ] || die "$SRC is not a git checkout — rsync new source then run without --pull"
# web/bun.nix and sdk/bun.nix are GENERATED (bun2nix, a pure function of the matching bun.lock —
# packaging/nix/README.md) yet COMMITTED, because the Nix build fetches node_modules only from
# them. Until the --ignore-scripts fix below, web's `bun install` here ran its `postinstall`
# (`bun2nix -o bun.nix`) and rewrote that tracked file on every single update. That is invisible
# while the committed file is in sync — but main carried a STALE web/bun.nix from 1db8f763 to
# b79d90b4, so any Deck updated in that window had the file rewritten to the *correct* content
# and has been sitting dirty ever since. The next `git pull --ff-only` that touches it then dies
# with "Your local changes to the following files would be overwritten by merge", and the update
# stops before a single service is restarted.
#
# Restore ONLY these two derived paths. Not a blanket `git reset --hard`: $SRC is the operator's
# own checkout (they may have patched a source file, or be carrying a cherry-pick), and silently
# deleting that to save an update is a far worse trade than one legible error. Discarding these
# two is provably lossless — regenerating them from the lockfiles is exactly what bun2nix does.
git -C "$SRC" checkout -- web/bun.nix sdk/bun.nix 2>/dev/null || true
log "git pull"
git -C "$SRC" pull --ff-only \
|| die "git pull --ff-only failed in $SRC. If it named locally-modified files, this checkout
has local changes: review them with 'git -C $SRC status', then commit or stash them (or discard
one with 'git -C $SRC checkout -- <file>') and re-run. Nothing was rebuilt or restarted."
ok "pulled"
fi
log "Rebuilding host (release)"
@@ -36,7 +57,14 @@ distrobox enter "$BOX" -- bash -lc "set -e; export PATH=\$HOME/.cargo/bin:\$PATH
ok "host rebuilt"
if [ "$WEB" = 1 ]; then
log "Rebuilding web console"
distrobox enter "$BOX" -- bash -lc "set -e; export PATH=\$HOME/.bun/bin:\$PATH; cd '$SRC/web' && bun install --frozen-lockfile && bun run build"
# --ignore-scripts, then `bun run codegen` explicitly: web has TWO install lifecycle scripts and
# we want exactly one of them. `prepare` (= codegen: orval + paraglide + the i18n check) is
# REQUIRED — src/api/gen, src/paraglide and src/routeTree.gen.ts are gitignored, and `prebuild`
# only re-runs orval, so dropping codegen leaves the build without its i18n messages. But
# `postinstall` (`bun2nix -o bun.nix`) writes a COMMITTED file, and an updater must never dirty
# the tree it just pulled into — that is what broke `--pull` above. The SDK install below has
# always passed --ignore-scripts, which is why only web/bun.nix ever went dirty.
distrobox enter "$BOX" -- bash -lc "set -e; export PATH=\$HOME/.bun/bin:\$PATH; cd '$SRC/web' && bun install --frozen-lockfile --ignore-scripts && bun run codegen && bun run build"
ok "web rebuilt"
fi