ci: skip jobs when their package version is already published #41

Merged
marfrit merged 2 commits from claude-noether/marfrit-packages:claude-noether/rebuild-guard-2026-05-20 into main 2026-05-20 10:05:40 +00:00
Contributor

Summary

CI currently rebuilds all 14 packages on every push, even when only one recipe changed. With the rate of pushes lately (the user said "wir sind aktiv den state of the art zu verändern"), a lot of runner-time goes into rebuilding e.g. distcc-avahi, which hasn't moved in weeks.

This PR adds a per-job guard:

  1. .gitea/scripts/check-already-published.sh — takes a recipe dir (arch/<n> or debian/<n>), reads PKGBUILD (or build-deb.sh + control), resolves the expected pool URL on packages.reauktion.de, and prints skip=1 or skip=0.
  2. build.yml — every job gets a skip if already published step right after actions/checkout@v4. Every subsequent step (bootstrap, import-key, deploy-key, makepkg, sign, repo-update, publish) gets if: steps.skip-check.outputs.skip != '1'. The wipe secrets step keeps its if: always().

Verified

Live-tested the helper against all 14 recipes against https://packages.reauktion.de/:

Recipe Verdict
arch/distcc-avahi skip=1
arch/lmcp skip=1
arch/claude-his-agent skip=1
arch/ffmpeg-v4l2-request-fourier skip=1
arch/firefox-fourier skip=0 (pkgrel=7 missing — repo has 4,5,8,16)
arch/chromium-fourier skip=0 (not in repo)
arch/qt6-base-fourier skip=0 (1:6.11.1-1 in repo, recipe is -2)
arch/linux-ampere-fourier skip=1
arch/mesa-panvk-bifrost skip=1
arch/mpv-fourier skip=1
arch/libva-v4l2-request-fourier skip=1
debian/lmcp skip=1
debian/claude-his-agent skip=1
debian/ffmpeg-v4l2-request-fourier skip=0
debian/libva-v4l2-request-fourier skip=0
debian/mpv-fourier skip=0
debian/daedalus-v4l2 skip=0
debian/daedalus-v4l2-dkms skip=0

Edge cases handled

  • Arch epoch= (qt6-base-fourier, chromium-fourier, ffmpeg-v4l2-request-fourier) — kept in the pool filename per the live repo's actual layout.
  • Arch pkgname=() arrays (linux-ampere-fourier, qt6-base-fourier) — first name used; split packages share one build so one missing forces all.
  • Arch pkgver=${_pkgver/-/} shell expansion (qt6-base-fourier) — PKGBUILD is sourced in a sandboxed bash subshell so expansions resolve naturally.
  • Debian epoch stripped from pool filename (verified against actual ffmpeg-v4l2-request-fourier_8.1+rfourier+gb57fbbe-4_arm64.deb).
  • Debian PKGVER=2:${FFMPEG_VERSION}+rfourier+gb57fbbe (mpv, ffmpeg) — top-level VAR=value lines are scanned with an awk guard that rejects command-subst ($(...)) and embedded-command (DESTDIR=... meson ...) lines, so HEREDOC-quoted KERNELVER=\$(uname -r) in daedalus-v4l2-dkms doesn't poison the parse.

Implementation notes

  • YAML patches are text-based (no PyYAML round-trip) so comments and blank lines survive. Net diff: 190 lines added, 0 removed.
  • If anything ever goes wrong with the helper, it errs on the side of skip=0 (build). The guard can only suppress builds, never publish stale binaries.
  • The helper takes ~3-5s per call (one or three HEAD requests). Negligible vs a 30-60min Mesa build.

Two commits

  1. ci: add check-already-published helper script
  2. ci: skip jobs when package already published
## Summary CI currently rebuilds all 14 packages on every push, even when only one recipe changed. With the rate of pushes lately (the user said *"wir sind aktiv den state of the art zu verändern"*), a lot of runner-time goes into rebuilding e.g. `distcc-avahi`, which hasn't moved in weeks. This PR adds a per-job guard: 1. **`.gitea/scripts/check-already-published.sh`** — takes a recipe dir (`arch/<n>` or `debian/<n>`), reads `PKGBUILD` (or `build-deb.sh` + `control`), resolves the expected pool URL on `packages.reauktion.de`, and prints `skip=1` or `skip=0`. 2. **`build.yml`** — every job gets a `skip if already published` step right after `actions/checkout@v4`. Every subsequent step (bootstrap, import-key, deploy-key, makepkg, sign, repo-update, publish) gets `if: steps.skip-check.outputs.skip != '1'`. The `wipe secrets` step keeps its `if: always()`. ## Verified Live-tested the helper against all 14 recipes against `https://packages.reauktion.de/`: | Recipe | Verdict | |---|---| | arch/distcc-avahi | skip=1 | | arch/lmcp | skip=1 | | arch/claude-his-agent | skip=1 | | arch/ffmpeg-v4l2-request-fourier | skip=1 | | arch/firefox-fourier | skip=0 (pkgrel=7 missing — repo has 4,5,8,16) | | arch/chromium-fourier | skip=0 (not in repo) | | arch/qt6-base-fourier | skip=0 (1:6.11.1-1 in repo, recipe is -2) | | arch/linux-ampere-fourier | skip=1 | | arch/mesa-panvk-bifrost | skip=1 | | arch/mpv-fourier | skip=1 | | arch/libva-v4l2-request-fourier | skip=1 | | debian/lmcp | skip=1 | | debian/claude-his-agent | skip=1 | | debian/ffmpeg-v4l2-request-fourier | skip=0 | | debian/libva-v4l2-request-fourier | skip=0 | | debian/mpv-fourier | skip=0 | | debian/daedalus-v4l2 | skip=0 | | debian/daedalus-v4l2-dkms | skip=0 | ## Edge cases handled - Arch `epoch=` (qt6-base-fourier, chromium-fourier, ffmpeg-v4l2-request-fourier) — kept in the pool filename per the live repo's actual layout. - Arch `pkgname=()` arrays (linux-ampere-fourier, qt6-base-fourier) — first name used; split packages share one build so one missing forces all. - Arch `pkgver=${_pkgver/-/}` shell expansion (qt6-base-fourier) — PKGBUILD is sourced in a sandboxed bash subshell so expansions resolve naturally. - Debian epoch stripped from pool filename (verified against actual `ffmpeg-v4l2-request-fourier_8.1+rfourier+gb57fbbe-4_arm64.deb`). - Debian `PKGVER=2:${FFMPEG_VERSION}+rfourier+gb57fbbe` (mpv, ffmpeg) — top-level `VAR=value` lines are scanned with an awk guard that rejects command-subst (`$(...)`) and embedded-command (`DESTDIR=... meson ...`) lines, so HEREDOC-quoted `KERNELVER=\$(uname -r)` in `daedalus-v4l2-dkms` doesn't poison the parse. ## Implementation notes - YAML patches are text-based (no PyYAML round-trip) so comments and blank lines survive. Net diff: 190 lines added, 0 removed. - If anything ever goes wrong with the helper, it errs on the side of `skip=0` (build). The guard can only suppress builds, never publish stale binaries. - The helper takes ~3-5s per call (one or three `HEAD` requests). Negligible vs a 30-60min Mesa build. ## Two commits 1. `ci: add check-already-published helper script` 2. `ci: skip jobs when package already published`
claude-noether added 2 commits 2026-05-20 09:50:05 +00:00
CI currently rebuilds every recipe on every push. distcc-avahi hasn't
changed in weeks but still burns runner-time. Add a small bash helper
that takes a recipe dir (arch/<n> or debian/<n>), resolves the expected
pool URL on packages.reauktion.de, and prints `skip=1` or `skip=0`.

Live-tested against all 14 recipes. Sources PKGBUILDs in a sandboxed
subshell so epoch=, ${_pkgver/-/}, and pkgname=() arrays resolve
correctly. For debian/*, extracts top-level PKGVER/PKGREL lines with
an awk guard that rejects command-subst and embedded-command
assignments (avoids false-positive matches against HEREDOC-quoted
dkms.conf content).

Wiring into build.yml lands in the next commit.
Wire .gitea/scripts/check-already-published.sh into every job in
build.yml. New step `skip if already published` (id: skip-check) lands
right after actions/checkout@v4 and runs the helper against the job's
recipe-dir. Subsequent steps gain `if: steps.skip-check.outputs.skip
!= '1'`, except `wipe secrets` which keeps its existing
`if: always()`.

Recipe-dir per job is taken from each job's existing `cp -r arch/...`
or `cd debian/...` line — no guessing.

Effect: on push where only e.g. firefox-fourier changed, 13 jobs HEAD
the pool, see 200, and short-circuit; only firefox-fourier rebuilds.
Verified live against packages.reauktion.de — current branch tip
would skip 10/14 jobs.

Patch is text-based (no PyYAML round-trip) so comments and blank
lines stay where they were. Diff is 190 lines added, 0 removed.
marfrit merged commit 20161d231f into main 2026-05-20 10:05:40 +00:00
marfrit deleted branch claude-noether/rebuild-guard-2026-05-20 2026-05-20 10:05:40 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: marfrit/marfrit-packages#41