From fd9b404a4318e4401e5d71b3cff65ece5c4c57cd Mon Sep 17 00:00:00 2001 From: Paul Mulligan Date: Sat, 24 Oct 2026 09:56:36 -0400 Subject: [PATCH 1/2] docs(release): record that the repository allows only squash merges Since 2026-10-24 the GitHub settings allow squash merges only, with the PR title as the commit title and a blank body. release-please splits any body paragraph that starts with a Conventional Commit type into a second changelog entry, so the merge commits behind 1.1.3 and 1.2.0 listed each change twice. RELEASING.md and the release rule now say so. Co-Authored-By: Claude Opus 5.5 --- .claude/rules/release.md | 2 +- docs/RELEASING.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.claude/rules/release.md b/.claude/rules/release.md index f885d1f..662a08b 100644 --- a/.claude/rules/release.md +++ b/.claude/rules/release.md @@ -11,7 +11,7 @@ paths: `docs/RELEASING.md` is canonical. release-please (`release-please.yml`, config `release-please-config.json`, state `.release-please-manifest.json`) is the only release mechanism; the `standard-version` scripts were removed on 2026-10-23. -- Conventional Commits on `main` drive the version: `fix:` patch, `feat:` minor, `feat!:` or a `BREAKING CHANGE:` footer major; `docs:`, `chore:`, `test:`, `ci:`, `refactor:` do not bump and stay out of the changelog. Squash-merge PRs with a Conventional Commit title. A `Release-As: x.y.z` footer forces a version. +- Conventional Commits on `main` drive the version: `fix:` patch, `feat:` minor, `feat!:` or a `BREAKING CHANGE:` footer major; `docs:`, `chore:`, `test:`, `ci:`, `refactor:` do not bump and stay out of the changelog. Squash-merge PRs with a Conventional Commit title: since 2026-10-24 the repository allows only squash merges, titled from the PR with a blank body, because release-please turns a body paragraph that starts with `feat(`, `fix:` and the like into a second changelog entry (the duplicated 1.1.3 and 1.2.0 entries came from merge commits). A `Release-As: x.y.z` footer forces a version. - release-please keeps one open Release PR from branch `release-please--branches--main--components--optia`. **Merging it is the human release gate.** It stamps `package.json`, `app/package.json` and `app/manifest.json` (the `extra-files`), rewrites `CHANGELOG.md`, tags `vX.Y.Z` and publishes a GitHub Release. The `attach-zip` job in the same run builds `app/dist` at the tag, deletes the manifest `key` (the store rejects it) and uploads `optia-X.Y.Z.zip`. Releases created with the default `GITHUB_TOKEN` do not fire `on: release`, which is why the zip is attached in that run. - `release-zip.yml` is the manual fallback (`workflow_dispatch` with a tag) to rebuild and re-attach the zip. - The Chrome Web Store upload is manual: Paul downloads the zip and uploads it in the Developer Dashboard under paul@pmds.info (item `gnlidlpidaoalbbmekofjednjkhhmehn`). The store requires `manifest.json` at the archive root and a version greater than the published one. `/store-upload-check [tag]` verifies the package first. diff --git a/docs/RELEASING.md b/docs/RELEASING.md index b488fc4..2c87c4f 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -23,6 +23,6 @@ To force a specific version, add a `Release-As: 1.0.0` footer to any commit on ` ## Cautions -- **Squash-merge PRs with a Conventional Commit title** — release-please reads the commits that land on `main`, and a squash commit's message is the PR title. +- **Squash-merge PRs with a Conventional Commit title** — release-please reads the commits that land on `main`, and a squash commit's message is the PR title. Since 2026-10-24 the repository allows only squash merges, with the PR title as the commit title and a blank body: release-please splits any body paragraph that starts with a type such as `feat(` into a second changelog entry, which is how 1.1.3 and 1.2.0 listed each change twice from their merge commits. - The manifest `key` field pins the extension ID (`lgkgkmjldppeidgafolhfpepmabnnbhe`); it ships in the zip so the store keeps the same ID across uploads. Do not remove or regenerate it. - The Chrome Web Store requires each upload's `manifest.json` version to be **greater** than the currently published one — another reason versions only move through the Release PR. From c9ff9707f0701733b10d9c0923821530912e675c Mon Sep 17 00:00:00 2001 From: Paul Mulligan Date: Sat, 24 Oct 2026 09:57:48 -0400 Subject: [PATCH 2/2] docs(release): footers go into the squash body at merge time With a blank squash body, Release-As and BREAKING CHANGE footers on branch commits never reach main. Say how to add them when merging. Co-Authored-By: Claude Opus 5.5 --- .claude/rules/release.md | 2 +- docs/RELEASING.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.claude/rules/release.md b/.claude/rules/release.md index 662a08b..82dcf83 100644 --- a/.claude/rules/release.md +++ b/.claude/rules/release.md @@ -11,7 +11,7 @@ paths: `docs/RELEASING.md` is canonical. release-please (`release-please.yml`, config `release-please-config.json`, state `.release-please-manifest.json`) is the only release mechanism; the `standard-version` scripts were removed on 2026-10-23. -- Conventional Commits on `main` drive the version: `fix:` patch, `feat:` minor, `feat!:` or a `BREAKING CHANGE:` footer major; `docs:`, `chore:`, `test:`, `ci:`, `refactor:` do not bump and stay out of the changelog. Squash-merge PRs with a Conventional Commit title: since 2026-10-24 the repository allows only squash merges, titled from the PR with a blank body, because release-please turns a body paragraph that starts with `feat(`, `fix:` and the like into a second changelog entry (the duplicated 1.1.3 and 1.2.0 entries came from merge commits). A `Release-As: x.y.z` footer forces a version. +- Conventional Commits on `main` drive the version: `fix:` patch, `feat:` minor, `feat!:` or a `BREAKING CHANGE:` footer major; `docs:`, `chore:`, `test:`, `ci:`, `refactor:` do not bump and stay out of the changelog. Squash-merge PRs with a Conventional Commit title: since 2026-10-24 the repository allows only squash merges, titled from the PR with a blank body, because release-please turns a body paragraph that starts with `feat(`, `fix:` and the like into a second changelog entry (the duplicated 1.1.3 and 1.2.0 entries came from merge commits). A `Release-As: x.y.z` footer forces a version; branch-commit footers do not survive the squash, so a `Release-As:` or `BREAKING CHANGE:` footer goes into the squash body at merge time (`gh pr merge --squash --body '...'`), or the title carries `!`. - release-please keeps one open Release PR from branch `release-please--branches--main--components--optia`. **Merging it is the human release gate.** It stamps `package.json`, `app/package.json` and `app/manifest.json` (the `extra-files`), rewrites `CHANGELOG.md`, tags `vX.Y.Z` and publishes a GitHub Release. The `attach-zip` job in the same run builds `app/dist` at the tag, deletes the manifest `key` (the store rejects it) and uploads `optia-X.Y.Z.zip`. Releases created with the default `GITHUB_TOKEN` do not fire `on: release`, which is why the zip is attached in that run. - `release-zip.yml` is the manual fallback (`workflow_dispatch` with a tag) to rebuild and re-attach the zip. - The Chrome Web Store upload is manual: Paul downloads the zip and uploads it in the Developer Dashboard under paul@pmds.info (item `gnlidlpidaoalbbmekofjednjkhhmehn`). The store requires `manifest.json` at the archive root and a version greater than the published one. `/store-upload-check [tag]` verifies the package first. diff --git a/docs/RELEASING.md b/docs/RELEASING.md index 2c87c4f..cfa55d2 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -19,7 +19,7 @@ Releases are automated with [release-please](https://github.com/googleapis/relea | `feat!:` / `BREAKING CHANGE:` footer | major | | `docs:`, `chore:`, `test:`, `ci:`, `refactor:` | none (hidden from changelog) | -To force a specific version, add a `Release-As: 1.0.0` footer to any commit on `main`. +To force a specific version, add a `Release-As: 1.0.0` footer to any commit on `main`. Footers on branch commits do not survive a squash merge (the squash body is blank), so type the footer into the squash commit when merging: `gh pr merge --squash --body 'Release-As: 1.0.0'`, or edit the message in the merge dialog. The same goes for a `BREAKING CHANGE:` footer; `feat!:` in the PR title needs nothing extra. ## Cautions