Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/release-candidate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ on:
pull_request:
types: [labeled, synchronize]

# One validation build per PR at a time: a new push cancels the previous
# (now-stale) build for the same PR. version-bump.yml additionally cancels
# whatever is still running here the moment the PR is merged, so a labeled
# PR merged immediately doesn't build the image both here and post-merge.
concurrency:
group: release-candidate-${{ github.event.pull_request.number }}
cancel-in-progress: true

jobs:
docker-build:
if: contains(github.event.pull_request.labels.*.name, 'release-candidate')
Expand Down
19 changes: 19 additions & 0 deletions .github/workflows/version-bump.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,25 @@ jobs:
!startsWith(github.event.pull_request.title, 'chore(release):')
runs-on: ubuntu-latest
steps:
- name: Cancel now-redundant release-candidate build
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
HEAD_REF: ${{ github.event.pull_request.head.ref }}
run: |
# The pre-merge Docker validation (release-candidate.yml) is moot
# once this PR is merged: the build dispatched at the end of this
# job validates AND publishes the real (version-bumped, multi-arch)
# image. Cancel any validation run still in flight for this branch
# so a labeled PR merged immediately doesn't build the image twice.
ids=$(gh run list --repo "$REPO" --workflow=release-candidate.yml \
--branch "$HEAD_REF" --json databaseId,status \
--jq '.[] | select(.status=="in_progress" or .status=="queued") | .databaseId' || true)
for id in $ids; do
echo "Cancelling redundant release-candidate run $id"
gh run cancel "$id" --repo "$REPO" || true
done

- uses: actions/checkout@v4
with:
ref: main
Expand Down
9 changes: 9 additions & 0 deletions docs/releasing.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@ GitHub Actions, gated behind a label so releases are a deliberate choice.
the merge itself, and the versioned tags (including `:latest`) follow
once `version-bump.yml` tags and dispatches the release build.

**No duplicate builds on merge.** The pre-merge validation build
(`release-candidate.yml`) only builds — it never publishes. If you merge a
labeled PR while that validation build is still running, `version-bump.yml`
cancels it as its first step, since the post-merge `release.yml` run
validates and publishes the real image anyway. The two post-merge
`release.yml` runs (`:edge` from the merge, semver from the tag) share the
GitHub Actions layer cache, so the second is mostly cache hits rather than
a full second build.

4. **Update the deployment** (e.g. Portainer):
- If the stack uses `:latest` (default), re-pull the image and
recreate the container ("Re-pull image and redeploy" in Portainer).
Expand Down
Loading