ci: stop disk reclaim from deleting a smoke image mid-test
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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user