Skip to content

ci: avoid duplicate Docker builds when a labeled PR is merged - #6

Merged
veniplex merged 1 commit into
mainfrom
ci/dedupe-release-builds
Jul 13, 2026
Merged

veniplex merged 1 commit into
mainfrom
ci/dedupe-release-builds

Conversation

@veniplex

Copy link
Copy Markdown
Owner

Summary

When a PR carries the release-candidate label, release-candidate.yml builds the Docker image (validation only, no push). If you then merge that PR immediately — while the validation build is still running — the post-merge pipeline (version-bump.ymlrelease.yml) builds the image again, so two Docker builds run at once. This dedupes that.

Two changes:

  1. release-candidate.yml gets a per-PR concurrency group with cancel-in-progress: true, so pushing new commits to a labeled PR cancels the previous (now-stale) validation build instead of stacking builds.
  2. version-bump.yml cancels, as its very first step, any release-candidate.yml run still in flight for the merged PR's branch. Once the PR is merged, that validation build is redundant: the release.yml run dispatched at the end of version-bump.yml validates and publishes the real image anyway.

Why not "reuse the PR-built image instead of rebuilding after merge"?

This was the other option considered, but the PR-built image and the release image are not interchangeable:

  • Different content: the release image is built from the chore(release): vX.Y.Z commit, which has the bumped package.json. APP_VERSION (shown in the app's sidebar footer) is baked in from package.json at build time — so the PR-built image would report the old version.
  • Different arch: the validation build is single-arch (amd64); the release build is multi-arch (amd64 + arm64).

So the PR build can't stand in for the release. Cancelling the redundant validation (rather than reusing it) is the fix that fits the current "bump the version after merge" flow.

Note on the two post-merge release.yml runs

Merging still produces two release.yml runs — :main/:edge from the merge commit, and the semver tags (:X.Y.Z, :latest) from the dispatched tag build. These are intentional (edge tracks main, latest tracks the release) and both use cache-to/from: type=gha, so the second run is mostly cache hits rather than a full second build. Left as-is; happy to collapse them too if you'd prefer only the semver build on a release merge.

Test plan

  • YAML validated for both workflow files.
  • Label a PR, push a commit while its validation build runs → confirm the older validation build is cancelled (concurrency).
  • Merge a labeled PR while its validation build is running → confirm version-bump.yml's first step cancels it, and only the post-merge release.yml runs build/publish the image.

Generated by Claude Code

Two changes prevent the pre-merge validation build from overlapping with
the post-merge publish build:

- release-candidate.yml gets a per-PR concurrency group with
  cancel-in-progress, so pushing new commits to a labeled PR cancels the
  previous (now-stale) validation build instead of stacking builds.
- version-bump.yml, as its first step, cancels any release-candidate
  validation run still in flight for the merged PR's branch. When a
  labeled PR is merged immediately, the validation build is redundant —
  the release.yml run dispatched at the end of version-bump.yml validates
  and publishes the real (version-bumped, multi-arch) image anyway.

Not reusing the PR-built image as the release is deliberate: the release
image is built from the chore(release) commit (bumped package.json, so a
different baked-in APP_VERSION) and is multi-arch, whereas the validation
build is single-arch and pre-bump — the artifacts are not interchangeable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ST7p7inT3agkLEp8qbPSC6
@veniplex
veniplex merged commit d6bce2c into main Jul 13, 2026
1 check passed
@veniplex
veniplex deleted the ci/dedupe-release-builds branch July 13, 2026 16:05
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.

2 participants