ci: rewrite release workflow to be fully GitHub Actions-driven (#25162)

Replace the local interactive release CLI and legacy shell scripts with
a non-interactive Go tool (`scripts/release-action/`) and a rewritten
`release.yaml` workflow. Release managers trigger releases from the
GitHub Actions UI by selecting a branch, picking a release type (`rc`,
`release`, or `create-release-branch`), and optionally providing a
commit SHA.

The Go tool has four subcommands: `calculate-version` (computes next
version from git state), `generate-notes` (release notes from commit log
and PR metadata), `publish` (creates GitHub release with checksums), and
the workflow handles tag creation, branch creation, building, and
downstream publishing.

`scripts/version.sh` fallback now uses `git describe` (nearest ancestor
tag) instead of global latest so dev builds on release branches show the
correct version series.
This commit is contained in:
Garrett Delfosse
2026-06-04 14:38:48 -04:00
committed by GitHub
parent d5b0e93c6c
commit b95697a370
14 changed files with 2485 additions and 178 deletions
+38 -33
View File
@@ -211,55 +211,60 @@ be applied selectively or to discourage anyone from contributing.
## Releases
Coder releases are initiated via
[`./scripts/release.sh`](https://github.com/coder/coder/blob/main/scripts/release.sh)
and automated via GitHub Actions. Specifically, the
Coder releases are managed entirely through the
[`release.yaml`](https://github.com/coder/coder/blob/main/.github/workflows/release.yaml)
workflow.
Release notes are automatically generated from commit titles and PR metadata.
GitHub Actions workflow, triggered manually via "Run workflow" in the Actions
tab. Release notes are automatically generated from commit titles and PR
metadata.
### Release types
| Type | Tag | Branch | Purpose |
|------------------------|---------------|---------------|-----------------------------------------|
| RC (release candidate) | `vX.Y.0-rc.W` | `main` | Ad-hoc pre-release for customer testing |
| Release | `vX.Y.0` | `release/X.Y` | First release of a minor version |
| Patch | `vX.Y.Z` | `release/X.Y` | Bug fixes and security patches |
| Type | Tag | Source | Purpose |
|------------------------|---------------|------------------|---------------------------------------|
| RC (release candidate) | `vX.Y.0-rc.W` | `main` or branch | Pre-release for testing |
| Create release branch | `vX.Y.0-rc.W` | `main` | Cut `release/X.Y` + tag RC atomically |
| Release | `vX.Y.0` | `release/X.Y` | First release of a minor version |
| Patch | `vX.Y.Z` | `release/X.Y` | Bug fixes and security patches |
### Workflow
RC tags are created directly on `main`. The `release/X.Y` branch is only cut
when the release is ready. This avoids cherry-picking main's progress onto
a release branch between the first RC and the release.
RC tags can be created from `main` or from a release branch. The
`create-release-branch` type creates `release/X.Y` and tags the next RC in one
step, continuing the RC numbering sequence.
```text
main: ──●──●──●──●──●──●──●──●──●──
↑ ↑ ↑
rc.0 rc.1 cut release/2.34, tag v2.34.0
\
release/2.34: ──●── v2.34.1 (patch)
main: --*--*--*--*--*--*--*--*--*--
| rc.0 rc.1 |
| +--- create-release-branch ---+
| |
| release/2.34: --*-- rc.2 -- rc.3 -- v2.34.0
|
+-- (more RCs on main for next cycle)
```
1. **RC:** On `main`, run `./scripts/release.sh`. The tool suggests the next
RC version and tags it on `main`.
2. **Release:** When the RC is blessed, create `release/X.Y` from `main` (or
the specific RC commit). Switch to that branch and run
`./scripts/release.sh`, which suggests `vX.Y.0`.
3. **Patch:** Cherry-pick fixes onto `release/X.Y` and run
`./scripts/release.sh` from that branch.
1. **RC:** Go to [Actions > Release](https://github.com/coder/coder/actions/workflows/release.yaml),
click "Run workflow", select `main` (or a release branch) from the "Use
workflow from" dropdown, choose `rc`, and optionally provide a commit SHA
(defaults to HEAD). The workflow calculates the next RC version
automatically.
2. **Create release branch:** Select `main` in the dropdown, choose
`create-release-branch`, and optionally provide a commit SHA. This creates
`release/X.Y` and tags the next RC atomically.
3. **Release:** Select the release branch (e.g. `release/2.34`) from the
dropdown and choose `release`. No other inputs needed.
4. **Patch:** Cherry-pick fixes onto `release/X.Y`, select that branch from
the dropdown, and choose `release`.
The release tool warns if you try to tag a non-RC on `main` or an RC on a
release branch.
The workflow validates that commits are on the expected branch for each release
type.
### Creating a release (via workflow dispatch)
### Retrying a failed release
If the
[`release.yaml`](https://github.com/coder/coder/actions/workflows/release.yaml)
workflow fails after the tag has been pushed, retry it from the GitHub Actions
UI: press "Run workflow", set "Use workflow from" to the tag (e.g.
`Tag: v2.34.0`), select the correct release channel, and do **not** select
dry-run.
workflow fails after the tag has been pushed, re-run the failed jobs from the
GitHub Actions UI. The `prepare-release` job is idempotent and will detect
the existing tag.
To test the workflow without publishing, select dry-run.