From eb9b4cec542d9bd9c793b8ba30c5c155a8a749b8 Mon Sep 17 00:00:00 2001 From: Paco Cartones <253313177+pacocartones@users.noreply.github.com> Date: Tue, 25 Aug 2026 18:12:02 +0200 Subject: [PATCH] fix(ci): skip stale release Docker publishes (#11527) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Validated in a combined 10-PR batch worktree off release/v3.8.51 tip. Fixes #11523. - Focused test: tests/unit/build/docker-next-channel-8576.test.ts — 7/7 pass - typecheck:core, file-size, changelog-integrity, complexity, cognitive-complexity gates — all OK - Full-repo lint: 503 pre-existing problems confirmed identical on the pure release/v3.8.51 tip — unrelated to this diff ⚠️ base-red inherited: #11449 Thanks for treating Docker publishes from non-default frozen release branches as an expected no-op. --- .github/workflows/docker-publish.yml | 10 ++++++++ .../fixes/11523-stale-release-docker-skip.md | 1 + scripts/ci/resolve-docker-publish-version.sh | 6 ++--- .../build/docker-next-channel-8576.test.ts | 23 ++++++++++--------- 4 files changed, 26 insertions(+), 14 deletions(-) create mode 100644 changelog.d/fixes/11523-stale-release-docker-skip.md diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 3b04a20c8b..f112fe7c54 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -68,6 +68,16 @@ jobs: "$EVENT_NAME" "$REF_TYPE" "$REF_NAME" "$INPUT_VERSION" "$DEFAULT_BRANCH") echo "version=$VERSION" >> "$GITHUB_OUTPUT" + # Frozen release branches keep receiving coordination commits after the + # next cycle becomes the default branch. They must not overwrite :next, + # but that expected no-op is not a workflow failure. + if [ "$VERSION" = "skip" ]; then + echo "promote_latest=false" >> "$GITHUB_OUTPUT" + echo "skip=true" >> "$GITHUB_OUTPUT" + echo "Skipping Docker publish from non-default release branch: $REF_NAME" + exit 0 + fi + # 2) Decide whether to promote :latest. Floating channels are never # eligible, and the helper independently fails closed for non-semver. PROMOTE="false" diff --git a/changelog.d/fixes/11523-stale-release-docker-skip.md b/changelog.d/fixes/11523-stale-release-docker-skip.md new file mode 100644 index 0000000000..0a84b74fed --- /dev/null +++ b/changelog.d/fixes/11523-stale-release-docker-skip.md @@ -0,0 +1 @@ +- Treat Docker publishing from a non-default release branch as an expected skip instead of a failed workflow, while preserving the guard that prevents it from overwriting the `next` channel. diff --git a/scripts/ci/resolve-docker-publish-version.sh b/scripts/ci/resolve-docker-publish-version.sh index a9844e76a7..1701a16983 100644 --- a/scripts/ci/resolve-docker-publish-version.sh +++ b/scripts/ci/resolve-docker-publish-version.sh @@ -32,10 +32,10 @@ case "$EVENT_NAME" in ;; release/v*) if [ -z "$DEFAULT_BRANCH" ] || [ "$REF_NAME" != "$DEFAULT_BRANCH" ]; then - echo "Refusing to publish next from non-default release branch: $REF_NAME" >&2 - exit 1 + VERSION="skip" + else + VERSION="next" fi - VERSION="next" ;; *) echo "Unsupported Docker publish branch: $REF_NAME" >&2 diff --git a/tests/unit/build/docker-next-channel-8576.test.ts b/tests/unit/build/docker-next-channel-8576.test.ts index 4d7a6d6b9b..be97b334d9 100644 --- a/tests/unit/build/docker-next-channel-8576.test.ts +++ b/tests/unit/build/docker-next-channel-8576.test.ts @@ -72,18 +72,19 @@ test("the current default release branch resolves to next", () => { ); }); -test("a stale release branch cannot overwrite next", () => { - assert.throws( - () => - resolveVersion( - "push", - "branch", - "release/v3.8.49", - "", - "release/v3.8.50", - ), - /Refusing to publish next from non-default release branch/, +test("a stale release branch skips without overwriting next", () => { + assert.equal( + resolveVersion( + "push", + "branch", + "release/v3.8.49", + "", + "release/v3.8.50", + ), + "skip", ); + assert.match(WORKFLOW, /\[ "\$VERSION" = "skip" \]/); + assert.match(WORKFLOW, /echo "skip=true" >> "\$GITHUB_OUTPUT"/); }); test("existing main, tag, dispatch, and release behavior is preserved", () => {