forked from RoushTech/docker
Run the whole repo in one concurrency lane #45
Loading…
Reference in a new issue
No description provided.
Delete branch "ci/serialize-runs"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The concurrency group keyed on the ref, which serialises nothing: different branches get different groups, so branch runs always executed concurrently. They share one Swarm manager and one disk, so they did not merely contend -- they took each other out, and always after the expensive part was already done:
Bind for 0.0.0.0:3181 failed: port is already allocated-- another run held thetest-healthchecks.ymlhost portsfrontend grpc server closed unexpectedly, with four runs in flightCLAUDE.md already records the same shape for
no space left on deviceandInternal: unknown blob sha256:...(buildkit GC evicting blobs out from under an in-flight export). None of it says anything about the change under test, and each one costs a full re-run -- so a large share of the time spent waiting for this pipeline was spent waiting for it twice.So: one lane for the workflow. Runs queue instead of overlapping.
Why not cancel-in-progress
It stays
false. Cancelling a main run mid-publish leaves some targets pushed and some not, which is how the registry ended up holding an incomplete set of build-stamped tags -- runs 265 and 270, both killed 7s intopushing layers.Queued runs still do not pile up: while one run holds the lane, only the newest queued run survives and older pending ones are dropped. The trade is that pushing again no longer kills a run that has already started; it queues behind it.
Note on the ports
The 26 published host ports in
test-healthchecks.ymlare still fixed and still global to the daemon -- #43 gave each run its own compose project, but not its own ports. Serialising is what stops them colliding. Switching them to ephemeral ("80") would make collisions structurally impossible and was the alternative considered here; it was not taken because it would cost the stablelocalhost:3084-style ports used for local debugging.Anything else sharing that daemon can still collide with us; the lane only covers this workflow.
Validated with
act -n(both jobs).🤖 Generated with Claude Code
The concurrency group keyed on the ref, which serialises nothing: different branches get different groups, so branch runs always executed concurrently. They share one Swarm manager and one disk, so they did not merely contend, they took each other out -- and always after the expensive part was already done: run 317 main all ~40 images built, then died bringing containers up on `Bind for 0.0.0.0:3181 failed: port is already allocated`; another run held the healthcheck ports run 314 branch `frontend grpc server closed unexpectedly`, with four runs in flight at once CLAUDE.md already records the same shape for `no space left on device` and `Internal: unknown blob sha256:...`. None of it says anything about the change under test, and each one costs a full re-run -- which is to say most of the time spent waiting for this pipeline was spent waiting for it twice. So: one lane for the workflow. Runs queue instead of overlapping. cancel-in-progress stays false. Cancelling a main run mid-publish leaves some targets pushed and some not, which is how the registry ended up holding an incomplete set of build-stamped tags (265 and 270, both killed 7s into `pushing layers`). Queued runs still do not pile up: while one holds the lane only the newest queued run survives. The trade is that pushing again no longer kills a run that has already started. Note the healthcheck host ports are still fixed and still global to the daemon; serialising is what stops them colliding. Anything else sharing that daemon can still collide with us. Co-Authored-By: Claude <noreply@anthropic.com>