From 4209d94fd177943ae4f85baa8039ab94059db6b0 Mon Sep 17 00:00:00 2001 From: Tobias Fischer Date: Fri, 23 Oct 2026 16:10:35 +1000 Subject: [PATCH] Build branches: a newer run cancels the older one A new push to a build branch (after a merge to main) brings the latest recipes and workflow; the older run's plan is out of date. The new run skips what the old one uploaded already, so only the packages its cancelled jobs had built but not uploaded are built again. Re-run failed jobs only in the newest run: re-running an older one would cancel the newer run. Co-Authored-By: Claude Opus 5.5 --- README.md | 1 + tools/robostack.py | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 9f7b9ab54..9a3b64a21 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,7 @@ changes no packages (tooling, CI, docs) gets `build:none`: only the checks run. - Each build branch carries its workflow as `.github/workflows/build.yaml`, which runs `.scripts/build_*.sh` in `distros//work`. - The workflow builds in stages (by dependency depth), each stage in parallel jobs. Each job records how long its recipes took to build and keeps that as an artifact; `robostack-bot update-build-timings` merges them weekly into `shared/build_timings/.json` (each recipe's time per distribution). With those times, each stage's recipes are packed into jobs by time (vinca-gha `--timings`, each recipe's average over the distributions), so that no single job holds up its stage; until a platform has times, its jobs are cut by count as before. - Those workflows build the packages and upload them to the distribution's channel on the servers `upload_to` in `distro.yaml` lists (prefix.dev and/or anaconda.org, the same channel name on each; packages already there are skipped). `read_from` says where the builds look up what's already published. + - A new push to a build branch cancels its run in progress: the new run skips what the old one uploaded. Re-run failed jobs only in a build branch's newest run, since re-running an older one cancels the newer run. - **Repository variables:** - `ROBOSTACK_UPLOAD_CHANNEL`: upload only to this prefix.dev channel instead (for example a test channel), or `none` to build without uploading. Use the canonical reference: `/` for a channel that isn't the namespace's primary one (e.g. `tobias-fischer/robostack-distro-test`). - Upload credentials: diff --git a/tools/robostack.py b/tools/robostack.py index 796b6230a..ddfc1c4aa 100644 --- a/tools/robostack.py +++ b/tools/robostack.py @@ -466,12 +466,12 @@ def generate_gha(distro: str, args: list[str]) -> int: lines = wf.read_text().splitlines() # all build branches share .github/workflows/build.yaml, which GitHub lists as one # workflow: run-name tells the runs apart - # one run per distribution and platform at a time: an older run can't upload - # alongside a newer one; a newer pending run replaces older pending ones (not - # cancel-in-progress: re-running a failed job of an older run would cancel the - # newer run) + # one run per distribution and platform at a time: a newer run (the latest main's + # recipes and workflow) cancels the older one, and skips what that one uploaded + # already. Re-run failed jobs only in the newest run: re-running an older one + # would cancel the newer run. lines = [f"name: build\nrun-name: {distro} {ns.platform}\n" - f"concurrency:\n group: build-{distro}-{ns.platform}\n cancel-in-progress: false" + f"concurrency:\n group: build-{distro}-{ns.platform}\n cancel-in-progress: true" if l.startswith("name: ") else l for l in lines] # vinca-gha passes secrets.ANACONDA_API_TOKEN to the build jobs, for the anaconda.org # upload (prefix.dev uses trusted publishing, id-token: write): each distribution