diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 9584cb54..2e1e7302 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -3,10 +3,10 @@ silently missing from CHANGELOG.md. The `PR title` check enforces this. See RELEASING.md. - The version is pinned to the alpha stream. While it is, a breaking marker - is refused. That means a `!` in the subject, or a `BREAKING CHANGE:` - footer. Such a marker moves the base version instead of the alpha - counter. Describe the break here instead. --> + A breaking marker — a `!` in the subject, or a `BREAKING CHANGE:` footer — + moves the base version, so the alpha stream goes from 0.0.1-alpha.N to + 0.1.0-alpha.N. Use one where a consumer has to change something, and say + what here. --> ## What this changes diff --git a/.github/workflows/pr-title.yml b/.github/workflows/pr-title.yml index cde0f5fb..01358878 100644 --- a/.github/workflows/pr-title.yml +++ b/.github/workflows/pr-title.yml @@ -45,23 +45,12 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 5 steps: - # Only the manifest, because only the manifest is read: the base-version - # guard below needs it, and a full checkout would fetch the tree to run a - # regex over one line of JSON. - - name: Fetch the version manifest - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - sparse-checkout: .release-please-manifest.json - sparse-checkout-cone-mode: false - persist-credentials: false - - name: Validate the subject that will land on main env: GH_TOKEN: ${{ github.token }} REPO: ${{ github.repository }} NUMBER: ${{ github.event.pull_request.number }} PR_TITLE: ${{ github.event.pull_request.title }} - PR_BODY: ${{ github.event.pull_request.body }} COMMIT_COUNT: ${{ github.event.pull_request.commits }} run: | set -euo pipefail @@ -86,66 +75,19 @@ jobs: echo "ok: ${what} — ${subject}" } - # Every subject GitHub could squash with, and every message a footer - # can hide in. A one-commit PR is squashed with that commit's own - # title, so both must reach both checks below — and the commit's whole - # message is kept, not just its first line, because a 'BREAKING - # CHANGE:' footer lives in the body. - # - # Checking only $PR_TITLE and $PR_BODY is how lpspec shipped - # 0.1.0-alpha.226 and .227 and had to withdraw them: the '!' was in - # the single commit's title, which the guard never read. + # Every subject GitHub could squash with. A one-commit PR is squashed + # with that commit's own title, so $PR_TITLE alone is not the subject + # that lands on main. titles=("PR title|${PR_TITLE}") - messages=("the PR body|${PR_BODY:-}") if [[ "$COMMIT_COUNT" == "1" ]]; then only=$(gh api "repos/${REPO}/pulls/${NUMBER}/commits" --jq '.[0].commit.message') titles+=("the single commit's title|$(head -1 <<<"$only")") - messages+=("the single commit's message|${only}") fi for entry in "${titles[@]}"; do check "${entry%%|*}" "${entry#*|}" done - # A breaking marker moves the *base* version, not the alpha counter. - # While the base is 0.0.0 that is harmless — under `versioning: - # prerelease` a zero patch is an absorbing state, so every bump only - # increments the counter — but the immunity goes away the moment the - # stream leaves 0.0.0, and then `feat!:` on 0.0.1-alpha.12 yields - # 0.1.0-alpha.12 and the project has jumped a minor by accident. The - # marker is refused here rather than discovered in a release PR. - # - # Both ways this can go wrong are named, because either one leaves the - # guard below not running: a missing file aborts the step under `set - # -e` with only sed's own message, and a manifest whose shape changed - # yields an empty $base, which fails *open* — every '!' would sail - # through and the version would move off the stream unannounced. - manifest=.release-please-manifest.json - if [[ ! -f "$manifest" ]]; then - echo "::error::${manifest} not found — the base-version guard cannot run." - exit 1 - fi - base=$(sed -n 's/.*"\.": *"\([^"]*\)".*/\1/p' "$manifest") - if [[ -z "$base" ]]; then - echo "::error::no \".\" version in ${manifest} — the base-version guard cannot run." - exit 1 - fi - - if [[ "$base" == 0.* ]]; then - for entry in "${titles[@]}"; do - if [[ "${entry#*|}" =~ ^[a-z]+(\([a-z0-9._/-]+\))?!: ]]; then - echo "::error::'!' in ${entry%%|*} bumps the base version off the pinned alpha stream (currently ${base})." - fail=1 - fi - done - for entry in "${messages[@]}"; do - if grep -qE '^BREAKING[ -]CHANGE:' <<<"${entry#*|}"; then - echo "::error::a 'BREAKING CHANGE:' footer in ${entry%%|*} bumps the base version off the pinned alpha stream (currently ${base})." - fail=1 - fi - done - fi - if (( fail )); then cat <<'MSG' @@ -156,10 +98,9 @@ jobs: fix(parser): where clauses with a trailing comma docs: describe the two expression tiers - A '!' (or a 'BREAKING CHANGE:' footer) is refused while the version is - pinned to an alpha stream: it moves the *base* version, not the counter. - Describe the break in the PR body instead — the alpha stream carries no - compatibility promise, so there is nothing for the version to announce. + A '!' (or a 'BREAKING CHANGE:' footer) moves the base version: the + stream goes from 0.0.1-alpha.N to 0.1.0-alpha.N. Use one where a + consumer has to change something, and say what in the PR body. Fix the PR title — no need to rewrite the branch. Edits re-run this check. MSG diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 0a4483c7..03663987 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.0.0-alpha.96" + ".": "0.0.1-alpha.96" } diff --git a/AGENTS.md b/AGENTS.md index f09dc0aa..6ec9bde2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -110,7 +110,7 @@ answer here is the mistake. ## Renaming and deleting -The project is on the `0.0.0-alphaN` stream, and it holds no compatibility +The project is on the `0.0.1-alphaN` stream, and it holds no compatibility promise. So when you are asked to change something, change it. Rename it, move it, or @@ -121,11 +121,10 @@ the valid keys, and that is the whole migration story. **A test that asserts the old behaviour is not a blocker.** Say in the PR what coverage moved where. -There is one place where this costs something. A breaking marker in the PR title -is **refused** by the `Conventional commit subject` check. A breaking marker is -a `!`, or a `BREAKING CHANGE:` footer. It is refused because it would move the -base version rather than the alpha counter. Describe the break in the PR body -instead. +This costs one thing. A breaking marker in the PR title moves the minor, so +the stream goes from `0.0.1-alphaN` to `0.1.0-alphaN`. A breaking marker is a +`!`, or a `BREAKING CHANGE:` footer. Use one where a consumer has to change +something, and say what broke in the PR body. ## Numbers and claims @@ -375,8 +374,8 @@ Then write the subject: - **Write a subject the changelog reader can name.** Not `a pass` or `a walk`, and not `dim`, `coord` or `AST`. -Use lower case, no full stop, and conventional-commit form. The breaking marker -is refused. See [CONTRIBUTING.md](CONTRIBUTING.md#commit-messages). The 72 +Use lower case, no full stop, and conventional-commit form. A breaking marker +bumps the minor. See [CONTRIBUTING.md](CONTRIBUTING.md#commit-messages). The 72 character warning in `pr-title.yml` is about `git log --oneline`. The changelog does not truncate. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 68092c85..dcd03106 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -93,9 +93,9 @@ hidden. A subject the parser cannot read is not an error — the entry simply never appears — so the `Conventional commit subject` check enforces the format on every pull request. -While the version is pinned to the alpha stream, a breaking marker (`!`, or a -`BREAKING CHANGE:` footer) is refused, because it moves the base version rather -than the alpha counter. Describe the break in the PR body instead. See +A breaking marker (`!`, or a `BREAKING CHANGE:` footer) moves the base version, +so the alpha stream goes from `0.0.1-alpha.N` to `0.1.0-alpha.N`. Use one where +a consumer has to change something, and say what in the PR body. See [RELEASING.md](https://github.com/energy-models/math-spec/blob/main/RELEASING.md). Beyond the subject line, write whatever body the change deserves — a paragraph diff --git a/RELEASING.md b/RELEASING.md index 8dc04619..117ef19f 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -54,14 +54,15 @@ will be created. ## The alpha stream -The manifest is seeded at `0.0.0-alpha.0`, and the config is in sticky -`prerelease` mode. So every release is `0.0.0-alpha.N`, which is the -distribution version `0.0.0aN`. +The config is in sticky `prerelease` mode, so every release is +`0.0.1-alpha.N`, which is the distribution version `0.0.1aN`. The manifest +carries the base, and one thing moves it: a breaking change. -The seed is what pins the `0.0.0`. release-please increments the counter only -when the version it starts from already carries a prerelease. From a plain -`0.0.0` it would bump the patch first, and the stream would be -`0.0.1-alpha.N`. +The base was `0.0.0` while the stream was pinned there. Under +`versioning: prerelease` a bump lands on the counter whenever the digits below +it are already zero, so at `0.0.0` a minor bump was absorbed and a breaking +marker changed nothing at all. At `0.0.1` the patch is not zero, so the minor +bump bites and one `feat!:` gives `0.1.0-alpha.N`. None of these versions carries a semantic promise. The point of them is that an early user always has a number to quote in a bug report, instead of a commit @@ -80,14 +81,14 @@ Two consequences worth knowing: that is not a prerelease. So the first official version stops the automation, and nobody has to remember to do it. To pause it earlier, set the repository variable `AUTO_RELEASE` to `false`, and merge the release PRs by hand. -- **Breaking markers are refused.** A `!` in the subject, or a - `BREAKING CHANGE:` footer, moves the _base_ version rather than the counter. - Under `versioning: prerelease`, a zero patch is an absorbing state. So at - `0.0.0` a breaking marker is currently harmless. But that immunity disappears - the moment the stream moves, and then one `feat!:` turns `0.0.1-alpha.12` - into `0.1.0-alpha.12`. So `pr-title.yml` refuses the marker. Describe the - break in the PR body instead. The alpha stream carries no compatibility - promise, so there is nothing for the version to announce. +- **A breaking marker bumps the minor.** A `!` in the subject, or a + `BREAKING CHANGE:` footer, moves the base from `0.0.1` to `0.1.0`, and the + counter carries on rather than restarting. That is the one compatibility + signal the stream has: the minor says a consumer has to change something, and + the counter says nothing at all. `pr-title.yml` used to refuse the marker, + because the base was pinned to `0.0.0` and a marker would have moved it off + the stream unannounced. The base is no longer pinned, so the check no longer + looks. ## Leaving the alpha stream @@ -98,8 +99,7 @@ When the project is ready for a real version: 2. Remove `versioning`, `prerelease` and `prerelease-type` from `.release-please-config.json`. 3. Set the manifest to the last version you want release-please to bump _from_. -4. Drop the base-version guard from `pr-title.yml`, so `!` works again. -5. Merge the next release PR by hand. +4. Merge the next release PR by hand. ## One-time setup