ci: stop disk reclaim from deleting a smoke image mid-test
Lint / skill-floor (push) Successful in 9s
Lint / hadolint (push) Successful in 15s
Lint / actionlint (push) Successful in 22s
Lint / doc-drift (push) Successful in 12s

v1.12.2 run 740: build-variant's `docker system prune -af --volumes`
untagged pi-devbox:smoke-studio 30 ms after smoke-studio loaded it, so
every studio assertion failed and the -studio tags were not published.
All jobs share the runner's Docker daemon, and a smoke image is unused
between smoke-test.sh's one-shot `docker run`s.

- scripts/ci-reclaim-docker.sh: the same reclaim, per object type, but
  never prunes an image labelled se.jordbo.pi-devbox.ci-smoke-image;
  labelled orphans are swept after 6h. `assert-protected IMG` is the
  smoke preflight; `lint WORKFLOW...` rejects raw system/image prunes.
- smoke jobs: label their image, assert it, tag it per run
  (pi-devbox:smoke[-studio]-<run_id>), remove it in an always() step.
- all five reclaim sites call the script; lint.yml runs the guard.
- Job order unchanged: studio jobs still gate only the -studio tags.

Verified on an isolated docker:29-dind (old prune deletes a labelled
image; new reclaim keeps it, removes unlabelled + 1970-created labelled
images, spares an in-use image, no errors); actionlint, shellcheck,
lint-shell, check-workflow-shell, check-doc-drift all clean.
This commit is contained in:
2026-10-23 08:34:39 +02:00
parent fb2cb2305c
commit 12e66aa52e
5 changed files with 193 additions and 14 deletions
+35
View File
@@ -11,6 +11,41 @@ Pre-v1.0.0 tags followed the pi npm version (`v{pi_version}[letter]`).
---
## Unreleased
### Fixed
- **CI: a smoke job's image could be deleted mid-test by another job's disk
reclaim.** This is why v1.12.2's `-studio` tags were not published by its
tag run. All `docker-publish.yml` jobs share the runner's Docker daemon, and
each began with `docker system prune -af --volumes`, which removes every
image that no container is using at that moment. A smoke image is unused
between `smoke-test.sh`'s one-shot `docker run`s. In run 740, `smoke`
passed and `build-variant` started. Its prune logged
`untagged: pi-devbox:smoke-studio` at 22:58:49.11Z, 30 ms after
`smoke-studio` had loaded that image. Every studio assertion then failed with
"Unable to find image … locally", and `build-variant-studio` was skipped.
`v1.12.2` and `latest` were published; `v1.12.2-studio` and
`latest-studio` were not, until the failed jobs were re-run. Now every job
reclaims disk through the new `scripts/ci-reclaim-docker.sh`. It does the
same work as before (stopped containers, unused images, networks, anonymous
volumes, build cache) but never prunes an image labelled
`se.jordbo.pi-devbox.ci-smoke-image`. The smoke builds apply that label, a
preflight fails if it is missing, and each smoke job removes its own image at
the end. Smoke images left by a killed job are swept once they are older
than 6 h. Smoke tags carry the run id (`pi-devbox:smoke-<run_id>`), so two
runs on different refs cannot test or delete each other's image. `lint.yml`
fails on any raw `docker system|image prune` in a workflow. Job order is
unchanged: the studio jobs still gate only the `-studio` tags. Reordering
could not have closed the race anyway, since the two smoke jobs also prune
each other whenever their start times drift. Measured 2026-10-23 on an
isolated `docker:29-dind` (engine 29.9.2; the runner has 29.7.2). The old
prune deletes an unused labelled image (the bug). The new reclaim keeps a
fresh labelled image, deletes an unlabelled one and a labelled one created
in 1970, keeps an image a running container uses, and prints no errors.
`assert-protected` passes the labelled image and fails both an unlabelled
and a missing one.
## v1.12.2 — 2026-10-22
Patch release. Headline: **pi `1.4.0`** (audited, see *Changed* below), plus