@verndale/ai-commit 2.4.3 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +221 -52
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,10 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
AI-assisted [Conventional Commits](https://www.conventionalcommits.org/) with **bundled [commitlint](https://commitlint.js.org/)** so generated messages match the same rules enforced in hooks.
|
|
4
4
|
|
|
5
|
+
---
|
|
6
|
+
|
|
5
7
|
## Requirements
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
| | |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| **Node.js** | `>=24.14.0` |
|
|
12
|
+
| **Package manager** | This repo pins **pnpm** in `package.json`. Enable with [Corepack](https://nodejs.org/api/corepack.html): `corepack enable`. |
|
|
13
|
+
|
|
14
|
+
---
|
|
9
15
|
|
|
10
16
|
## Install
|
|
11
17
|
|
|
@@ -13,48 +19,118 @@ AI-assisted [Conventional Commits](https://www.conventionalcommits.org/) with **
|
|
|
13
19
|
pnpm add -D @verndale/ai-commit
|
|
14
20
|
```
|
|
15
21
|
|
|
16
|
-
|
|
22
|
+
**npm** and **yarn** work too (`npm install -D @verndale/ai-commit`). Where this doc says `pnpm exec`, use your tool’s equivalent (`npx`, `yarn exec`, etc.).
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Setup
|
|
27
|
+
|
|
28
|
+
Do these **in order** from your **git repository root** (the directory that contains `package.json`).
|
|
29
|
+
|
|
30
|
+
### 1. Install the package
|
|
31
|
+
|
|
32
|
+
See [Install](#install).
|
|
33
|
+
|
|
34
|
+
### 2. Run init
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pnpm exec ai-commit init
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**What init does (by default):**
|
|
41
|
+
|
|
42
|
+
| Action | Detail |
|
|
43
|
+
| --- | --- |
|
|
44
|
+
| Env files | Merges **`.env`** and **`.env-example`**; creates **`.env-example`** from the bundled template if missing. Template reference: [`.env-example`](.env-example). |
|
|
45
|
+
| Husky | Runs **`npx husky@9 init`** if Husky is not present. |
|
|
46
|
+
| `package.json` | Adds missing **`commit`**, **`prepare`**, **`husky`** entries when the file exists. |
|
|
47
|
+
| Hooks | Writes **`.husky`** hook files. |
|
|
48
|
+
|
|
49
|
+
If **`package.json`** changed, run **`pnpm install`** (or `npm install`) again.
|
|
50
|
+
|
|
51
|
+
### 3. Add your API key
|
|
52
|
+
|
|
53
|
+
Set **`OPENAI_API_KEY`** in **`.env`** and/or **`.env.local`**. Duplicate keys: **`.env.local`** wins.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
### Init: flags and shortcuts
|
|
58
|
+
|
|
59
|
+
| Flag | Use when |
|
|
60
|
+
| --- | --- |
|
|
61
|
+
| *(none)* | Full setup: env files + Husky + hooks + `package.json` updates (when applicable). |
|
|
62
|
+
| `--env-only` | You only want env / **`.env-example`** updates—no Git hooks. |
|
|
63
|
+
| `--husky` | Hooks + Husky only; skips **`package.json`** changes. Combine with **`--workspace`** if you need **`package.json`** merged again. |
|
|
64
|
+
| `--force` | Replace **`.env`** and **`.env-example`** with the bundled template **(destructive)** and/or overwrite existing Husky hook files. |
|
|
65
|
+
|
|
66
|
+
**Edge cases**
|
|
67
|
+
|
|
68
|
+
| Situation | Behavior |
|
|
69
|
+
| --- | --- |
|
|
70
|
+
| Not in a git repo | Init updates env files only and reports that Git/Husky were skipped. |
|
|
71
|
+
| Template filename | The published file is **`.env-example`** (hyphen), not **`.env.example`**. |
|
|
72
|
+
| Without **`--force`** | Missing **`.env-example`** is created; otherwise missing ai-commit keys are **appended** to **`.env`** (and the example file) without wiping the file. |
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
### Setup — command cheat sheet
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
pnpm add -D @verndale/ai-commit
|
|
80
|
+
pnpm exec ai-commit init
|
|
81
|
+
# Set OPENAI_API_KEY in .env or .env.local
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Optional variants:
|
|
17
85
|
|
|
18
|
-
|
|
86
|
+
```bash
|
|
87
|
+
pnpm exec ai-commit init --env-only
|
|
88
|
+
pnpm exec ai-commit init --husky
|
|
89
|
+
pnpm exec ai-commit init --force
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
19
93
|
|
|
20
|
-
|
|
21
|
-
2. **Init** — From the **git repo root** (where **`package.json`** lives), run **`pnpm exec ai-commit init`**. That merges **`.env`** and **`.env-example`** (creates **`.env-example`** from the bundled template if it is missing; see [`.env-example`](.env-example) for keys and comments), runs **`npx husky@9 init`** if Husky is not present, adds missing **`commit`** / **`prepare`** / **`husky`** entries to **`package.json`** when the file exists, and writes **`.husky`** hooks. **Install dependencies** afterward if **`package.json`** changed (`pnpm install`, `npm install`, etc.).
|
|
22
|
-
- Not in a git repo? **init** only updates env files and explains that Git/Husky were skipped.
|
|
23
|
-
- Env files only? Use **`pnpm exec ai-commit init --env-only`**.
|
|
24
|
-
- Hooks only (no **`package.json`** changes)? Use **`pnpm exec ai-commit init --husky`**.
|
|
25
|
-
3. **Secrets** — Set **`OPENAI_API_KEY`** in `.env` and/or `.env.local` (`.env.local` overrides `.env` for duplicate keys).
|
|
94
|
+
## Environment variables
|
|
26
95
|
|
|
27
|
-
|
|
96
|
+
| Variable | Notes |
|
|
97
|
+
| --- | --- |
|
|
98
|
+
| **`OPENAI_API_KEY`** | Required for **`ai-commit run`** and for AI in **`prepare-commit-msg`** when you want the model. |
|
|
99
|
+
| **`COMMIT_AI_MODEL`** | Optional; default **`gpt-4o-mini`**. |
|
|
100
|
+
| **Load order** | CLI loads **`.env`**, then **`.env.local`** (same key → `.env.local` wins). |
|
|
101
|
+
|
|
102
|
+
**Comments:** If another tool already documents **`OPENAI_API_KEY`** or **`COMMIT_AI_MODEL`**, **`ai-commit init`** inserts a `# @verndale/ai-commit — …` line above the assignment when that line is missing. It does not remove existing comments.
|
|
28
103
|
|
|
29
|
-
|
|
104
|
+
**Other tooling (optional):** `PR_*` for [`@verndale/ai-pr`](https://www.npmjs.com/package/@verndale/ai-pr) and **`pnpm run pr:create`** / PR workflows; `RELEASE_NOTES_AI_*` for [`tools/semantic-release-notes.cjs`](./tools/semantic-release-notes.cjs). Use a GitHub PAT as **`GH_TOKEN`** or **`GITHUB_TOKEN`** when calling the GitHub API outside Actions.
|
|
30
105
|
|
|
31
|
-
|
|
32
|
-
- **Shared env vars** — If another tool already documents **`OPENAI_API_KEY`** or **`COMMIT_AI_MODEL`**, **`ai-commit init`** adds its own `# @verndale/ai-commit — …` line immediately above the assignment when missing; it does not remove or replace existing comment lines.
|
|
33
|
-
- The CLI loads **`.env`** then **`.env.local`** from the current working directory (project root); values in `.env.local` override `.env` for the same key.
|
|
34
|
-
- **Optional tooling:** `PR_*` env vars for [`@verndale/ai-pr`](https://www.npmjs.com/package/@verndale/ai-pr) (`pnpm run pr:create` in this repo) / the **Create or update PR** workflow; `RELEASE_NOTES_AI_*` for [`tools/semantic-release-notes.cjs`](./tools/semantic-release-notes.cjs). Use a GitHub PAT as **`GH_TOKEN`** (or `GITHUB_TOKEN`) when calling the GitHub API outside Actions.
|
|
106
|
+
---
|
|
35
107
|
|
|
36
108
|
## Commit policy (v2)
|
|
37
109
|
|
|
38
|
-
- **Mandatory scope** —
|
|
110
|
+
- **Mandatory scope** — Headers are `type(scope): Subject` (or `type(scope)!:` when breaking). Scope comes from staged paths ([`lib/core/message-policy.js`](lib/core/message-policy.js)), not from the model, with fallback from `package.json` (e.g. `ai-commit`).
|
|
39
111
|
- **Types** — `build`, `chore`, `ci`, `docs`, `feat`, `fix`, `perf`, `refactor`, `revert`, `style`, `test`.
|
|
40
112
|
- **Subject** — Imperative, Beams-style (first word capitalized), max **50** characters, no trailing period.
|
|
41
|
-
- **Body / footer** — Wrap
|
|
113
|
+
- **Body / footer** — Wrap at **72** characters when present.
|
|
42
114
|
- **Issues** — If branch or diff mentions `#123`, footers may add `Refs #n` / `Closes #n` (no invented numbers).
|
|
43
|
-
- **Breaking changes** — Only when policy detects governance-related files (commitlint, Husky, this package’s rules/preset); otherwise `!` and `BREAKING CHANGE:`
|
|
44
|
-
- **Staged diff for AI** — Lockfile and common binary globs are
|
|
115
|
+
- **Breaking changes** — Only when policy detects governance-related files (commitlint, Husky, this package’s rules/preset); otherwise `!` and `BREAKING CHANGE:` are stripped.
|
|
116
|
+
- **Staged diff for AI** — Lockfile and common binary globs are excluded from the text sent to the model ([`lib/core/git.js`](lib/core/git.js)); path detection still uses the full staged file list.
|
|
117
|
+
|
|
118
|
+
**Semver:** v2 tightens commitlint (mandatory scope, stricter lengths). If you `extends` this preset, review [`lib/rules.js`](lib/rules.js) and adjust overrides as needed.
|
|
45
119
|
|
|
46
|
-
|
|
120
|
+
---
|
|
47
121
|
|
|
48
|
-
##
|
|
122
|
+
## CLI reference
|
|
49
123
|
|
|
50
124
|
| Command | Purpose |
|
|
51
125
|
| --- | --- |
|
|
52
|
-
|
|
|
53
|
-
|
|
|
54
|
-
|
|
|
55
|
-
|
|
|
126
|
+
| **`ai-commit run`** | Build a message from the staged diff and run **`git commit`**. |
|
|
127
|
+
| **`ai-commit init`** | Env merge (including **`.env-example`**), Husky if needed, **`package.json`** when present, hooks. See [flags](#init-flags-and-shortcuts). |
|
|
128
|
+
| **`ai-commit prepare-commit-msg <file> [source]`** | Hook: fill an empty message; skips `merge` / `squash`. |
|
|
129
|
+
| **`ai-commit lint --edit <file>`** | Hook: commitlint with this package’s default config. |
|
|
56
130
|
|
|
57
|
-
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## `package.json` script (example)
|
|
58
134
|
|
|
59
135
|
```json
|
|
60
136
|
{
|
|
@@ -64,9 +140,11 @@ Use **`ai-commit init --force`** to replace **`.env`** and **`.env-example`** wi
|
|
|
64
140
|
}
|
|
65
141
|
```
|
|
66
142
|
|
|
143
|
+
---
|
|
144
|
+
|
|
67
145
|
## Husky (manual setup)
|
|
68
146
|
|
|
69
|
-
**`pnpm exec ai-commit init`**
|
|
147
|
+
**`pnpm exec ai-commit init`** configures Husky for you. To add hooks by hand, install Husky (`husky` + `"prepare": "husky"` in `package.json` if needed), then add:
|
|
70
148
|
|
|
71
149
|
**`.husky/prepare-commit-msg`**
|
|
72
150
|
|
|
@@ -86,15 +164,17 @@ pnpm exec ai-commit prepare-commit-msg "$1" "$2"
|
|
|
86
164
|
pnpm exec ai-commit lint --edit "$1"
|
|
87
165
|
```
|
|
88
166
|
|
|
89
|
-
Hooks
|
|
167
|
+
Hooks from **`init`** use **`pnpm exec ai-commit`** when **`pnpm-lock.yaml`** exists; otherwise **`npx --no ai-commit`**. Edit the files if you use another runner.
|
|
168
|
+
|
|
169
|
+
**Already using Husky?** If **`.husky/_/husky.sh`** exists, **`init`** does not run **`npx husky@9 init`**. **`package.json`** is only amended for missing **`commit`**, **`prepare`**, or **`devDependencies.husky`**. Existing **`.husky/prepare-commit-msg`** and **`.husky/commit-msg`** are not overwritten unless you use **`ai-commit init --force`**.
|
|
90
170
|
|
|
91
|
-
|
|
171
|
+
---
|
|
92
172
|
|
|
93
173
|
## commitlint without a second install
|
|
94
174
|
|
|
95
|
-
Use
|
|
175
|
+
Use **`ai-commit lint --edit`** from hooks (see above).
|
|
96
176
|
|
|
97
|
-
To **extend** the
|
|
177
|
+
To **extend** the preset in your own `commitlint.config.js`:
|
|
98
178
|
|
|
99
179
|
```js
|
|
100
180
|
module.exports = {
|
|
@@ -105,12 +185,95 @@ module.exports = {
|
|
|
105
185
|
};
|
|
106
186
|
```
|
|
107
187
|
|
|
108
|
-
|
|
188
|
+
Shared constants (types, line limits):
|
|
109
189
|
|
|
110
190
|
```js
|
|
111
191
|
const rules = require("@verndale/ai-commit/rules");
|
|
112
192
|
```
|
|
113
193
|
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## GitHub Actions (CI snippet)
|
|
197
|
+
|
|
198
|
+
Use **commitlint in your own workflow file** — nothing calls back to the `ai-commit` repository’s pipelines. After `pnpm add -D @verndale/ai-commit`, add a root **`commitlint.config.cjs`** (or `.js`) that **`extends: ["@verndale/ai-commit"]`** as in [commitlint without a second install](#commitlint-without-a-second-install). **`@commitlint/cli`** is already a dependency of this package, so `pnpm exec commitlint` works once dependencies are installed.
|
|
199
|
+
|
|
200
|
+
Save as **`.github/workflows/commitlint.yml`** (or merge the job into an existing workflow). Adjust **`branches`** / **`branches-ignore`** if your default branch is not **`main`**.
|
|
201
|
+
|
|
202
|
+
```yaml
|
|
203
|
+
name: Commit message lint
|
|
204
|
+
|
|
205
|
+
on:
|
|
206
|
+
pull_request:
|
|
207
|
+
branches: [main]
|
|
208
|
+
types: [opened, synchronize, reopened, edited]
|
|
209
|
+
push:
|
|
210
|
+
branches-ignore:
|
|
211
|
+
- main
|
|
212
|
+
|
|
213
|
+
jobs:
|
|
214
|
+
commitlint:
|
|
215
|
+
runs-on: ubuntu-latest
|
|
216
|
+
steps:
|
|
217
|
+
- name: Checkout
|
|
218
|
+
uses: actions/checkout@v4
|
|
219
|
+
with:
|
|
220
|
+
fetch-depth: 0
|
|
221
|
+
|
|
222
|
+
- name: Setup Node
|
|
223
|
+
uses: actions/setup-node@v4
|
|
224
|
+
with:
|
|
225
|
+
node-version: "24.14.0"
|
|
226
|
+
|
|
227
|
+
- name: Enable pnpm via Corepack
|
|
228
|
+
run: corepack enable && corepack prepare pnpm@10.11.0 --activate
|
|
229
|
+
|
|
230
|
+
- name: Get pnpm store path
|
|
231
|
+
id: pnpm-cache
|
|
232
|
+
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT
|
|
233
|
+
|
|
234
|
+
- name: Cache pnpm store
|
|
235
|
+
uses: actions/cache@v4
|
|
236
|
+
with:
|
|
237
|
+
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
|
238
|
+
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
|
239
|
+
restore-keys: |
|
|
240
|
+
${{ runner.os }}-pnpm-store-
|
|
241
|
+
|
|
242
|
+
- name: Install dependencies
|
|
243
|
+
run: pnpm install --frozen-lockfile
|
|
244
|
+
|
|
245
|
+
- name: Lint PR title (squash merge becomes the commit on main)
|
|
246
|
+
if: github.event_name == 'pull_request'
|
|
247
|
+
env:
|
|
248
|
+
PR_TITLE: ${{ github.event.pull_request.title }}
|
|
249
|
+
run: |
|
|
250
|
+
printf '%s\n' "$PR_TITLE" | pnpm exec commitlint --verbose
|
|
251
|
+
|
|
252
|
+
- name: Lint commit messages (PR range)
|
|
253
|
+
if: github.event_name == 'pull_request'
|
|
254
|
+
run: |
|
|
255
|
+
pnpm exec commitlint \
|
|
256
|
+
--from "${{ github.event.pull_request.base.sha }}" \
|
|
257
|
+
--to "${{ github.event.pull_request.head.sha }}" \
|
|
258
|
+
--verbose
|
|
259
|
+
|
|
260
|
+
- name: Lint last commit (push)
|
|
261
|
+
if: github.event_name == 'push'
|
|
262
|
+
run: |
|
|
263
|
+
pnpm exec commitlint --from=HEAD~1 --to=HEAD --verbose
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
**Notes**
|
|
267
|
+
|
|
268
|
+
| Topic | Detail |
|
|
269
|
+
| --- | --- |
|
|
270
|
+
| **Node** | Use a version that satisfies this package’s **`engines.node`** (see [Requirements](#requirements)). |
|
|
271
|
+
| **npm or Yarn** | Replace the Corepack + pnpm steps with your install (`npm ci`, `yarn install --immutable`, etc.) and run **`npx --no commitlint`** or **`yarn exec commitlint`** instead of **`pnpm exec commitlint`**. |
|
|
272
|
+
| **Config path** | If commitlint does not find your config (non-root monorepo, unusual filename), add **`--config path/to/commitlint.config.cjs`** to each **`commitlint`** invocation. |
|
|
273
|
+
| **Alignment with hooks** | The same rules apply as for **`.husky/commit-msg`** when it runs **`ai-commit lint --edit`** — both use the **`@verndale/ai-commit`** preset. |
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
114
277
|
## Development (this repository)
|
|
115
278
|
|
|
116
279
|
```bash
|
|
@@ -118,46 +281,52 @@ corepack enable
|
|
|
118
281
|
pnpm install
|
|
119
282
|
```
|
|
120
283
|
|
|
121
|
-
Copy **`.env-example`** to `.env`
|
|
284
|
+
Copy **`.env-example`** to `.env` / `.env.local` and set **`OPENAI_API_KEY`**. After staging, **`pnpm commit`** runs **`node ./bin/cli.js run`**; published installs use the **`ai-commit`** binary under **`node_modules/.bin`**. Local **`.husky`** hooks use **`pnpm exec ai-commit`**.
|
|
122
285
|
|
|
123
286
|
### Repository automation
|
|
124
287
|
|
|
288
|
+
To run the same style of checks in **another** repository, copy the workflow in [GitHub Actions (CI snippet)](#github-actions-ci-snippet) (self-contained YAML; no call into this repo’s Actions).
|
|
289
|
+
|
|
125
290
|
| Workflow | Trigger | Purpose |
|
|
126
291
|
| --- | --- | --- |
|
|
127
|
-
| [`.github/workflows/commitlint.yml`](./.github/workflows/commitlint.yml) | PRs to `main`, pushes to non-`main`
|
|
128
|
-
| [`.github/workflows/pr.yml`](./.github/workflows/pr.yml) | Pushes (not `main`)
|
|
129
|
-
| [`.github/workflows/release.yml`](./.github/workflows/release.yml) | Push to **`main`**
|
|
292
|
+
| [`.github/workflows/commitlint.yml`](./.github/workflows/commitlint.yml) | PRs to `main`, pushes to non-`main` | Commitlint on PR range or last push |
|
|
293
|
+
| [`.github/workflows/pr.yml`](./.github/workflows/pr.yml) | Pushes (not `main`), `workflow_dispatch` | **`pnpm run pr:create`** ([**`@verndale/ai-pr`**](https://www.npmjs.com/package/@verndale/ai-pr)); workflow sets **`PR_HEAD_BRANCH`** / **`PR_BASE_BRANCH`**. Use secret **`PR_BOT_TOKEN`** if branch protection requires it. |
|
|
294
|
+
| [`.github/workflows/release.yml`](./.github/workflows/release.yml) | Push to **`main`** | **semantic-release** — version, `CHANGELOG.md`, tag, npm publish, GitHub Release |
|
|
295
|
+
|
|
296
|
+
**Local `pnpm run pr:create`:** set **`GH_TOKEN`** / **`GITHUB_TOKEN`** and **`PR_BASE_BRANCH`** / **`PR_HEAD_BRANCH`** as needed.
|
|
130
297
|
|
|
131
|
-
|
|
298
|
+
---
|
|
132
299
|
|
|
133
300
|
## Publishing (maintainers)
|
|
134
301
|
|
|
135
|
-
Releases
|
|
302
|
+
Releases run via **[semantic-release](https://github.com/semantic-release/semantic-release)** on push to **`main`** ([`.releaserc.json`](.releaserc.json), [`tools/semantic-release-notes.cjs`](./tools/semantic-release-notes.cjs)).
|
|
136
303
|
|
|
137
304
|
### Secrets and registry
|
|
138
305
|
|
|
139
|
-
- **`NPM_TOKEN`** (
|
|
140
|
-
- **If the job fails with `EOTP` / “
|
|
141
|
-
- **Classic token:** npmjs.com → **Access Tokens** → **Generate New Token** (classic) → type **Automation** (not “Publish”). Store
|
|
142
|
-
- **Granular token:** **New Granular Access Token** →
|
|
143
|
-
-
|
|
144
|
-
- **`GITHUB_TOKEN`** —
|
|
306
|
+
- **`NPM_TOKEN`** (repo or org secret) — must **`npm publish`** in CI **without** an interactive OTP. The Release workflow sets **`NPM_TOKEN`** and **`NODE_AUTH_TOKEN`** from it.
|
|
307
|
+
- **If the job fails with `EOTP` / “one-time password”:** 2FA is enforced on publish and the token cannot skip OTP. Fix in one of these ways:
|
|
308
|
+
- **Classic token:** [npmjs.com](https://www.npmjs.com/) → **Access Tokens** → **Generate New Token** (classic) → type **Automation** (not “Publish”). Store as **`NPM_TOKEN`**.
|
|
309
|
+
- **Granular token:** **New Granular Access Token** → enable **Bypass two-factor authentication (2FA)**. Under **Packages and scopes**, **Read and write** for **`@verndale/ai-commit`**. Leave **Allowed IP ranges** empty unless required (Actions egress is not a single fixed IP).
|
|
310
|
+
- Or finish **[Trusted Publishing](https://docs.npmjs.com/trusted-publishers)** for this repo and package (OIDC); you may still need npm-side setup—see npm’s docs for your account.
|
|
311
|
+
- **`GITHUB_TOKEN`** — Provided by Actions. Checkout and **`@semantic-release/git`** use **`SEMANTIC_RELEASE_TOKEN`** when set; otherwise **`GITHUB_TOKEN`**.
|
|
145
312
|
|
|
146
|
-
**npm provenance:** [`.releaserc.json`](
|
|
313
|
+
**npm provenance:** [`.releaserc.json`](.releaserc.json) sets **`"provenance": true`** on **`@semantic-release/npm`**, which matches **npm Trusted Publishing** from this GitHub repo. On [npmjs.com](https://www.npmjs.com/), enable **Trusted Publishing** for this package linked to **`verndale/ai-commit`** (or your fork). If publish fails until that works, finish Trusted Publishing or temporarily set **`"provenance": false`** in **`.releaserc.json`** (you lose the provenance badge).
|
|
147
314
|
|
|
148
|
-
### Branch protection
|
|
315
|
+
### Branch protection
|
|
149
316
|
|
|
150
|
-
semantic-release pushes a **release commit** and **tag** back to
|
|
317
|
+
semantic-release pushes a **release commit** and **tag** back to **`main`** via **`@semantic-release/git`**. If **`main`** is protected and the default token cannot push, either allow **GitHub Actions** to bypass protection for this repository, or add a PAT (classic: **`repo`**; fine-grained: **Contents** read/write) as **`SEMANTIC_RELEASE_TOKEN`**. The Release workflow passes **`SEMANTIC_RELEASE_TOKEN || GITHUB_TOKEN`** to checkout and to semantic-release as **`GITHUB_TOKEN`**.
|
|
151
318
|
|
|
152
319
|
### Commits that produce releases
|
|
153
320
|
|
|
154
|
-
**Conventional Commits** on
|
|
321
|
+
**Conventional Commits** on **`main`** drive the analyzer (patch / minor / major) using each commit’s **first line**; PR bodies do not replace that.
|
|
322
|
+
|
|
323
|
+
With default [`.releaserc.json`](.releaserc.json) (no custom **`releaseRules`**), types like **`chore`**, **`docs`**, **`ci`**, **`style`**, **`test`**, **`build`** do **not** bump version or update **`CHANGELOG.md`**. For user-facing releases, use **`feat`**, **`fix`**, **`perf`**, **`revert`**, or breaking markers. With **squash merge**, the merged message is usually the **PR title**—keep it commitlint-clean.
|
|
155
324
|
|
|
156
|
-
|
|
325
|
+
To release from **`chore`**/**`docs`**-only merges, maintainers can add **`releaseRules`** to **`@semantic-release/commit-analyzer`** in **`.releaserc.json`**; the default skips those types so releases stay signal-heavy.
|
|
157
326
|
|
|
158
|
-
|
|
327
|
+
Tag-only npm publish was removed in favor of this flow to avoid double publishes. **Local try:** `pnpm release` (needs tokens and git state; use a fork or **`--dry-run`** as appropriate).
|
|
159
328
|
|
|
160
|
-
|
|
329
|
+
---
|
|
161
330
|
|
|
162
331
|
## License
|
|
163
332
|
|