From 3b36d6febab688bdf03d2e7677a23e8700579291 Mon Sep 17 00:00:00 2001 From: Klink <85062+dogmar@users.noreply.github.com> Date: Mon, 15 Jun 2026 12:41:43 -0700 Subject: [PATCH] ci: publish prereleases from main on the alpha channel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switch semantic-release so `main` publishes prereleases (X.Y.Z-alpha.N) to the npm `alpha` dist-tag instead of stable releases to `latest`. The first stable release will be 3.0.0 — the next major above the prematurely published, now-deprecated 2.x. - release.config.mjs: branches = ["stable", { name: "main", prerelease: "alpha" }]. `stable` is an inert placeholder required by semantic-release (it rejects a prerelease-only config); no release commits go to it until the 3.0.0 cutover. - CLAUDE.md: document the alpha-by-default policy and the 3.0.0 cutover steps. The 0.0.0 and 2.0.x versions are deprecated on npm separately (manual, requires npm auth). `latest` stays on 2.0.3 until the 3.0.0 cutover. Co-Authored-By: Claude Opus 4.8 --- CLAUDE.md | 36 ++++++++++++++++++++++++++++++++++++ release.config.mjs | 8 +++++++- 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..db3a544 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,36 @@ +# CLAUDE.md + +Guidance for Claude Code and other agents working in this repository. + +## Releasing / Publishing + +**Status: pre-stable.** The API is unstable and changes frequently. The first stable release +will be **`3.0.0`** — the next major above the prematurely published (now-deprecated) `2.x`. + +**Default release channel is `alpha`.** Version-bumping commits on `main` are published by +semantic-release as `X.Y.Z-alpha.N` to the npm **`alpha`** dist-tag. Install the latest +prerelease with `npm install @klinking/colander@alpha`. + +**Never publish to `latest`** (the stable channel) until a deliberate `3.0.0` cutover. Until +then `latest` stays on the deprecated `2.0.3`. + +Mechanics: + +- Config: [`release.config.mjs`](release.config.mjs) → + `branches: ["stable", { name: "main", prerelease: "alpha" }]`. +- `stable` is an **inert placeholder branch** required by semantic-release (it rejects a + prerelease-only config). Do not push release commits to it. (`stable` is exempt from the + "Enforce branch folders" repo ruleset so it can exist as a top-level branch.) +- The alpha line only resolves to `3.0.0-alpha.N` once a **breaking change** (`feat!:` / + `BREAKING CHANGE:`) lands since `v2.0.3`; a plain `feat:` would yield a `2.x` alpha line, and + the strategy/config commits (`chore:`/`ci:`/`docs:`) don't trigger a release at all. + +### Cutting the stable 3.0.0 release (when the API is deemed stable) + +1. Ensure ≥1 breaking change exists since `v2.0.3` so the version resolves to `3.0.0`. +2. In [`release.config.mjs`](release.config.mjs), set `branches: ["main"]` (drop the prerelease + and the placeholder). +3. Optionally delete the placeholder branch: `git push origin --delete stable` (leaving it is + harmless; if the branch-folder ruleset exemption was removed, re-add it first to delete). +4. Push to `main` → semantic-release publishes **`3.0.0`** to `latest`. Verify with + `npx semantic-release --dry-run` first. diff --git a/release.config.mjs b/release.config.mjs index 4ff9e0f..e5c7d0a 100644 --- a/release.config.mjs +++ b/release.config.mjs @@ -2,7 +2,13 @@ * @type {import('semantic-release').GlobalConfig} */ export default { - branches: ["main"], + // PUBLISHING POLICY (pre-stable): `main` publishes prereleases to the npm `alpha` dist-tag + // as X.Y.Z-alpha.N. `latest` must NOT be updated until we deliberately cut the first stable + // release — 3.0.0, the next major above the prematurely published (now-deprecated) 2.x. + // `stable` is an inert placeholder: semantic-release rejects a prerelease-only config, so a + // release branch must exist. Do not push release commits to it until the cutover. + // See CLAUDE.md "Releasing / Publishing" for the policy and the 3.0.0 cutover steps. + branches: ["stable", { name: "main", prerelease: "alpha" }], plugins: [ ["@semantic-release/commit-analyzer", { preset: "conventionalcommits" }], [