Skip to content

fix: avoid immutable release races during asset upload#44

Merged
adityathebe merged 1 commit into
mainfrom
fix/semantic-release-draft-upload
May 20, 2026
Merged

fix: avoid immutable release races during asset upload#44
adityathebe merged 1 commit into
mainfrom
fix/semantic-release-draft-upload

Conversation

@adityathebe
Copy link
Copy Markdown
Member

@adityathebe adityathebe commented May 20, 2026

deps failed release was blocking this PR: flanksource/config-db#2227

Release asset uploads were running from parallel matrix jobs.

See: https://github.com/flanksource/deps/actions/runs/26118570624/job/76911704691

image

With immutable GitHub releases, the first matrix job to publish the release locked the asset list, causing later uploads to fail. Switching uploads to draft releases by tag also created multiple draft releases for the same tag. image

Use semantic-release to create one draft release, build all platform assets in one binary job, upload them with gh release upload, then publish the draft after uploads complete.
Follow the same pattern as mission-control.


Summary by CodeRabbit

  • Chores
    • Transitioned to automated semantic-release for consistent version management
    • Enhanced build infrastructure to support multiple platforms and architectures
    • Implemented binary compression optimization for release artifacts
    • Streamlined release workflow with automated asset generation and GitHub publishing

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

Walkthrough

The PR migrates the release pipeline from manual versioning and per-OS build matrices to semantic-release driven automation. The Makefile now defines platform-specific builds with optional compression and archive generation; .releaserc configures semantic-release to determine versions from commits; and the GitHub Actions workflow orchestrates semantic-release version detection, conditional artifact builds via make, and draft-to-published release finalization.

Changes

Semantic-release Release Pipeline Migration

Layer / File(s) Summary
Makefile release build infrastructure
Makefile
Project metadata variables (NAME, DATE, VERSION_TAG), SHA256 hash selection, platform targets for linux/darwin/windows, UPX-based compression for Linux, and a release target that builds binaries, computes SHA256 checksums, and generates zip (Windows) or tar.gz archives.
Semantic-release configuration
.releaserc
Semantic-release branch targeting, commit analyzer mapping feat/fix/docs/perf/refactor/chore to patch releases, MAJOR RELEASE note keyword, and GitHub plugin settings to create draft releases while suppressing success comments.
GitHub Actions release pipeline
.github/workflows/release.yml
Workflow trigger restricted to main, permissions reduced to read-only, Go version updated to 1.26.x. New semantic-release job determines version; conditional binary job runs make release and uploads artifacts to draft GitHub release; conditional publish-release job finalizes the release by setting draft=false.
Build output ignore patterns
.gitignore
Added .bin/ and .release/ directory ignore patterns.

Sequence Diagram

sequenceDiagram
  participant Push as Push to main
  participant SemRel as semantic-release job
  participant Binary as binary job
  participant Publish as publish-release job
  participant GH as GitHub Release API
  
  Push->>SemRel: Trigger workflow
  SemRel->>SemRel: Analyze commits<br/>determine next version
  SemRel->>GH: Create draft release
  SemRel-->>Binary: version & published flag
  Binary->>Binary: make release VERSION=x.y.z
  Binary->>Binary: Build linux/darwin/windows
  Binary->>Binary: Compress (UPX on Linux)
  Binary->>Binary: Generate SHA256 checksums
  Binary->>Binary: Create archives (zip/tar.gz)
  Binary->>GH: Upload artifacts to draft
  Binary-->>Publish: Signal completion
  Publish->>GH: Set draft=false
  GH-->>Push: Release published
Loading

Possibly related PRs

  • flanksource/deps#41: Registry update to consume plugin binaries from GitHub release assets using shared checksum file naming produced by this PR's Makefile release infrastructure.
  • flanksource/deps#43: Concurrent PR that also modifies .github/workflows/release.yml to keep releases as drafts during asset upload and publish them in a separate final job.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: avoid immutable release races during asset upload' directly addresses the core problem solved by this PR: preventing race conditions during parallel asset uploads to GitHub releases by switching to semantic-release with draft releases.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/semantic-release-draft-upload
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch fix/semantic-release-draft-upload

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@adityathebe adityathebe requested a review from moshloop May 20, 2026 11:53
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
.github/workflows/release.yml (2)

25-28: ⚡ Quick win

Consider disabling credential persistence for defense in depth.

The checkout action persists Git credentials by default. While the risk is low in this job, setting persist-credentials: false is a security best practice that prevents potential credential leakage if subsequent steps or actions are compromised.

🛡️ Proposed fix
       - name: Checkout
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
         with:
           fetch-depth: 0
+          persist-credentials: false
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 25 - 28, The Checkout step
currently uses actions/checkout@de0fac2e... and leaves default credential
persistence; update the Checkout step (the step with name "Checkout" and uses:
actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd) to add the input
persist-credentials: false so GitHub credentials are not written to the
workspace after checkout.

44-45: ⚡ Quick win

Add persist-credentials: false here as well.

Same security recommendation as the semantic-release job—disable credential persistence on checkout.

🛡️ Proposed fix
       - name: Checkout
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+        with:
+          persist-credentials: false
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 44 - 45, The Checkout step
currently uses actions/checkout@de0fac2e... but does not disable credential
persistence; update the Checkout job's step (the step with name "Checkout" and
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd) to include
persist-credentials: false so credentials are not persisted to the workspace for
subsequent steps.
.releaserc (1)

5-17: 💤 Low value

All commit types mapped to patch deviates from semantic versioning conventions.

Mapping feat to patch (line 11) is unconventional—semantic versioning typically treats features as minor bumps. This is a valid choice if the project intentionally wants conservative versioning, but contributors familiar with standard semver may expect feat commits to trigger minor releases.

If this is intentional, consider adding a comment in this file or documenting the versioning policy.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.releaserc around lines 5 - 17, The releaseRules mapping currently maps all
commit types (releaseRules) including the 'feat' rule to release: patch; update
the 'feat' rule inside releaseRules to release: minor to align with semver
(change the entry "- { type: feat, release: patch }" to "- { type: feat,
release: minor }"), or if the current conservative mapping is intentional, add a
clear comment above releaseRules explaining that 'feat' is intentionally mapped
to patch and documenting the project's versioning policy so contributors are not
surprised.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Makefile`:
- Around line 98-102: The Makefile recipe for target $(UPX) uses the
non-portable `trash` command for cleanup; replace that with a portable command
such as `rm -rf` to delete the downloaded archive and extracted directory.
Update the recipe under the $(UPX): .bin rule so the last line becomes `rm -rf
upx.tar.xz upx-$(UPX_VERSION)-$(TASK_ARCH)_$(TASK_PLATFORM)` (or an equivalent
safe `rm -rf` invocation) to ensure CI on Linux/Ubuntu succeeds.

---

Nitpick comments:
In @.github/workflows/release.yml:
- Around line 25-28: The Checkout step currently uses
actions/checkout@de0fac2e... and leaves default credential persistence; update
the Checkout step (the step with name "Checkout" and uses:
actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd) to add the input
persist-credentials: false so GitHub credentials are not written to the
workspace after checkout.
- Around line 44-45: The Checkout step currently uses
actions/checkout@de0fac2e... but does not disable credential persistence; update
the Checkout job's step (the step with name "Checkout" and uses:
actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd) to include
persist-credentials: false so credentials are not persisted to the workspace for
subsequent steps.

In @.releaserc:
- Around line 5-17: The releaseRules mapping currently maps all commit types
(releaseRules) including the 'feat' rule to release: patch; update the 'feat'
rule inside releaseRules to release: minor to align with semver (change the
entry "- { type: feat, release: patch }" to "- { type: feat, release: minor }"),
or if the current conservative mapping is intentional, add a clear comment above
releaseRules explaining that 'feat' is intentionally mapped to patch and
documenting the project's versioning policy so contributors are not surprised.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 13e05eb6-6d08-4fa7-a2ca-645baa42db38

📥 Commits

Reviewing files that changed from the base of the PR and between 7d210a0 and 5d0b877.

📒 Files selected for processing (4)
  • .github/workflows/release.yml
  • .gitignore
  • .releaserc
  • Makefile

Comment thread Makefile Outdated
Release asset uploads were running from parallel matrix jobs.

With immutable GitHub releases, the first matrix job to publish the release locked the asset list, causing later uploads to fail. Switching uploads to draft releases by tag also created multiple draft releases for the same tag.

Use semantic-release to create one draft release, build all platform assets in one binary job, upload them with gh release upload, then publish the draft after uploads complete.
@adityathebe adityathebe force-pushed the fix/semantic-release-draft-upload branch from 5d0b877 to 46baf1e Compare May 20, 2026 11:58
@adityathebe adityathebe merged commit e309486 into main May 20, 2026
16 checks passed
@adityathebe adityathebe deleted the fix/semantic-release-draft-upload branch May 20, 2026 14:31
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