Gate build + release on the version bump #488

Closed
opened 2026-09-07 10:34:10 +02:00 by johnsturgeon · 0 comments
Owner

Summary

Make releases deliberate: land 1..N PRs, then when I run uv version --bump (in a PR that lands), that merge triggers a single image build and a single Forgejo release. Merges that don't change the version produce no image and no release. The release notes cover every PR landed since the previous release, not just the triggering PR.

Current behavior

  • .forgejo/workflows/build-image.yml builds and pushes on every push to main (:latest, :<version>, :<sha>). Because the version only moves on uv version --bump, back-to-back merges re-push :<version> onto newer SHAs — the version tag drifts off the commit it was first cut at.
  • .forgejo/workflows/release-on-merge.yml cuts a release/tag on every merged PR, with notes drawn from that one PR. It already no-ops when a release for the current version exists (the guard that catches unbumped PRs), so it half-does this already.

Desired behavior

  • Version bump is the trigger. A merge whose pyproject.toml version differs from the latest release → build image + cut release. A merge with no version change → nothing (no build, no release, no tag).
  • Notes aggregate the whole span. The release body lists every PR merged since the previous release — the commit range (previous release's target commit .. this merge commit] — each PR's title/link plus the issues it closed (reuse the existing close/fix/resolve #n keyword scan per PR).
  • :<version> is pushed once, at the bump commit, so version ↔ image tag ↔ release tag stay a single identifier for a given landing.

Implementation sketch

  • Detect a bump by comparing the version at MERGE_SHA against the latest existing release tag — release-on-merge.yml already fetches both; extend that guard to also gate the build.
  • Enumerate the PRs in range via the pulls API (or by parsing merge-commit messages for #N) between the previous release's target commit and MERGE_SHA.
  • build-image.yml needs the same gate — either detect the bump itself, or trigger off the created release/tag instead of a raw push to main.

Open questions

  • On non-bump merges, still build :latest/:<sha> for testing, or build nothing at all until a bump?
    Answer: build nothing until a bump, I don't want any automated build / deploy / on new release stuff firing until I intentionally release a new version
  • Chain the workflows (release creates the tag → build triggers on tag) vs. each workflow independently detecting the bump?
    Answer: version bump is the trigger -> tag -> create the release -> build the release / tag

The per-PR version bump requirement stays as-is; only the build/release trigger and the notes assembly change.

## Summary Make releases deliberate: land 1..N PRs, then when I run `uv version --bump` (in a PR that lands), *that* merge triggers a single image build and a single Forgejo release. Merges that don't change the version produce no image and no release. The release notes cover **every PR landed since the previous release**, not just the triggering PR. ## Current behavior - `.forgejo/workflows/build-image.yml` builds and pushes on **every** push to `main` (`:latest`, `:<version>`, `:<sha>`). Because the version only moves on `uv version --bump`, back-to-back merges re-push `:<version>` onto newer SHAs — the version tag drifts off the commit it was first cut at. - `.forgejo/workflows/release-on-merge.yml` cuts a release/tag on **every** merged PR, with notes drawn from that one PR. It already no-ops when a release for the current version exists (the guard that catches unbumped PRs), so it half-does this already. ## Desired behavior - **Version bump is the trigger.** A merge whose `pyproject.toml` version differs from the latest release → build image + cut release. A merge with no version change → nothing (no build, no release, no tag). - **Notes aggregate the whole span.** The release body lists every PR merged since the previous release — the commit range `(previous release's target commit .. this merge commit]` — each PR's title/link plus the issues it closed (reuse the existing `close/fix/resolve #n` keyword scan per PR). - **`:<version>` is pushed once**, at the bump commit, so version ↔ image tag ↔ release tag stay a single identifier for a given landing. ## Implementation sketch - Detect a bump by comparing the version at `MERGE_SHA` against the latest existing release tag — `release-on-merge.yml` already fetches both; extend that guard to also gate the build. - Enumerate the PRs in range via the pulls API (or by parsing merge-commit messages for `#N`) between the previous release's target commit and `MERGE_SHA`. - `build-image.yml` needs the same gate — either detect the bump itself, or trigger off the created release/tag instead of a raw push to `main`. ## Open questions - On non-bump merges, still build `:latest`/`:<sha>` for testing, or build nothing at all until a bump? Answer: build nothing until a bump, I don't want any automated build / deploy / on new release stuff firing until I intentionally release a new version - Chain the workflows (release creates the tag → build triggers on tag) vs. each workflow independently detecting the bump? Answer: version bump is the trigger -> tag -> create the release -> build the release / tag The per-PR version bump requirement stays as-is; only the build/release trigger and the notes assembly change.
johnsturgeon changed title from Gate build + release on the version bump, and aggregate all PRs since the last release to Gate build + release on the version bump 2026-09-07 11:03:57 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
johnsturgeon/tgfp-web#488
No description provided.