Skip to content

Commit 6cb37e9

Browse files
pcamarajrclaude
andauthored
ci: automate releases with release-please manifest mode (#51)
* ci: automate releases with release-please manifest mode One release-please package per plugin (release-type simple); each package syncs its version into .claude-plugin/marketplace.json via a root-relative extra-files jsonpath filter. PR titles are linted as conventional commits since squash-merge titles are what release-please reads. /version-plugin no longer bumps versions by hand — it registers new plugins and points updates at the conventional-commit flow. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * ci: enforce conventional commits locally; fold /version-plugin into CLAUDE.md Mirror Scout's guardrails: husky commit-msg hook running commitlint (config-conventional) via a tooling-only private package.json. The version-plugin skill is removed — release-please owns version bumps and the new-plugin registration checklist now lives in CLAUDE.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 2a31317 commit 6cb37e9

11 files changed

Lines changed: 1179 additions & 217 deletions

File tree

.claude/skills/version-plugin/SKILL.md

Lines changed: 0 additions & 216 deletions
This file was deleted.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: lint-pr-title
2+
3+
on:
4+
pull_request:
5+
types: [opened, edited, synchronize, reopened]
6+
7+
permissions:
8+
pull-requests: read
9+
10+
jobs:
11+
lint:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: amannn/action-semantic-pull-request@v6
15+
env:
16+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
17+
with:
18+
# Squash-merge: the PR title becomes the commit on main that
19+
# release-please reads — the scope should be the plugin name.
20+
scopes: |
21+
astro-builder
22+
astro-lsp
23+
content-image-gemini
24+
content-ops
25+
content-seo
26+
cost-tracker
27+
marketplace
28+
deps
29+
requireScope: false
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: release-please
2+
3+
on:
4+
push:
5+
branches: [main]
6+
7+
permissions:
8+
contents: write
9+
pull-requests: write
10+
11+
jobs:
12+
release-please:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: googleapis/release-please-action@v5

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
node_modules/
12
.claude/worktrees/
23
.claude/settings.local.json
34
.worktrees/

.husky/commit-msg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
npx --no -- commitlint --edit "$1"

.release-please-manifest.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"astro-builder": "1.8.0",
3+
"astro-lsp": "1.0.1",
4+
"content-image-gemini": "1.0.0",
5+
"content-ops": "0.7.0",
6+
"content-seo": "2.0.0",
7+
"cost-tracker": "0.3.0"
8+
}

CLAUDE.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,23 @@ Every plugin entry must have: `name`, `version` (semver), `description`, `author
3737

3838
---
3939

40+
## Releases
41+
42+
Versions are managed by **release-please** (manifest mode, one package per plugin) — never bump a `version` by hand. PRs are squash-merged, so the PR title must be a conventional commit scoped to the plugin (e.g. `feat(astro-builder): ...`); `feat`/`fix`/`!` trigger releases, `chore`/`docs`/`refactor`/`ci` do not — a refactor users will perceive as a feature should be titled `feat(...)`. Merging the release PR that release-please opens updates `marketplace.json` + the plugin's `CHANGELOG.md`/`version.txt` and cuts the tag (`<plugin>-v<version>`) and GitHub Release. Config: `release-please-config.json` + `.release-please-manifest.json`.
43+
44+
Commit messages and PR titles/descriptions are always written in English. Conventional-commit format is enforced locally by a husky `commit-msg` hook (commitlint — run `npm install` once to activate) and in CI by the PR-title lint.
45+
4046
---
4147

4248
## Adding a new plugin
4349

4450
1. Create the plugin directory with `README.md` and its components
45-
2. Run `/version-plugin` — it will register the entry in `marketplace.json` and update the root `README.md`
51+
2. Add the entry to `.claude-plugin/marketplace.json` with `version: "1.0.0"` — the only time a version is written by hand
52+
3. Scaffold `<plugin>/.claude-plugin/plugin.json` (name, description, author, repository, license — no `version` field; version lives exclusively in `marketplace.json`)
53+
4. Register in `release-please-config.json` (copy an existing `packages` entry, adjusting the plugin name in the key and the jsonpath) and `.release-please-manifest.json` (`"<plugin>": "1.0.0"`)
54+
5. Add the plugin name to the `scopes` list in `.github/workflows/lint-pr-title.yml`
55+
6. Add the plugin section to the root `README.md`, in alphabetical order
56+
7. Title the PR `feat(<plugin>): ...``feat` makes release-please cut the plugin's first release, anchored at `1.0.0` by the manifest
4657

4758
---
4859

commitlint.config.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default { extends: ["@commitlint/config-conventional"] };

0 commit comments

Comments
 (0)