Menu

#499 ci(release): parallelise the production release build

closed
nobody
None
2026-07-20
2026-07-20
Anonymous
No

Originally created by: Akarsh-Hegde

[!WARNING]
Do not merge yet. Gated on two things, both listed under "Before this merges" below. Opened now so the design can be reviewed while staging finishes proving itself.

What

Ports the restructure release-staging.yml proved to production: the two macOS arches compile concurrently on separate runners instead of sequentially inside one tauri build --target universal-apple-darwin. semantic-release stops compiling and becomes a publisher - .releaserc.json loses its exec prepareCmd, and everything it did becomes explicit workflow steps.

The changelog and git plugins are untouched, so CHANGELOG.md and the version-bump commit still land back on main exactly as before.

The part that is not a copy of staging

Splitting the build forces a pinned SHA - two runners cannot agree on a commit any other way, and if they disagreed the two halves of the universal binary would silently differ.

But this workflow deliberately checked out the tip of main, and said so:

a burst of merges otherwise has each run pinned to its own (stale) trigger SHA: the older run releases a stale snapshot and its git push HEAD:main is rejected once a newer commit lands ("fetch first")

That is @semantic-release/git pushing the version bump. Staging never hit it - no git plugin, nothing pushed, so pinning was free. Here, pinning is load-bearing for the build and disqualifying for the publish.

Resolved by deferring, not failing. Read what that comment actually guarantees: a burst of merges ends with the release == main and no failed runs - later runs "find nothing new to release (clean no-op)". A hard failure on "main moved" would have thrown that away, converting green no-ops into red X's. So instead:

plan     pins SHA1 (tip at plan time)
build    ~30 min. Meanwhile SHA2 lands -> its own run queues behind this one
release  before publishing: if origin/main != SHA1, log and exit 0.
         Nothing published, no failure. The SHA2 run releases the newer tip.

Deferring is safe precisely because "main moved" always means someone else pushed, and that push always has its own queued run - so a deferral can never drop a release. It cannot livelock either: main only takes infrequent release-PR merges plus [skip ci] version bumps.

The version assertion from staging is kept as a secondary tripwire - the SHA check catches main moving, the version check catches a v* tag appearing from elsewhere (the staging workflow is in a different concurrency group and cuts tags).

Production-only details staging did not need

  • issues: write + pull-requests: write on the release job. Prod's @semantic-release/github comments on what a release closes; staging sets successComment: false. Without these the publish step 403s at the very last moment.
  • create-icons.sh kept in the build jobs. The icons are a compile-time input via generate_context!, so this preserves byte-for-byte what production has always shipped. (Staging's build omits it and relies on the committed icons.)
  • save-if scoped to refs/heads/main, matching [#497]'s reasoning for staging.

Before this merges

  • [ ] Staging's windows-release job goes green, and windows-x86_64 lands in the staging latest.json. 1.73.0 broke on the Windows job specifically - porting a path whose Windows arm has not been watched succeed would be repeating that mistake.
  • [ ] #495 merges first. It unsticks actual stranded Windows customers and is the more urgent change.

The risk I cannot test

@semantic-release/git's push-back has no dry-run. The first real merge of this PR is its test, on the branch that ships to customers. Everything else here was exercised on staging; this one thing structurally cannot be.

Mitigations worth considering before merging: rehearse via workflow_dispatch, or treat the first release after this as supervised rather than fire-and-forget. If the push is rejected, the failure mode is a tagged, published release with no version-bump commit - recoverable by hand, but it should be caught in minutes, not on the next release.

Measured on staging (run 29734394528)

aarch64 x86_64
Build daemon 7.8m 4.8m
Compile tray 19.3m 13.7m

Wall clock is the slower arch, so this is bounded by aarch64, not the sum. With [#497]'s cache fix landing separately, both numbers should drop substantially on warm runs.

🤖 Generated with Claude Code

Related

Tickets: #497
Tickets: #500
Tickets: #508

Discussion

  • Anonymous

    Anonymous - 2026-07-20

    Originally posted by: coderabbitai[bot]

    [!IMPORTANT]

    Review skipped

    Auto reviews are disabled on base/target branches other than the default branch.

    Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.


    ⚙️ Run configuration

    Configuration used: Organization UI

    Review profile: ASSERTIVE

    Plan: Pro Plus

    Run ID: cd0d1ebe-b570-4182-a7c1-967b3efd94dd

    You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

    Use the checkbox below for a quick retry:
    - [ ] 🔍 Trigger review

    ✨ Finishing Touches
    🧪 Generate unit tests (beta) - [ ] Create PR with unit tests - [ ] Commit unit tests in branch `ci/parallel-prod-release`

    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 - [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai) - [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai) - [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai) - [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

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

     
  • Anonymous

    Anonymous - 2026-07-20

    Ticket changed by: Akarsh-Hegde

    • status: open --> closed
     

Log in to post a comment.