Skip to content

fix(release): draft-first pattern to avoid immutability failure on retag#580

Merged
intel352 merged 1 commit into
mainfrom
fix/draft-release
May 8, 2026
Merged

fix(release): draft-first pattern to avoid immutability failure on retag#580
intel352 merged 1 commit into
mainfrom
fix/draft-release

Conversation

@intel352

@intel352 intel352 commented May 8, 2026

Copy link
Copy Markdown
Contributor

Summary

  • .github/workflows/release.yml: change Create Release step to draft: true and add a Publish release step after asset upload completes

Why

The "target_commitish cannot be changed when release is immutable" error occurs when softprops/action-gh-release attempts to update an existing (already-published) release for a tag. By starting as a draft, the action can safely create/update the release and upload assets without hitting the immutability gate. The separate gh release edit --draft=false step only fires after all assets are uploaded successfully.

The downstream jobs (update-homebrew, notify-ide-plugins) already depend on the release job completing, so they fire naturally after the publish step — no sequencing changes needed.

Test plan

  • Tag a new release (e.g. v0.25.0) and verify the release starts as draft, all binary + UI assets upload, then the release becomes public
  • Verify that retrying a failed build doesn't hit the immutability error

🤖 Generated with Claude Code

softprops/action-gh-release now creates the GitHub release as a draft
while uploading assets; a final step publishes it after all assets are
uploaded. This prevents the "target_commitish cannot be changed when
release is immutable" error observed on workflow v0.24.0 when retrying
a failed release on an existing tag.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 8, 2026 09:30
@intel352 intel352 merged commit bac533a into main May 8, 2026
10 checks passed
@intel352 intel352 deleted the fix/draft-release branch May 8, 2026 09:30

Copilot AI 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.

Pull request overview

Updates the GitHub Actions release workflow to avoid GitHub “immutable release” failures when rerunning a release for an existing tag by creating/updating the release as a draft during asset upload, then publishing it only after uploads succeed.

Changes:

  • Switch softprops/action-gh-release to create the release as a draft during the upload step.
  • Add a follow-up gh release edit ... --draft=false step to publish the release after assets are uploaded.

Comment on lines +276 to +277
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh release edit ${{ env.TAG_NAME }} --draft=false --repo ${{ github.repository }}
@github-actions

github-actions Bot commented May 8, 2026

Copy link
Copy Markdown

⏱ Benchmark Results

No significant performance regressions detected.

benchstat comparison (baseline → PR)
## benchstat: baseline → PR
baseline-bench.txt:260: parsing iteration count: invalid syntax
baseline-bench.txt:313980: parsing iteration count: invalid syntax
baseline-bench.txt:647440: parsing iteration count: invalid syntax
baseline-bench.txt:927965: parsing iteration count: invalid syntax
baseline-bench.txt:1194885: parsing iteration count: invalid syntax
baseline-bench.txt:1518715: parsing iteration count: invalid syntax
benchmark-results.txt:260: parsing iteration count: invalid syntax
benchmark-results.txt:301179: parsing iteration count: invalid syntax
benchmark-results.txt:622855: parsing iteration count: invalid syntax
benchmark-results.txt:899948: parsing iteration count: invalid syntax
benchmark-results.txt:1194342: parsing iteration count: invalid syntax
benchmark-results.txt:1706566: parsing iteration count: invalid syntax
goos: linux
goarch: amd64
pkg: github.com/GoCodeAlone/workflow/dynamic
cpu: AMD EPYC 7763 64-Core Processor                
                            │ baseline-bench.txt │        benchmark-results.txt        │
                            │       sec/op       │    sec/op      vs base              │
InterpreterCreation-4              5.246m ± 104%   3.158m ± 114%       ~ (p=1.000 n=6)
ComponentLoad-4                    3.565m ±   0%   3.670m ±  13%  +2.95% (p=0.002 n=6)
ComponentExecute-4                 1.974µ ±   0%   1.998µ ±   1%  +1.22% (p=0.004 n=6)
PoolContention/workers-1-4         1.089µ ±   1%   1.124µ ±   4%  +3.22% (p=0.002 n=6)
PoolContention/workers-2-4         1.092µ ±   1%   1.113µ ±   3%  +1.92% (p=0.002 n=6)
PoolContention/workers-4-4         1.093µ ±   2%   1.122µ ±   1%  +2.65% (p=0.009 n=6)
PoolContention/workers-8-4         1.098µ ±   3%   1.117µ ±   2%  +1.68% (p=0.039 n=6)
PoolContention/workers-16-4        1.099µ ±   2%   1.135µ ±   2%  +3.32% (p=0.002 n=6)
ComponentLifecycle-4               3.576m ±   1%   3.717m ±   2%  +3.95% (p=0.002 n=6)
SourceValidation-4                 2.305µ ±   0%   2.330µ ±   1%  +1.08% (p=0.002 n=6)
RegistryConcurrent-4               805.0n ±   5%   789.9n ±   4%  -1.88% (p=0.041 n=6)
LoaderLoadFromString-4             3.590m ±   1%   3.673m ±   1%  +2.29% (p=0.002 n=6)
geomean                            18.26µ          17.83µ         -2.36%

                            │ baseline-bench.txt │        benchmark-results.txt         │
                            │        B/op        │     B/op      vs base                │
InterpreterCreation-4               2.027Mi ± 0%   2.027Mi ± 0%       ~ (p=0.193 n=6)
ComponentLoad-4                     2.180Mi ± 0%   2.180Mi ± 0%       ~ (p=0.665 n=6)
ComponentExecute-4                  1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-1-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-2-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-4-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-8-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-16-4         1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
ComponentLifecycle-4                2.183Mi ± 0%   2.183Mi ± 0%       ~ (p=0.167 n=6)
SourceValidation-4                  1.984Ki ± 0%   1.984Ki ± 0%       ~ (p=1.000 n=6) ¹
RegistryConcurrent-4                1.133Ki ± 0%   1.133Ki ± 0%       ~ (p=1.000 n=6) ¹
LoaderLoadFromString-4              2.182Mi ± 0%   2.182Mi ± 0%       ~ (p=0.667 n=6)
geomean                             15.25Ki        15.25Ki       +0.00%
¹ all samples are equal

                            │ baseline-bench.txt │        benchmark-results.txt        │
                            │     allocs/op      │  allocs/op   vs base                │
InterpreterCreation-4                15.68k ± 0%   15.68k ± 0%       ~ (p=1.000 n=6) ¹
ComponentLoad-4                      18.02k ± 0%   18.02k ± 0%       ~ (p=1.000 n=6)
ComponentExecute-4                    25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-1-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-2-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-4-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-8-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-16-4           25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
ComponentLifecycle-4                 18.07k ± 0%   18.07k ± 0%       ~ (p=1.000 n=6) ¹
SourceValidation-4                    32.00 ± 0%    32.00 ± 0%       ~ (p=1.000 n=6) ¹
RegistryConcurrent-4                  2.000 ± 0%    2.000 ± 0%       ~ (p=1.000 n=6) ¹
LoaderLoadFromString-4               18.06k ± 0%   18.06k ± 0%       ~ (p=1.000 n=6) ¹
geomean                               183.3         183.3       +0.00%
¹ all samples are equal

pkg: github.com/GoCodeAlone/workflow/middleware
                                  │ baseline-bench.txt │       benchmark-results.txt       │
                                  │       sec/op       │   sec/op     vs base              │
CircuitBreakerDetection-4                  285.2n ± 4%   287.0n ± 1%       ~ (p=0.240 n=6)
CircuitBreakerExecution_Success-4          21.52n ± 1%   21.53n ± 0%       ~ (p=0.814 n=6)
CircuitBreakerExecution_Failure-4          66.38n ± 1%   66.24n ± 0%       ~ (p=0.169 n=6)
geomean                                    74.12n        74.25n       +0.17%

                                  │ baseline-bench.txt │       benchmark-results.txt        │
                                  │        B/op        │    B/op     vs base                │
CircuitBreakerDetection-4                 144.0 ± 0%     144.0 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Success-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Failure-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                              ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                  │ baseline-bench.txt │       benchmark-results.txt        │
                                  │     allocs/op      │ allocs/op   vs base                │
CircuitBreakerDetection-4                 1.000 ± 0%     1.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Success-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Failure-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                              ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/module
                                 │ baseline-bench.txt │       benchmark-results.txt        │
                                 │       sec/op       │    sec/op     vs base              │
JQTransform_Simple-4                     952.7n ± 20%   897.8n ± 33%       ~ (p=0.589 n=6)
JQTransform_ObjectConstruction-4         1.437µ ±  1%   1.477µ ±  2%  +2.78% (p=0.002 n=6)
JQTransform_ArraySelect-4                3.293µ ±  1%   3.497µ ±  5%  +6.18% (p=0.002 n=6)
JQTransform_Complex-4                    37.64µ ±  1%   40.31µ ±  1%  +7.10% (p=0.002 n=6)
JQTransform_Throughput-4                 1.751µ ±  2%   1.802µ ±  1%  +2.94% (p=0.004 n=6)
SSEPublishDelivery-4                     62.83n ± 11%   63.60n ±  5%       ~ (p=0.065 n=6)
geomean                                  1.629µ         1.666µ        +2.32%

                                 │ baseline-bench.txt │        benchmark-results.txt         │
                                 │        B/op        │     B/op      vs base                │
JQTransform_Simple-4                   1.273Ki ± 0%     1.273Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ObjectConstruction-4       1.773Ki ± 0%     1.773Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ArraySelect-4              2.625Ki ± 0%     2.625Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Complex-4                  16.22Ki ± 0%     16.22Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Throughput-4               1.984Ki ± 0%     1.984Ki ± 0%       ~ (p=1.000 n=6) ¹
SSEPublishDelivery-4                     0.000 ± 0%       0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                             ²                 +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                 │ baseline-bench.txt │       benchmark-results.txt        │
                                 │     allocs/op      │ allocs/op   vs base                │
JQTransform_Simple-4                     10.00 ± 0%     10.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ObjectConstruction-4         15.00 ± 0%     15.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ArraySelect-4                30.00 ± 0%     30.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Complex-4                    324.0 ± 0%     324.0 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Throughput-4                 17.00 ± 0%     17.00 ± 0%       ~ (p=1.000 n=6) ¹
SSEPublishDelivery-4                     0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                             ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/schema
                                    │ baseline-bench.txt │       benchmark-results.txt        │
                                    │       sec/op       │    sec/op     vs base              │
SchemaValidation_Simple-4                    1.116µ ± 4%   1.116µ ± 21%       ~ (p=1.000 n=6)
SchemaValidation_AllFields-4                 1.679µ ± 3%   1.677µ ±  2%       ~ (p=1.000 n=6)
SchemaValidation_FormatValidation-4          1.599µ ± 0%   1.591µ ±  3%       ~ (p=0.177 n=6)
SchemaValidation_ManySchemas-4               1.805µ ± 2%   1.849µ ±  2%  +2.41% (p=0.009 n=6)
geomean                                      1.525µ        1.532µ        +0.45%

                                    │ baseline-bench.txt │       benchmark-results.txt        │
                                    │        B/op        │    B/op     vs base                │
SchemaValidation_Simple-4                   0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_AllFields-4                0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_FormatValidation-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_ManySchemas-4              0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                                ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                    │ baseline-bench.txt │       benchmark-results.txt        │
                                    │     allocs/op      │ allocs/op   vs base                │
SchemaValidation_Simple-4                   0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_AllFields-4                0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_FormatValidation-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_ManySchemas-4              0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                                ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/store
                                   │ baseline-bench.txt │        benchmark-results.txt        │
                                   │       sec/op       │    sec/op     vs base               │
EventStoreAppend_InMemory-4                1.242µ ± 18%   1.316µ ± 12%        ~ (p=0.394 n=6)
EventStoreAppend_SQLite-4                  1.229m ±  4%   1.420m ±  4%  +15.52% (p=0.002 n=6)
GetTimeline_InMemory/events-10-4           13.83µ ±  4%   14.16µ ±  3%        ~ (p=0.240 n=6)
GetTimeline_InMemory/events-50-4           76.99µ ± 20%   78.37µ ±  4%        ~ (p=0.132 n=6)
GetTimeline_InMemory/events-100-4          123.4µ ±  1%   148.8µ ± 14%  +20.63% (p=0.002 n=6)
GetTimeline_InMemory/events-500-4          634.2µ ±  1%   662.3µ ±  1%   +4.44% (p=0.002 n=6)
GetTimeline_InMemory/events-1000-4         1.291m ±  2%   1.365m ±  1%   +5.70% (p=0.002 n=6)
GetTimeline_SQLite/events-10-4             106.1µ ±  0%   112.1µ ±  2%   +5.65% (p=0.002 n=6)
GetTimeline_SQLite/events-50-4             247.9µ ±  1%   260.3µ ±  3%   +4.99% (p=0.002 n=6)
GetTimeline_SQLite/events-100-4            419.9µ ±  1%   439.2µ ±  1%   +4.59% (p=0.002 n=6)
GetTimeline_SQLite/events-500-4            1.786m ±  0%   1.878m ±  2%   +5.16% (p=0.002 n=6)
GetTimeline_SQLite/events-1000-4           3.478m ±  0%   3.742m ±  1%   +7.57% (p=0.002 n=6)
geomean                                    217.6µ         232.6µ         +6.90%

                                   │ baseline-bench.txt │        benchmark-results.txt         │
                                   │        B/op        │     B/op      vs base                │
EventStoreAppend_InMemory-4                  804.5 ± 7%     794.0 ± 5%       ~ (p=0.937 n=6)
EventStoreAppend_SQLite-4                  1.988Ki ± 1%   1.986Ki ± 1%       ~ (p=0.519 n=6)
GetTimeline_InMemory/events-10-4           7.953Ki ± 0%   7.953Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-50-4           46.62Ki ± 0%   46.62Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-100-4          94.48Ki ± 0%   94.48Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-500-4          472.8Ki ± 0%   472.8Ki ± 0%       ~ (p=1.000 n=6)
GetTimeline_InMemory/events-1000-4         944.3Ki ± 0%   944.3Ki ± 0%       ~ (p=1.000 n=6)
GetTimeline_SQLite/events-10-4             16.74Ki ± 0%   16.74Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-50-4             87.14Ki ± 0%   87.14Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-100-4            175.4Ki ± 0%   175.4Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-500-4            846.1Ki ± 0%   846.1Ki ± 0%       ~ (p=0.448 n=6)
GetTimeline_SQLite/events-1000-4           1.639Mi ± 0%   1.639Mi ± 0%       ~ (p=0.080 n=6)
geomean                                    67.46Ki        67.38Ki       -0.12%
¹ all samples are equal

                                   │ baseline-bench.txt │        benchmark-results.txt        │
                                   │     allocs/op      │  allocs/op   vs base                │
EventStoreAppend_InMemory-4                  7.000 ± 0%    7.000 ± 0%       ~ (p=1.000 n=6) ¹
EventStoreAppend_SQLite-4                    53.00 ± 0%    53.00 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-10-4             125.0 ± 0%    125.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-50-4             653.0 ± 0%    653.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-100-4           1.306k ± 0%   1.306k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-500-4           6.514k ± 0%   6.514k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-1000-4          13.02k ± 0%   13.02k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-10-4               382.0 ± 0%    382.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-50-4              1.852k ± 0%   1.852k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-100-4             3.681k ± 0%   3.681k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-500-4             18.54k ± 0%   18.54k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-1000-4            37.29k ± 0%   37.29k ± 0%       ~ (p=1.000 n=6) ¹
geomean                                     1.162k        1.162k       +0.00%
¹ all samples are equal

Benchmarks run with go test -bench=. -benchmem -count=6.
Regressions ≥ 20% are flagged. Results compared via benchstat.

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.

2 participants