From 24b8d52f3c77dff0af14821bb80d506073f1cdfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sat, 16 May 2026 20:27:22 +0200 Subject: [PATCH] ci(docker): fire the release build once per tag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Build & Publish Docker Image workflow fired twice on every release. The squash-merge to `main` and the `v*` tag push landed within a second of each other and each kicked off its own run against the same SHA. Both runs finished green and pushed overlapping tag sets — the main-branch run added the `latest` alias, the tag run added the semver tags — but the duplication doubled GHCR CI minutes per release with no operational benefit. Drop the `push.branches: [main]` trigger so only `v*` tag pushes fire the build on a release. Tighten the `latest` raw-tag rule in docker/metadata-action so it enables on stable release tags (`refs/tags/v*` without a pre-release suffix) rather than the `is_default_branch` condition (false on tag refs). Net result: a release tag pushes a single multi-arch image carrying both the semver tags and the `latest` alias in one run, halving the CI minutes per release. PR + workflow_dispatch triggers are preserved so pre-merge validation and manual reruns still build. --- .github/workflows/docker-publish.yml | 29 ++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 238ccd896..708ab8122 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -1,8 +1,20 @@ name: Build & Publish Docker Image +# v1.4.34 IW-A — release pipeline fires on tag pushes only. Earlier +# releases triggered the workflow twice on each cut: the squash-merge +# to `main` and the corresponding `v*` tag push landed within a second +# of each other and each kicked off its own build. Both runs ended +# green and produced the same image at the same SHA with overlapping +# tag sets (the main run added `latest`, the tag run added the +# semver tags), but the duplication doubled GHCR CI minutes for +# every release. Dropping `push.branches: [main]` collapses the +# pipeline to a single run per release tag. The `latest` rule in +# the metadata-action (`type=raw,value=latest,...`) now keys on +# the v* tag presence so each release still refreshes the `latest` +# alias in the same run. PR + workflow_dispatch triggers stay so +# the image still builds on PR validation and manual reruns. on: push: - branches: [main] tags: ["v*"] pull_request: branches: [main] @@ -13,8 +25,8 @@ env: IMAGE_NAME: ${{ github.repository }} # Cancel in-progress runs when a new commit is pushed to the same ref. -# main + a v* tag at the same SHA are different refs, so the per-ref -# gha cache scope below keeps them from contending on cache writes. +# Different ref types (tag vs PR head) don't share a group, so a tag +# build and a concurrent PR build won't cancel each other. concurrency: group: docker-publish-${{ github.ref }} cancel-in-progress: true @@ -264,7 +276,16 @@ jobs: type=semver,pattern={{major}}.{{minor}} type=match,pattern=v(.+),group=1 type=ref,event=tag - type=raw,value=latest,enable={{is_default_branch}} + # v1.4.34 IW-A — release pipeline fires on `v*` tag pushes + # only (the `push.branches: [main]` trigger was dropped to + # eliminate the per-release double-build). `is_default_branch` + # is false for tag refs, so the prior condition stopped + # refreshing the `latest` alias once main pushes no longer + # trigger the workflow. Enable on every release tag that + # does not carry a pre-release suffix (`-rc.1`, `-beta.2`, + # etc.) so each stable release rotates the `latest` alias + # while pre-release tags stay off it. + type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') && !contains(github.ref_name, '-') }} type=sha,prefix=sha-,format=short labels: | org.opencontainers.image.title=HealthLog