Skip to content

Make release workflow reruns idempotent when release already exists#246

Merged
erikdarlingdata merged 1 commit intodevfrom
fix/release-workflow-idempotent-rerun
Apr 21, 2026
Merged

Make release workflow reruns idempotent when release already exists#246
erikdarlingdata merged 1 commit intodevfrom
fix/release-workflow-idempotent-rerun

Conversation

@erikdarlingdata
Copy link
Copy Markdown
Owner

Summary

Only `Create release` retains the `EXISTS == 'false'` guard. Every downstream step (Setup .NET, Build, Publish, Sign, Velopack, Package/upload) always runs. `gh release upload --clobber` on the final step safely overwrites existing assets on rerun.

Why

Happened during v1.7.0: first run timed out on SignPath approval after creating the release + tag, rerun skipped all work because v1.7.0 already existed. The only unblock was `gh release delete v1.7.0 --cleanup-tag` then rerun. After this change, a rerun after signing failure re-does the build + sign + upload and repopulates the empty release.

Test plan

  • Validate on the next dev→main release cycle — we're intentionally not reproducing the failure to test (rerunning this workflow on an already-shipped release would re-upload identical artifacts under `--clobber`, which is safe but noisy).

🤖 Generated with Claude Code

If signing (or any step after "Create release") fails, the release + tag
are created but empty. Previously every downstream step was guarded by
EXISTS == 'false', so reruns short-circuited to a no-op and the only fix
was to delete the empty release and tag before rerunning.

Now only "Create release" itself is guarded; Setup .NET, Build and test,
Publish, Sign, Velopack, and Package/upload always run. The final
gh release upload uses --clobber, so rerunning against an existing
release safely overwrites its assets.

Happened during v1.7.0: first attempt timed out on SignPath approval,
the rerun skipped all work because v1.7.0 already existed, and manual
release+tag deletion was needed to unstick it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Owner Author

@erikdarlingdata erikdarlingdata left a comment

Choose a reason for hiding this comment

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

What it does
Drops the steps.check.outputs.EXISTS == 'false' gate from every step after Create release (Setup .NET → Build/test → Publish → signing chain → Velopack → Package/upload). Only Create release itself keeps the guard. Reruns after the release+tag are created now re-execute build/sign/upload instead of no-opping.

What's good

  • Base branch is dev. Correct.
  • gh release upload ... --clobber at release.yml:184 makes the zip + SHA256SUMS upload safe to repeat.
  • vpk upload ... --merge at release.yml:187 handles the Velopack side.
  • Scope is minimal — no behavior change on the happy path.

Needs attention

  • release.yml:78-84 — actions/upload-artifact@v4 rejects duplicate artifact names within a run. If the user hits "Re-run failed jobs" (same run, attempt 2) after a SignPath timeout — which is exactly the scenario described in the PR body — the App-unsigned artifact from attempt 1 will collide. Adding overwrite: true closes this. A brand-new workflow run is unaffected, but the maintainer will likely reach for "Re-run failed jobs" first. Inline comment left.
  • release.yml:117-120 — vpk download + vpk pack for the same $VERSION on a rerun: if a prior attempt already uploaded Velopack assets, vpk download will pull them back and treat v$VERSION as "previous" when packing v$VERSION. Not the failure mode this PR targets (sign-timeout halts before Velopack runs), so not blocking. Worth a quick sanity check that vpk tolerates that case before relying on rerun for failures past the Velopack step.
  • Test plan is "validate on next release cycle" — fine, given the alternative (forcing a failure) would re-upload artifacts on a shipped release.

No C#/XAML changes, so Avalonia/brush/MVVM/test-coverage checks are N/A.


Generated by Claude Code

Comment on lines 78 to 84
- name: Upload Windows build for signing
if: steps.check.outputs.EXISTS == 'false' && steps.signing.outputs.ENABLED == 'true'
if: steps.signing.outputs.ENABLED == 'true'
id: upload-unsigned
uses: actions/upload-artifact@v4
with:
name: App-unsigned
path: publish/win-x64/
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

actions/upload-artifact@v4 requires unique artifact names within a workflow run. The target failure scenario here is "SignPath times out on attempt 1, user reruns" — if that rerun is done via GitHub's "Re-run failed jobs" (same run, attempt 2), the prior attempt's App-unsigned artifact persists and this step will fail with an artifact with this name already exists. Consider adding overwrite: true here to make the rerun path fully idempotent. A fresh workflow_dispatch run is unaffected, but "Re-run failed jobs" is the more likely maintainer action.


Generated by Claude Code

@erikdarlingdata erikdarlingdata merged commit d37ecac into dev Apr 21, 2026
2 checks passed
@erikdarlingdata erikdarlingdata deleted the fix/release-workflow-idempotent-rerun branch April 21, 2026 01:05
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