## Summary
Removes the GitHub Actions-driven releaser **v2** pipeline so the
interactive release wizard is the only release path, and drops the `v1`
naming now that it is the sole implementation.
## Changes
- Delete `.github/workflows/tag-and-release.yaml` (the v2 workflow).
- Delete `scripts/releaser/v2/`.
- Move `scripts/releaser/v1/` into `scripts/releaser/` as `package
main`.
- Rewrite `scripts/releaser/main.go` to a single wizard command: drop
the `--legacy` flag and the v2 `rc`/`branch`/`release` subcommands and
hidden CI compat commands. `--dry-run` is preserved.
- Update `scripts/release.sh` to run `go run ./scripts/releaser "$@"`
(no `--legacy`).
The legacy `release.yaml` workflow (triggered by `scripts/release.sh`)
is unchanged and remains the release pipeline.
## Validation
- `go build ./scripts/releaser/...`
- `go test ./scripts/releaser/...`
- `go vet` + `golangci-lint run ./scripts/releaser/...`
- `gofmt -l` clean
> [!NOTE]
> The GPG signing key check removal is handled in a stacked follow-up PR
based on this branch.
<details>
<summary>Implementation plan</summary>
- v2 flow = `scripts/releaser/v2/` +
`.github/workflows/tag-and-release.yaml` (uses `go run
./scripts/releaser prepare-release|generate-notes`). `v2` was imported
only by `main.go`; the workflow was referenced nowhere else.
- v1 flow = interactive wizard in `scripts/releaser/v1/`, reached via
`--legacy`, driving `release.yaml` (triggered by `scripts/release.sh`).
- No `docs/` referenced the releaser tool or these workflows.
- Steps: delete the v2 workflow and package; move `v1/*` up to
`scripts/releaser/` (`package main`, including test files); rewrite
`main.go` to a single wizard command; update `release.sh`.
</details>
---
Generated by Coder Agents on behalf of @f0ssel.
## What
Consolidates the two separate release programs into a single command at
`scripts/releaser`:
- `scripts/releaser/v1/` — the former interactive releaser (package
`v1`).
- `scripts/releaser/v2/` — the former `scripts/release-action` CI tool
(package `v2`).
- `scripts/releaser/main.go` — new entrypoint. Runs the **v2** tooling
by
default and the **v1** interactive wizard with `--legacy`.
## CLI shape
Three documented subcommands, each backed by v2 `prepare-release` with
the
release type baked in:
- `releaser rc` — tag a release candidate
- `releaser branch` — cut a new release branch and tag its first RC
- `releaser release` — tag a stable release or patch
The former release-action verbs (`calculate-version`, `prepare-release`,
`generate-notes`, `publish`) are retained as **hidden** top-level
commands with
identical flags and stdout, so `tag-and-release.yaml` migrates with a
path-only
change (`scripts/release-action` -> `scripts/releaser`). `--legacy` runs
the v1
wizard and is mutually exclusive with the subcommands.
`scripts/release.sh` now
launches `releaser --legacy`.
All file moves are rename-detected by git, so the per-file diff is just
the
package declaration.
## Testing
- `go build ./scripts/...`, `go vet ./scripts/releaser/...`, `go test
./scripts/releaser/...`
- `golangci-lint run ./scripts/releaser/...`, `make lint/emdash`,
`shellcheck`, `actionlint`
- Smoke: `releaser --help` shows only rc/branch/release; hidden verbs
still run;
`releaser rc --ref main --dry-run` emits the same JSON contract;
`--legacy rc`
errors cleanly.
<details>
<summary>Implementation plan</summary>
# Plan: Consolidate release tooling into a single `scripts/releaser`
command
## Goal
Merge the two separate release programs into one binary at
`scripts/releaser`:
- `scripts/releaser/v1/` — the current interactive releaser (package
`v1`).
- `scripts/releaser/v2/` — the current CI `scripts/release-action`
(package `v2`).
- `scripts/releaser/main.go` — new entrypoint (package `main`).
- Uses v2 by default, v1 with `--legacy`.
- Exposes 3 subcommands: `rc`, `branch` (cut release branch), `release`.
## Design decision (Option A, chosen)
The workflow needs `prepare-release`, `generate-notes`, and `publish`
invokable
separately (a build happens between prepare and publish). The latter two
are
version-driven and type-agnostic, so they do not map cleanly onto
`rc`/`branch`/`release`.
- Visible subcommands `rc`, `branch`, `release` run v2 `prepare-release`
with the
type baked in and print the same JSON.
- Hidden verbs `calculate-version`, `prepare-release`, `generate-notes`,
`publish` keep byte-identical flags/stdout, so the workflow change is
path-only. Lowest risk; honors "3 subcommands" from a UX perspective.
## `--legacy` semantics
- `releaser --legacy` runs the v1 interactive wizard (preserves today's
behavior; the wizard auto-detects RC vs release from the branch).
- `--legacy` is mutually exclusive with the subcommands (clear error if
combined), because v1 auto-detects type and cannot cut a branch.
## Work items
1. Create `v1` and `v2` packages via `git mv`, renaming `package main`.
Move the `owner`/`repo` consts into each package. Add `v1.Run(inv,
dryRun)`
(old wizard `main()` body) and v2 command builders (`CICommands`,
`TypeCommand`) so internals stay unexported.
2. New `scripts/releaser/main.go`: top-level `releaser` with `--legacy`,
the 3
subcommands, and the hidden compat verbs; delegates to `v1.Run` for
legacy.
3. Update references: `tag-and-release.yaml` (3 command paths + header
comment)
and `scripts/release.sh` (`--legacy`).
4. Verify: build, vet, test, `go run` smoke tests, fmt, lint.
5. Open a single PR from a feature branch.
## Risks / notes
- stdout contract for rc/branch/release and the hidden verbs must stay
identical
(workflow parses stdout); logs go to stderr.
- Patch releases from pre-existing `release/X.Y` branches run those
branches'
own (old) workflow + `scripts/release-action`, so they stay
self-consistent.
New releases cut from branches containing this change get the new
workflow +
`scripts/releaser`. No forwarding stub needed since code and workflow
ship
together.
</details>
---
This PR was created by Coder Agents on behalf of @f0ssel.
Restore PR title validation that was removed in 828f33a when
cdr-bot was expected to handle it. That bot has since been disabled.
The new title job in contrib.yaml validates:
- Conventional commit format (type(scope): description)
- Type from the same set used by release notes generation
- Scope validity derived from the changed files in the PR diff
- All changed files fall under the declared scope
Uses actions/github-script (no third-party marketplace actions).
Also fixes feat(api) examples across docs (no api folder exists)
and consolidates commit rules into CONTRIBUTING.md as the single
source of truth.
Add a confirmation dialog to the release script that prompts the user to
manually update the release calendar documentation before proceeding
with the release.
## Changes
- Added a confirmation prompt that asks users to update the release
calendar documentation
- Provides the URL to the documentation
(https://coder.com/docs/install/releases#release-schedule)
- Suggests running the `./scripts/update-release-calendar.sh` script
- Requires explicit confirmation before proceeding with the release
- Exits the script if the user hasn't updated the documentation
## Testing
- [x] Script syntax validation passes (`bash -n scripts/release.sh`)
- [x] Changes are placed at the appropriate point in the release flow
(after release notes editing, before actual release creation)
This addresses the issue where the release calendar documentation was
getting out of date. While automation can be added later, this ensures
users manually confirm the documentation is updated before each release.
Co-authored-by: blink-so[bot] <211532188+blink-so[bot]@users.noreply.github.com>
Co-authored-by: bpmct <22407953+bpmct@users.noreply.github.com>
The initial assumption that branch manipulations should be done by this
script and not pushed to remote manually has proven to get in the way of
the regular release flow.
These are just safety-checks to prevent user error, safe to remove.
Fixes#13648
* Fix use of `mapfile < <(cmd)` which silently hid errors
* Fix script paths since `SCRIPT_DIR` changed in `lib.sh`
* Set `GITHUB_TOKEN` in release.yaml
* ci: Do release tagging in CI and add --draft support
* Add -h, --help to release.sh
* Add -h, --help to increment_version_tag.sh
* Limit release concurrency
* Add automatic release watching
* ci: Add git config, tag as "GitHub Actions Bot"
Co-authored-by: Dean Sheather <dean@deansheather.com>
This commit introduces three new scripts:
- `release.sh` To be run by a user on their local machine to preview and
create a new release (tag + push)
- `check_commit_metadata.sh` For e.g. detecting breaking changes
- `genereate_release_notes.sh` To display the generated release notes,
used for previews and in `publish_release.sh`
The `release.sh` script can be run without arguments, and it will
automatically determine if we're to do a patch or minor release. A minor
release can be forced via `--minor` flag.
Breaking changes can be annotated either via commit/merge title prefix
(`feat!:`, `feat(api)!:`), or by adding the `release/breaking` label to
the PR that was merged (on GitHub).
Related #5233