release(v1.11.2): smoke esbuild check present-iff-declared; pi-studio 0.10.1
Lint / hadolint (push) Successful in 8s
Lint / skill-floor (push) Successful in 13s
Lint / doc-drift (push) Successful in 17s
Lint / actionlint (push) Successful in 30s
Publish Docker Image / lint-gate (push) Successful in 26s
Publish Docker Image / resolve-versions (push) Successful in 16s
Publish Docker Image / base-decide (push) Successful in 15s
Publish Docker Image / build-base (push) Has been skipped
Publish Docker Image / smoke (push) Successful in 5m25s
Publish Docker Image / smoke-studio (push) Successful in 8m40s
Publish Docker Image / build-variant (push) Successful in 16m48s
Publish Docker Image / update-description (push) Successful in 8s
Publish Docker Image / promote-base-latest (push) Successful in 9s
Publish Docker Image / build-variant-studio (push) Successful in 21m23s

v1.11.1 (run 724) was tagged and never published: the smoke assertion
"esbuild works at every install site" required esbuild to exist, and pi
1.2.0 dropped @earendil-works/chord, its only source. The image was right.

- smoke-test.sh: esbuild must be present iff an installed package root or
  /opt repo root declares it, and compile at every site. Body tested 8 ways
  (v1.11.0-studio ok; sites removed / natives pruned / residue / bare
  declarer fail; fixture decoy ignored; v1.11.2 candidates ok). Full smoke
  on local arm64 candidates with run 724's args: old script 102/1 (CI
  reproduced), new core 103/0, studio 106/0 (0.9.63 and 0.10.1).
- pi-studio v0.9.63 -> v0.10.1 (tagged 2026-10-14; CI takes the newest
  tag): devbox contract unchanged (manifest, client bundle, 11 tools, 6
  commands, --no-browser/--port/--listen-all, env vars); exercised under pi
  1.2.0 in headless Chromium (render, Run Prompt via ERDC, Files ->
  Document, port freed); in-image TUI starts with no extension issues.
- CHANGELOG v1.11.1 -> v1.11.2; Dockerfile.variant/workflow cycle notes.
  No base input changed: base-6f3b20266de1 (built by run 724) is reused.
This commit is contained in:
2026-10-14 07:28:38 +02:00
parent 4efa84bb42
commit bf265f6d54
4 changed files with 121 additions and 19 deletions
+36 -3
View File
@@ -30,7 +30,8 @@
# client bundle present + registered via `pi install`
# - no foreign npm-11 platform packages (@esbuild, clipboard) beyond the host
# - no build-time npm cache (/root/.npm) shipped in the image
# - esbuild compiles everywhere; clipboard present iff pi declares it
# - esbuild present iff something declares it, and compiles everywhere;
# clipboard present iff pi declares it
# - image size within threshold
set -euo pipefail
@@ -985,8 +986,40 @@ run "no build-time npm cache shipped (/root/.npm)" \
# runbook as "if this fails, revert the release", and it duly failed for the
# wrong reason on the first machine that ran it. A check must fail only for the
# thing it is checking.
run "esbuild works at every install site (prune removed weight, not function)" \
'sites=$(find /usr/lib/node_modules /opt -type d -path "*/node_modules/esbuild" -prune 2>/dev/null); if [ -z "$sites" ]; then echo "no esbuild install found at all" >&2; exit 1; fi; for d in $sites; do node -e "require(\"$d\").transformSync(\"const x:number=1\",{loader:\"ts\"})" || { echo "esbuild broken at $d" >&2; exit 1; }; done; echo ok'
#
# PRESENT IFF DECLARED, like clipboard below. esbuild was never a direct pi
# dependency: it arrived through @earendil-works/chord (pi 1.1.0 > chord >
# esbuild 0.28.2, at both the pi and pi-fork sites). pi 1.2.0 dropped chord, so
# a correct 1.2.0 image has NO esbuild, and the old "must exist" form failed the
# v1.11.1 tag build (102/103 core, 105/106 studio, nothing published) against a
# good image — the same mistake the clipboard check made at v1.10.0. Because it
# is transitive, "declared" cannot be read from pi's package.json: it is
# derived from every INSTALLED package root (node_modules/<pkg>/package.json,
# node_modules/@scope/<pkg>/package.json) and every /opt repo root, counting
# dependencies, optionalDependencies and peerDependencies (devDependencies are
# not installed: --omit=dev). Anchoring on package roots keeps a test fixture's
# package.json from counting. Both directions fail: declared but missing (the
# prune removed function), and installed with nothing declaring it (residue).
run "esbuild: present iff something declares it, and works at every install site (prune removed weight, not function)" \
'declarers=$(find /usr/lib/node_modules /opt -regextype posix-extended -type f \( -regex ".*/node_modules/(@[^/]+/)?[^/]+/package\.json" -o -regex "/opt/[^/]+/package\.json" \) 2>/dev/null | node -e "
const fs = require(\"fs\"); const hit = [];
for (const f of fs.readFileSync(0, \"utf8\").split(String.fromCharCode(10)).filter(Boolean)) {
let j; try { j = JSON.parse(fs.readFileSync(f, \"utf8\")); } catch (e) { continue; }
if (!j || j.name === \"esbuild\") continue;
for (const k of [\"dependencies\", \"optionalDependencies\", \"peerDependencies\"]) {
if (j[k] && Object.prototype.hasOwnProperty.call(j[k], \"esbuild\")) { hit.push(f); break; }
}
}
console.log(hit.join(\" \"));") || { echo "declarer scan itself failed" >&2; exit 1; };
sites=$(find /usr/lib/node_modules /opt -type d -path "*/node_modules/esbuild" -prune 2>/dev/null);
if [ -n "$declarers" ]; then
[ -n "$sites" ] || { echo "declared by $declarers but NO install found - prune removed function" >&2; exit 1; };
for d in $sites; do node -e "require(\"$d\").transformSync(\"const x:number=1\",{loader:\"ts\"})" || { echo "esbuild broken at $d" >&2; exit 1; }; done;
echo "ok: declared ($(echo $declarers | wc -w) package(s)) and compiles at $(echo $sites | wc -w) site(s)";
else
[ -z "$sites" ] || { echo "nothing declares esbuild yet installs remain: $sites" >&2; exit 1; };
echo "ok: nothing declares esbuild (pi >= 1.2.0 dropped chord); no install expected";
fi'
# Clipboard is the family pruned second. Upstream pi 0.86.0 (#9163) REPLACED the
# external `@mariozechner/clipboard` dependency with bundled macOS/Windows/X11