Hive Hive
Sign in

feat(cli): release channels (canary / rc / stable)

GitHub issue · Closed

Metadata
Source
tuist/tuist #11242
Updated
Jun 24, 2026
Domains
Distribution
Details

What changed

Implements the release channels RFC, restructuring CLI distribution into three channels with different stability guarantees.

The model shift: today every CLI-touching commit to main cuts a stable X.Y.Z and moves the “Latest” pointer. After this change, main only ever publishes canary prereleases. Stable is reached deliberately:

Channel Version Cadence Resolved by default?
Canary X.Y.0-canary.N every CLI-touching commit to main no — opt-in
Release candidate X.Y.0-rc.N cut from main onto releases/X.Y.x, soaks no — opt-in
Stable X.Y.Z promoted after a clean soak yes

Patches on a stable line keep flowing through the unchanged cli-backport.yml.

CLI release pipeline (feat(cli))

  • mise/tasks/cli/release/channel-version.sh (new) — single script deriving the next version per channel (canary / rc-new / rc / promote) from the git tag set.
  • cli-release.yml — repurposed from stable-cutter into the canary publisher (prerelease, never Latest, no Homebrew; skips when HEAD already has a canary tag).
  • cli-rc.yml (new) — dispatch: empty branch cuts a new releases/X.Y.x line + rc.1; an existing branch iterates rc.N+1.
  • cli-promote.yml (new) — dispatch: promotes a soaked RC to stable X.Y.0 (make_latest=true + Homebrew).
  • cli/cliff.tomlignore_tags = "rc|canary" so prerelease tags never anchor a changelog section.
  • All four reuse cli-build-publish.yml unchanged and share the cli-publish concurrency group.

Server + docs (fix(server))

  • releases.ex — root-cause correctness fix. get_latest_cli_release only filtered tag names that fail to parse as a Version, but a canary like 4.201.0-canary.5 parses fine and sorts above the latest stable 4.200.x (a prerelease only loses the compare when major.minor.patch are equal). Without this, a canary would be advertised as the recommended install. Now gated on %Version{pre: []}; regression test added.
  • New Release channels docs page (channels table, pinning strategy, two-line backport policy) registered in the sidebar, with cross-links from the install and compatibility pages.

Why

Teams upgrading Tuist hit regressions because stable releases bundle unrelated changes. Decoupling fixes from features gives a slow-moving recommended install (tuist@latest / tuist@4.200) that only receives backported fixes, while early adopters keep per-commit builds on canary.

How the canary minor advances

The script’s “highest cut line” is the max minor over stable + RC tags only — canary is deliberately excluded, since it tracks the next minor and counting it would chase its own tail. Because rc-new creates the release branch and publishes rc.1 atomically, the moment a line is cut, main’s canary advances to the following minor. So main keeps moving while a line soaks.

Validation

  • channel-version.sh exercised end-to-end in a throwaway git repo: all four channels plus every error guard (already-stable line, missing RC, malformed branch name, unknown channel).
  • mix test test/tuist/github/releases_test.exs14 tests, 0 failures (includes the new prerelease-exclusion test).
  • shellcheck clean; actionlint clean apart from the pre-existing tuist-linux self-hosted-runner label note (same as cli-backport.yml).

Reviewer notes

  • cli-rc.yml auto-creates the releases/X.Y.x branch by pushing from CI with TUIST_RELEASE_GITHUB_TOKEN. If a branch-protection ruleset blocks branch creation by that token, the rc-new path will fail and the token needs creation bypass on the releases/* pattern. Pushes to existing protected branches still go through PRs.
  • RC cuts, RC iterations, and promotions are all manual workflow_dispatch per the RFC — no cron. The RFC’s open questions (2-week cadence, soak-gating on tester evidence) are operational and intentionally left unencoded.
  • No changes to CLI public API/behavior, and no changes to the server/cache release processes beyond the latest-detection filter.

🤖 Generated with Claude Code

Flights

Investigate, reproduce, or fix this item in an isolated repository. Each Flight preserves its outcome and agent session.

New Flights are paused Configure model inference, GitHub, and a sandbox provider to start another Flight. Existing results remain available below.
No Flights yet

Start a Flight and preserve its objective, outcome, and session here.

Comments
TA
tuist-atlas[bot] Jun 16, 2026

The release channels feature you implemented is now available in 4.201.0-canary.1. Install with:

mise use tuist@4.201.0-canary.1
# or
tuist install 4.201.0-canary.1
TA
tuist-atlas[bot] Jun 16, 2026

This is now available in xcresult-processor-image@0.22.0. Update to this version to use the release channels (canary / rc / stable).

TA
tuist-atlas[bot] Jun 17, 2026

This feature is now available in 4.201.0-canary.5. Update to this version to use release channels (canary, rc, stable).

TA
tuist-atlas[bot] Jun 17, 2026

This change is now available in 4.201.0-canary.4. Update to this version to start using release channels.

TA
tuist-atlas[bot] Jun 17, 2026

The release channels feature (canary, rc, and stable) is now available in 4.201.0-canary.3. Update to this version to try the new channel distribution system.

Note: This is itself a canary release, so you will need to opt-in to this channel to access it.

TA
tuist-atlas[bot] Jun 17, 2026

This change is now available in version 4.201.0-canary.2. Update to use release channels (canary, rc, stable).

TA
tuist-atlas[bot] Jun 18, 2026

Release channels (canary, rc, stable) are now available in 4.201.0-canary.8. Update to this version to use the new channel-based distribution model.

TA
tuist-atlas[bot] Jun 18, 2026

The release channels feature (canary / rc / stable) is now available in 4.201.0-canary.7. This restructures CLI distribution so that main publishes canary prereleases, release candidates soak on dedicated branches, and stable releases are promoted deliberately after a clean soak period.

See the new Release channels documentation for details on pinning strategies and channel stability guarantees.

Update to 4.201.0-canary.7 to use this feature.

TA
tuist-atlas[bot] Jun 18, 2026

The release channels feature (canary / rc / stable) is now available in version 4.201.0-canary.6. Update to this version to use the new channel-based distribution model.

TA
tuist-atlas[bot] Jun 19, 2026

Release channels (canary / rc / stable) are now available in 4.201.0-canary.9. This restructures CLI distribution into three channels with different stability guarantees: canary for per-commit builds from main, release candidate for soak testing, and stable as the default recommended install. Update to 4.201.0-canary.9 to use this feature.

TA
tuist-atlas[bot] Jun 19, 2026

The release channels feature (canary / rc / stable) from this pull request is now available in version 4.201.0-canary.13. Update to that version to use the new channel-based distribution model.

TA
tuist-atlas[bot] Jun 19, 2026

Release channels (canary / rc / stable) are now available in 4.201.0-canary.12. This restructures CLI distribution into three channels with different stability guarantees: canary prereleases on every CLI-touching commit to main, release candidates that soak on release branches, and stable releases promoted after a clean soak. Update to this version to start using the new channel model.

TA
tuist-atlas[bot] Jun 19, 2026

Release channels (canary / rc / stable) are now available in 4.201.0-canary.11. This restructures CLI distribution into three channels: canary prereleases for every CLI-touching commit, release candidates that soak on release branches, and stable releases promoted after a clean soak.

Update to 4.201.0-canary.11 to use this feature.

TA
tuist-atlas[bot] Jun 19, 2026

This is now available in 4.201.0-canary.10. Update to pick up the release channels feature (canary / rc / stable).

TA
tuist-atlas[bot] Jun 20, 2026

Release channels (canary / rc / stable) are now available in 4.201.0-canary.18. Update to this version to use them.

TA
tuist-atlas[bot] Jun 20, 2026

Release channels (canary, rc, stable) are now available in 4.201.0-canary.17. Update to this version to use the new channel-based distribution model.

TA
tuist-atlas[bot] Jun 20, 2026

The release channels feature (canary, release candidate, and stable) is now available in 4.201.0-canary.16. This restructures CLI distribution with explicit stability guarantees. Update to this version to opt into the new channel model.

TA
tuist-atlas[bot] Jun 20, 2026

Release channels (canary, release candidate, and stable) are now available in 4.201.0-canary.15. This restructures CLI distribution into three channels with different stability guarantees. Update to this version to access the new channel-based distribution model.

TA
tuist-atlas[bot] Jun 20, 2026

Release channels (canary, rc, stable) are now available in version 4.201.0-canary.14. Update to this version to use the new channel-based distribution model for CLI releases.

TA
tuist-atlas[bot] Jun 21, 2026

Release channels (canary / rc / stable) are now available in 4.201.0-canary.19. This introduces a three-channel distribution model: canary builds from main, release candidates that soak on release branches, and stable releases promoted after validation. Update to 4.201.0-canary.19 to start using release channels.