Skip to content

fix(ci): create releases as drafts so assets survive Immutable Releases - #19

Merged
bougyman merged 1 commit into
mainfrom
issue-18
Aug 9, 2026
Merged

fix(ci): create releases as drafts so assets survive Immutable Releases#19
bougyman merged 1 commit into
mainfrom
issue-18

Conversation

@bougyman

@bougyman bougyman commented Aug 9, 2026

Copy link
Copy Markdown
Member

Summary

Closes #18.

v0.2.0 shipped with zero release assets, permanently - GitHub's Immutable Releases (GA since Oct 2025) is enabled on this repo, and locks a published release's assets the moment it's created. Confirmed directly via the API: v0.1.2 shows "immutable": false, v0.2.0 shows "immutable": true. release-please was publishing the release immediately, then spending ~10 minutes cross-compiling Burrito targets before gh release upload ran - by then the release was already locked, and the upload 422'd (Cannot upload assets to an immutable release).

Fix is the documented workaround: create the release as a draft (.release-please-config.json: "draft": false -> true), upload every asset while still a draft, then publish it (gh release edit --draft=false) as the final step of the burrito job, once binaries + SHA256SUMS have actually landed.

Bonus fix this gets for free: previously a half-built release was visible/"latest" with zero assets for the whole ~10-minute build window even without the immutability bug - drafts aren't visible until published.

v0.2.0 itself can't be repaired. Since this is a fix: commit, merging it will make release-please want to cut v0.2.1 on its own - that'll be the first release to actually carry real assets, which CRY-37 (the Homebrew tap) needs.

Test plan

  • Validated both edited files parse correctly (ruby -ryaml for the workflow, python3 -m json.tool for the config)
  • Verified draft is a current, non-deprecated release-please config field by checking release-please's own published JSON schema directly, rather than assuming
  • mix test - 180 passed (no application code touched by this change, confirmed unaffected)
  • Next real release should be created as a draft, get its assets attached successfully, then auto-publish - watch for the "Publish the release" step succeeding and the release actually carrying SHA256SUMS + all 3 binaries when it goes live

🤖 Generated with Claude Code

v0.2.0 shipped with zero assets, permanently - GitHub's Immutable
Releases (GA since Oct 2025) is enabled on this repo, and locks a
*published* release's assets the moment it's created (confirmed via
`gh api .../releases`: v0.1.2 shows immutable: false, v0.2.0 shows
immutable: true). release-please was publishing the release
immediately, then spending ~10 minutes cross-compiling Burrito targets
before `gh release upload` ran - by then the release was already
locked, and the upload 422'd.

Fix is the documented workaround: create the release as a draft
(.release-please-config.json), upload every asset while still a draft,
then publish it (gh release edit --draft=false) as the final step of
the burrito job, once binaries + SHA256SUMS have actually landed.

Also closes a latent window beyond the 422 itself: previously a
half-built release was visible/"latest" with zero assets for the whole
build window even without the immutability bug - drafts aren't visible
until published.

v0.2.0 itself can't be repaired - a genuinely new release is needed
after this lands to get real, installable assets.

Closes #18.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 9, 2026 21:13

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the release automation to accommodate GitHub “Immutable Releases” by ensuring release assets are uploaded before the release is published, preventing releases from being permanently created with zero assets.

Changes:

  • Configure release-please to create GitHub releases as drafts ("draft": true) so assets can still be attached.
  • Publish the release only after binaries + SHA256SUMS are uploaded by adding a final gh release edit --draft=false step to the Burrito release workflow.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
.release-please-config.json Switches release-please to create draft releases so assets can be uploaded prior to publication.
.github/workflows/burrito-release.yaml Adds an explicit “Publish the release” step after asset upload to avoid immutable-release asset lockouts.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@bougyman
bougyman merged commit 8572623 into main Aug 9, 2026
3 checks passed
@bougyman
bougyman deleted the issue-18 branch August 9, 2026 21:14
bougyman pushed a commit that referenced this pull request Aug 9, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.2.1](v0.2.0...v0.2.1)
(2026-08-09)


### Bug Fixes

* **ci:** create releases as drafts so assets survive Immutable Releases
([#19](#19))
([8572623](8572623))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
bougyman pushed a commit that referenced this pull request Aug 9, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.3.0](v0.2.1...v0.3.0)
(2026-08-09)


### ⚠ BREAKING CHANGES

* add Readme/LICENSE, feat: wire up the issue list --project picker
([#12](#12))

### Features

* **api:** add LinearCli.Api GraphQL client (Phase 1)
([723f3f6](723f3f6))
* **cli:** add issue create/develop/pr/take/update write commands (Phase
6)
([1649618](1649618))
* **cli:** support Ruby's short subcommand aliases
([#15](#15))
([9fca6b5](9fca6b5))
* initial commit with ash submodule
([c2ceafb](c2ceafb))
* **linear:** add Ash domain resources for
Issue/Project/Team/User/Label/WorkflowState/Comment (Phase 2)
([e2a27f3](e2a27f3))
* **oban:** add scheduled monthly project rollover (Phase 7)
([11afb43](11afb43))
* phase 4 from initial plan -&gt; complete
([012866e](012866e))
* phase 8 - packaging, releasing, and CI
([#1](#1))
([905c238](905c238))
* scaffold Elixir port and enforce conventional commits
([a4d03a0](a4d03a0))


### Bug Fixes

* **ci:** create releases as drafts so assets survive Immutable Releases
([#19](#19))
([8572623](8572623))
* **cli:** reject unrecognized flags instead of treating them as issue
ids ([#2](#2))
([#4](#4))
([e697ff6](e697ff6))


### Performance Improvements

* **linear:** fan out find-by-ids and per-team project fetches (Phase 5)
([fb00153](fb00153))


### Documentation

* add Readme/LICENSE, feat: wire up the issue list --project picker
([#12](#12))
([eb42c69](eb42c69))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
This was referenced Aug 9, 2026
bougyman pushed a commit that referenced this pull request Aug 9, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.4.0](v0.3.1...v0.4.0)
(2026-08-09)


### ⚠ BREAKING CHANGES

* add Readme/LICENSE, feat: wire up the issue list --project picker
([#12](#12))

### Features

* **api:** add LinearCli.Api GraphQL client (Phase 1)
([723f3f6](723f3f6))
* **cli:** add issue create/develop/pr/take/update write commands (Phase
6)
([1649618](1649618))
* **cli:** support Ruby's short subcommand aliases
([#15](#15))
([9fca6b5](9fca6b5))
* initial commit with ash submodule
([c2ceafb](c2ceafb))
* **linear:** add Ash domain resources for
Issue/Project/Team/User/Label/WorkflowState/Comment (Phase 2)
([e2a27f3](e2a27f3))
* **oban:** add scheduled monthly project rollover (Phase 7)
([11afb43](11afb43))
* phase 4 from initial plan -&gt; complete
([012866e](012866e))
* phase 8 - packaging, releasing, and CI
([#1](#1))
([905c238](905c238))
* scaffold Elixir port and enforce conventional commits
([a4d03a0](a4d03a0))


### Bug Fixes

* **ci:** create releases as drafts so assets survive Immutable Releases
([#19](#19))
([8572623](8572623))
* **ci:** package release binaries with the wrapper scripts
([#24](#24))
([5fb24a4](5fb24a4))
* **cli:** reject unrecognized flags instead of treating them as issue
ids ([#2](#2))
([#4](#4))
([e697ff6](e697ff6))


### Performance Improvements

* **linear:** fan out find-by-ids and per-team project fetches (Phase 5)
([fb00153](fb00153))


### Documentation

* add Readme/LICENSE, feat: wire up the issue list --project picker
([#12](#12))
([eb42c69](eb42c69))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
bougyman pushed a commit that referenced this pull request Aug 9, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.5.0](v0.4.0...v0.5.0)
(2026-08-09)


### ⚠ BREAKING CHANGES

* add Readme/LICENSE, feat: wire up the issue list --project picker
([#12](#12))

### Features

* **api:** add LinearCli.Api GraphQL client (Phase 1)
([723f3f6](723f3f6))
* **cli:** add issue create/develop/pr/take/update write commands (Phase
6)
([1649618](1649618))
* **cli:** support Ruby's short subcommand aliases
([#15](#15))
([9fca6b5](9fca6b5))
* initial commit with ash submodule
([c2ceafb](c2ceafb))
* **linear:** add Ash domain resources for
Issue/Project/Team/User/Label/WorkflowState/Comment (Phase 2)
([e2a27f3](e2a27f3))
* **oban:** add scheduled monthly project rollover (Phase 7)
([11afb43](11afb43))
* phase 4 from initial plan -&gt; complete
([012866e](012866e))
* phase 8 - packaging, releasing, and CI
([#1](#1))
([905c238](905c238))
* scaffold Elixir port and enforce conventional commits
([a4d03a0](a4d03a0))


### Bug Fixes

* **ci:** create releases as drafts so assets survive Immutable Releases
([#19](#19))
([8572623](8572623))
* **ci:** package release binaries with the wrapper scripts
([#24](#24))
([5fb24a4](5fb24a4))
* **cli:** reject unrecognized flags instead of treating them as issue
ids ([#2](#2))
([#4](#4))
([e697ff6](e697ff6))


### Performance Improvements

* **linear:** fan out find-by-ids and per-team project fetches (Phase 5)
([fb00153](fb00153))


### Documentation

* add Readme/LICENSE, feat: wire up the issue list --project picker
([#12](#12))
([eb42c69](eb42c69))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
bougyman pushed a commit that referenced this pull request Aug 9, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.6.0](v0.5.0...v0.6.0)
(2026-08-09)


### ⚠ BREAKING CHANGES

* add Readme/LICENSE, feat: wire up the issue list --project picker
([#12](#12))

### Features

* **api:** add LinearCli.Api GraphQL client (Phase 1)
([723f3f6](723f3f6))
* **cli:** add issue create/develop/pr/take/update write commands (Phase
6)
([1649618](1649618))
* **cli:** support Ruby's short subcommand aliases
([#15](#15))
([9fca6b5](9fca6b5))
* initial commit with ash submodule
([c2ceafb](c2ceafb))
* **linear:** add Ash domain resources for
Issue/Project/Team/User/Label/WorkflowState/Comment (Phase 2)
([e2a27f3](e2a27f3))
* **oban:** add scheduled monthly project rollover (Phase 7)
([11afb43](11afb43))
* phase 4 from initial plan -&gt; complete
([012866e](012866e))
* phase 8 - packaging, releasing, and CI
([#1](#1))
([905c238](905c238))
* scaffold Elixir port and enforce conventional commits
([a4d03a0](a4d03a0))


### Bug Fixes

* **ci:** create releases as drafts so assets survive Immutable Releases
([#19](#19))
([8572623](8572623))
* **ci:** package release binaries with the wrapper scripts
([#24](#24))
([5fb24a4](5fb24a4))
* **cli:** reject unrecognized flags instead of treating them as issue
ids ([#2](#2))
([#4](#4))
([e697ff6](e697ff6))


### Performance Improvements

* **linear:** fan out find-by-ids and per-team project fetches (Phase 5)
([fb00153](fb00153))


### Documentation

* add Readme/LICENSE, feat: wire up the issue list --project picker
([#12](#12))
([eb42c69](eb42c69))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
bougyman pushed a commit that referenced this pull request Aug 9, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.7.0](v0.6.0...v0.7.0)
(2026-08-09)


### ⚠ BREAKING CHANGES

* add Readme/LICENSE, feat: wire up the issue list --project picker
([#12](#12))

### Features

* **api:** add LinearCli.Api GraphQL client (Phase 1)
([723f3f6](723f3f6))
* **cli:** add issue create/develop/pr/take/update write commands (Phase
6)
([1649618](1649618))
* **cli:** support Ruby's short subcommand aliases
([#15](#15))
([9fca6b5](9fca6b5))
* initial commit with ash submodule
([c2ceafb](c2ceafb))
* **linear:** add Ash domain resources for
Issue/Project/Team/User/Label/WorkflowState/Comment (Phase 2)
([e2a27f3](e2a27f3))
* **oban:** add scheduled monthly project rollover (Phase 7)
([11afb43](11afb43))
* phase 4 from initial plan -&gt; complete
([012866e](012866e))
* phase 8 - packaging, releasing, and CI
([#1](#1))
([905c238](905c238))
* scaffold Elixir port and enforce conventional commits
([a4d03a0](a4d03a0))


### Bug Fixes

* **ci:** create releases as drafts so assets survive Immutable Releases
([#19](#19))
([8572623](8572623))
* **ci:** package release binaries with the wrapper scripts
([#24](#24))
([5fb24a4](5fb24a4))
* **cli:** reject unrecognized flags instead of treating them as issue
ids ([#2](#2))
([#4](#4))
([e697ff6](e697ff6))


### Performance Improvements

* **linear:** fan out find-by-ids and per-team project fetches (Phase 5)
([fb00153](fb00153))


### Documentation

* add Readme/LICENSE, feat: wire up the issue list --project picker
([#12](#12))
([eb42c69](eb42c69))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
bougyman added a commit that referenced this pull request Aug 9, 2026
…y loop (#30)

## Summary

`draft:true` (#18/#19) desynced release-please's own tracking from
GitHub's actual release state once we published drafts ourselves via a
raw `gh release edit --draft=false`, outside release-please's own
process. Every subsequent run re-included already-released commits and
kept bumping minor forever (0.2.1 -> 0.3.0 -> 0.3.1 -> 0.4.0 -> 0.5.0 ->
0.6.0 -> 0.7.0 -> a pending 0.8.0 PR).

Split release-please's responsibilities into two workflows:

- **`release-pr.yaml`**: runs on every push to `main`,
`skip-github-release: true` - manages the version-bump PR only
(manifest/CHANGELOG.md/`app/mix.exs`), never touches tags/releases at
all, so it has nothing left to get confused about.
- **`release.yaml`**: triggers only when that PR merges (`pull_request:
closed` filtered to `release-please--branches--main` merging - approving
the release *is* the trigger, not every push). Builds the Burrito
binaries/tarballs/checksums first, reads the version straight from the
manifest `release-pr.yaml` already bumped, then creates the tag +
release + uploads every asset in one atomic `gh release create` call. No
separate release object ever sits around waiting for a later upload, so
Immutable Releases (GA Oct 2025, the reason #18 existed) never gets a
chance to lock us out.

Also reverts `.release-please-config.json`'s `draft: true` - unused now
that release-please never creates the release itself.
`burrito-release.yaml` is removed; its steps are folded directly into
`release.yaml`.

**Follow-up needed after this merges**: close the stray "chore(main):
release 0.8.0" PR (#29), opened under the old broken setup, and let
release-please regenerate a clean one against this new pipeline.

## Test plan

- [x] Both new/edited workflow YAML files validated with `ruby -ryaml`
(not python - not reliably available)
- [x] Verified `skip-github-release` is release-please-action's real,
documented input (checked its actual `action.yml` + README directly,
including the exact migration-table semantics: this is what the old
`release-pr` command did)
- [x] Verified release-please-action's own README documents the
identical "build artifacts, run release-please, gh release upload if
release_created" pattern we're now using (minus its release-creation
step, which we do ourselves) - confirms this is well-trodden, not novel
- [x] Manually tested the exact version-extraction one-liner against the
real `.release-please-manifest.json`
- [ ] Next real release-please PR merge should build binaries, create
exactly one tag/release with all assets attached, and not trigger any
further automatic version bump

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This was referenced Aug 11, 2026
bougyman pushed a commit that referenced this pull request Aug 11, 2026
🤖 I have created a release *beep* *boop*
---


##
[1.0.0](v1.0.0...v1.0.0)
(2026-08-11)


### ⚠ BREAKING CHANGES

* graduate to 1.0.0 - disable pre-major version bumping
([#70](#70))
* **cd:** parallelize Burrito target builds and fix Trivy/Podman image
scanning ([#68](#68))
* **ci:** rename release.yaml to main.yaml, workflow name to "main"
([#38](#38))
* add Readme/LICENSE, feat: wire up the issue list --project picker
([#12](#12))

### Features

* add mix githooks.install to activate the repo's git hooks
([#51](#51))
([9b35472](9b35472))
* **api:** add LinearCli.Api GraphQL client (Phase 1)
([723f3f6](723f3f6))
* **ci:** add a full SBOM - app deps, OTP/Elixir runtime, container OS
packages ([#54](#54))
([e296fdd](e296fdd))
* **cli:** add favorite teams/projects, filtering list views by them
([#61](#61))
([6c858d9](6c858d9))
* **cli:** add issue create/develop/pr/take/update write commands (Phase
6)
([1649618](1649618))
* **cli:** add profiles - default team/project stored in local SQLite
([#57](#57))
([554e336](554e336))
* **cli:** add project update - post a status update to a project
([#43](#43))
([30dc6dc](30dc6dc))
* **cli:** make version respect --output json
([#33](#33))
([b160aad](b160aad))
* **cli:** resolve bare issue numbers via active profile, favorited
teams, or a team prompt
([#65](#65))
([8b183da](8b183da))
* **cli:** support Ruby's short subcommand aliases
([#15](#15))
([9fca6b5](9fca6b5))
* initial commit with ash submodule
([c2ceafb](c2ceafb))
* **linear:** add Ash domain resources for
Issue/Project/Team/User/Label/WorkflowState/Comment (Phase 2)
([e2a27f3](e2a27f3))
* **oban:** add scheduled monthly project rollover (Phase 7)
([11afb43](11afb43))
* phase 4 from initial plan -&gt; complete
([012866e](012866e))
* phase 8 - packaging, releasing, and CI
([#1](#1))
([905c238](905c238))
* scaffold Elixir port and enforce conventional commits
([a4d03a0](a4d03a0))


### Bug Fixes

* **ci:** consolidate the release pipeline into one workflow/DAG
([ba821bb](ba821bb))
* **ci:** create releases as drafts so assets survive Immutable Releases
([#19](#19))
([8572623](8572623))
* **ci:** package release binaries with the wrapper scripts
([#24](#24))
([5fb24a4](5fb24a4))
* **ci:** rebuild the release pipeline to stop the version-bump runaway
loop ([#30](#30))
([c311fd4](c311fd4))
* **ci:** relabel the release PR as tagged after we tag it ourselves
([ab1408e](ab1408e))
* **ci:** skip commit-subject validation in the post-merge pipeline
([#41](#41))
([3d00a85](3d00a85))
* **cli:** reject unrecognized flags instead of treating them as issue
ids ([#2](#2))
([#4](#4))
([e697ff6](e697ff6))
* **deps:** update ash to a non-vulnerable version
([#63](#63))
([b838e2a](b838e2a))


### Performance Improvements

* **linear:** fan out find-by-ids and per-team project fetches (Phase 5)
([fb00153](fb00153))


### Documentation

* add Readme/LICENSE, feat: wire up the issue list --project picker
([#12](#12))
([eb42c69](eb42c69))


### Miscellaneous Chores

* **ci:** rename release.yaml to main.yaml, workflow name to "main"
([#38](#38))
([2581a40](2581a40))
* graduate to 1.0.0 - disable pre-major version bumping
([#70](#70))
([87a65ae](87a65ae))


### Continuous Integration

* **cd:** parallelize Burrito target builds and fix Trivy/Podman image
scanning ([#68](#68))
([5cc829a](5cc829a))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
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.

Releases ship with zero assets - GitHub's Immutable Releases locks them before the build finishes

2 participants