Skip to content

Skip rebuilds whose inputs have not changed - #9

Merged
excid3 merged 2 commits into
mainfrom
skip-unchanged-builds
Sep 9, 2026
Merged

excid3 merged 2 commits into
mainfrom
skip-unchanged-builds

Conversation

@excid3

@excid3 excid3 commented Sep 9, 2026

Copy link
Copy Markdown
Member

Stacked on #7 (same create-release and publish-release code); it will retarget to main when #7 merges.

Problem

Today's repeated full rebuilds had two causes.

  1. Release New Versions rebuilt versions that already had releases. It decided which versions lack a release from gh release list --limit 100. The repository has 277 releases, so every version whose releases fell outside the newest 100 was reported as missing and rebuilt. Each rebuild created new releases, pushing other versions out of the window for the next scheduled or push-triggered run. The push-triggered run at 13:49 UTC listed 1.8.7-p374 as missing while its floating release existed.
  2. A dispatched release always built, even when nothing that affects the output had changed.

Change

  • release-new.yml pages through every published release instead of the newest 100.
  • bin/build-fingerprint VERSION digests everything in the repository that determines a version's build: the version's recipe, its effective series settings (same merge as package.rb), every dependency's version and checksum (not URLs or mirrors), the targets, libexec/package.rb and .github/workflows/build.yml. It is stable across runs, differs per version, and ignores mirror-only edits.
  • release.yml gains a plan job that runs first. It computes the fingerprint, determines the next revision number (moved here from create-release), and reads the fingerprint recorded in the newest revision release's notes. If they match and the floating release exists, the run ends there (about 30 seconds on one small runner). Otherwise it builds as before. A new force input rebuilds regardless, for changes the fingerprint cannot see: what a pinned container resolves to, the Rust toolchain, the bootstrap Ruby.
  • create-release writes **Build fingerprint:** v1-… into the revision release notes, which PR Update the floating release in place instead of recreating it #7 also copies to the floating release.
  • When a run is skipped and latest was requested, the existing floating release is marked latest. notify sends nothing for a skipped run.

First run after merging

Existing revision releases carry no fingerprint, so the first dispatch of each version after this merges will build once and record it. From then on unchanged versions skip. If that one-time rebuild of every version is unwanted, the fingerprint can be backfilled into each newest revision release's notes instead; happy to do that as a follow-up.

Verification

  • bin/build-fingerprint returns the same value on repeated runs, a different one per version, exits non-zero for an unknown version, and does not change when only a dependency's mirror is edited.
  • Workflow YAML parses, the extracted step scripts pass bash -n, and rubocop is clean on the new script. The workflow itself can only be exercised by dispatching a release after merge.

https://claude.ai/code/session_01KeNcsk8V24YRXGfD2HwDZY

Two things caused today's repeated full rebuilds. Release New Versions
decided which versions lack a release from `gh release list --limit
100`; with more than 100 releases in the repository every version whose
releases fell outside that window was reported missing and rebuilt, and
each rebuild pushed other versions out of the window for the next run.
It now pages through every published release.

Independently, a dispatched release always built, whether or not
anything relevant had changed. bin/build-fingerprint digests everything
in the repository that determines a version's output: its recipe, the
effective series settings, dependency versions and checksums, the
targets, package.rb and build.yml. Each revision release records the
fingerprint in its notes, and a new plan job compares it to the newest
revision's before building: a match with the floating release in place
ends the run after one small job. A `force` input rebuilds regardless,
for changes the fingerprint cannot see such as a container pin's
contents or the Rust toolchain. The revision number is now determined
in plan and handed to the later jobs.

Claude-Session: https://claude.ai/code/session_01KeNcsk8V24YRXGfD2HwDZY
@excid3
excid3 changed the base branch from floating-release-in-place to main September 9, 2026 19:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant