Skip to content

ci(docker): only upload standalone binaries when a release will use them - #223

Merged
shockalotti merged 1 commit into
mainfrom
fix/standalone-upload-gate
Nov 4, 2026
Merged

shockalotti merged 1 commit into
mainfrom
fix/standalone-upload-gate

Conversation

@shockalotti

Copy link
Copy Markdown
Contributor

Follow-up to #112, which was merged before this could be added.

Problem

Since #112 the build job exports and packages the standalone binaries on every run, then uploads them as an artifact. Only the release job downloads that artifact, and it runs on a version tag or a dry-run dispatch. So every PR and every branch push stores an archive nobody consumes.

Change

Gate the upload step only:

if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && inputs.dry_run)

Export and packaging stay ungated on purpose. They are what proves the standalone stage still builds. Gating them would move that check to release time, which is the trap of a gate nobody exercises until it matters.

The condition is not a bare tag check

The obvious startsWith(github.ref, 'refs/tags/v') would break the dry_run rehearsal, because the release job also runs on a dry-run dispatch and its first step is download-artifact. A bare tag check would leave it with nothing to download, killing the one path that exists to prove the release sequence works without cutting a tag. The gate therefore mirrors the release job's condition exactly, which is verified below.

Verification

Parsed from the workflow:

Export standalone binaries:  if=(none)
Package standalone binaries: if=(none)
Upload standalone binaries:  if=startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && inputs.dry_run)
release job if:              if=startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && inputs.dry_run)

On this PR the upload should be skipped while export and packaging still run. After merging I will dispatch dry_run=true against main to prove the opposite case: upload runs, the release job downloads the artifact and rehearses, and it stops before creating a Release.

Since #112 the build job exports and packages the standalone binaries on every
run, then uploads them as an artifact. Only the release job consumes that
artifact, and it runs on a version tag or a dry-run dispatch, so every PR and
branch push currently stores an archive nobody downloads.

Gate just the upload. Export and packaging stay ungated on purpose: they are
what proves the `standalone` stage still builds, and moving that check to
release time is exactly the trap of a gate that cannot fail until it matters.

The condition deliberately mirrors the release job's, including the
workflow_dispatch dry run. A bare `startsWith(github.ref, 'refs/tags/v')` would
make the dry-run rehearsal fail at download-artifact, which is the one path
that exists to prove the release sequence works without cutting a tag.

@pullfrog pullfrog Bot left a comment

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.

✅ No new issues found.

Reviewed changes

  • Gate the standalone artifact upload — adds an if: to the build job's Upload standalone binaries step so standalone-binaries is only uploaded when the release job will download it; export and packaging stay ungated so the standalone stage is still exercised on every PR and branch push.
  • Condition matches the release job exactly — the new step condition is identical to the release job's if: (.github/workflows/docker-publish.yml:291), preserving the workflow_dispatch dry-run rehearsal path that downloads the artifact.
  • Documented rationale — the added comment explains why export/packaging must not be gated and why the condition must stay in sync with release.

The PR's own pull_request run confirms the intended behavior: Export standalone binaries and Package standalone binaries succeeded while Upload standalone binaries was skipped. Only the release job consumes the artifact, so no other consumer is left without it.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash | 𝕏

@shockalotti
shockalotti merged commit 010547e into main Nov 4, 2026
11 checks passed
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.

1 participant