Skip to content
Merged
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
17 changes: 14 additions & 3 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ on:
branches: [main, dev]
tags: ['v*.*.*']
pull_request:
# A rehearsal: build everything and run the release job's packaging and download
# steps, then stop before publishing a GitHub Release. It exists so the release
# path can be executed without cutting a tag, which is otherwise the only way to
# find out whether it still works.
workflow_dispatch:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The trigger inherits concurrency: docker-publish-${{ github.ref }} with cancel-in-progress: true, and a dispatch on main — the usage documented in the PR body — lands in the same group as the merge commit's own main push build. Running the rehearsal right after merging therefore cancels that real :edge publish; a dispatch against a release tag cancels the tag build the same way.

Technical details
# Rehearsal cancels a real publish via shared concurrency group

## Affected sites
- `.github/workflows/docker-publish.yml:26` — new trigger joins an existing ref-keyed concurrency group.
- `.github/workflows/docker-publish.yml:33-35` — `group: docker-publish-${{ github.ref }}`, `cancel-in-progress: true`.

## Required outcome
- A dry-run dispatch must not cancel a concurrent push build for the same ref.

## Suggested approach
- Add the event (or the dry-run flag) to the group, e.g. `docker-publish-${{ github.ref }}-${{ github.event_name }}`, or set `cancel-in-progress` false for dispatch.

inputs:
dry_run:
description: 'Exercise the release job without creating a GitHub Release'
type: boolean
default: true

concurrency:
group: docker-publish-${{ github.ref }}
Expand Down Expand Up @@ -87,7 +97,7 @@ jobs:
with:
context: .
platforms: ${{ env.BUILD_PLATFORMS }}
push: ${{ github.event_name != 'pull_request' }}
push: ${{ github.event_name == 'push' }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On a workflow_dispatch, push is false, but arm64-smoke still takes its "pull the image this build just published" path because every gate there tests github.event_name != 'pull_request' (lines 168, 180, 187), which is true for a dispatch. With nothing pushed, needs.build.outputs.digest is empty — buildx only emits containerimage.digest when a result is exported — so the step fails its explicit empty-digest check, and a non-empty digest would still docker pull an image that was never pushed. A dry run therefore always ends red, which is the opposite of the green rehearsal this PR adds.

Technical details
# Dry-run dispatch fails arm64-smoke

## Affected sites
- `.github/workflows/docker-publish.yml:100` — `push: ${{ github.event_name == 'push' }}` leaves a dispatch with no pushed image.
- `.github/workflows/docker-publish.yml:168` — `if: github.event_name != 'pull_request'` selects the pull path on dispatch.
- `.github/workflows/docker-publish.yml:173-176` — explicit `::error::build produced no digest` exit.
- `.github/workflows/docker-publish.yml:187-191` — `Resolve the image under test` chooses `calnode-pr:arm64` only for `pull_request`.

## Required outcome
- A `workflow_dispatch` run must not depend on an image this run pushed. Either skip `arm64-smoke` on dispatch, or let dispatch take the native-build path.
- If dispatch is routed through the native path, `Resolve the image under test` must select the locally built `calnode-pr:arm64` for dispatch too, not just `pull_request`.

tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
Expand Down Expand Up @@ -266,8 +276,8 @@ jobs:
run: docker logs calnode 2>&1 | tail -30

release:
# Only on a version tag, and only once the image built + pushed.
if: startsWith(github.ref, 'refs/tags/v')
# On a version tag, and on a dry-run dispatch, where it stops before publishing.
if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && inputs.dry_run)
needs: build
runs-on: ubuntu-latest
permissions:
Expand Down Expand Up @@ -303,6 +313,7 @@ jobs:
# Preinstalled gh CLI + GITHUB_TOKEN (no third-party action — keeps the
# supply-chain surface small).
- name: Create GitHub Release
if: startsWith(github.ref, 'refs/tags/v')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This guard checks only the ref, and a dispatch can target a tag (ref accepts a branch or tag name). On a tag ref startsWith(github.ref, 'refs/tags/v') is true, so gh release create runs even with dry_run: true, contradicting the input description, and would publish a release whose image this run never pushed. Require github.event_name == 'push' (or negate inputs.dry_run) in this condition.

env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
Expand Down
Loading