semantic-release plugin to analyze commits with conventional-changelog
npx @tessl/cli install tessl/npm-semantic-release--commit-analyzer@13.0.00
# @semantic-release/commit-analyzer
1
2
A semantic-release plugin that analyzes commits with conventional-changelog to determine the type of release (major, minor, patch, or no release) that should be created. It parses commits according to conventional commit formats and matches them against configurable release rules to provide automated semantic versioning decisions.
3
4
## Package Information
5
6
- **Package Name**: @semantic-release/commit-analyzer
7
- **Package Type**: npm
8
- **Language**: JavaScript (ES modules)
9
- **Installation**: `npm install @semantic-release/commit-analyzer -D`
10
11
## Core Imports
12
13
```javascript
14
import { analyzeCommits } from "@semantic-release/commit-analyzer";
15
```
16
17
For CommonJS (not supported - this is an ES module only):
18
19
```javascript
20
// Not supported - ES module only
21
const { analyzeCommits } = require("@semantic-release/commit-analyzer");
22
```
23
24
## Basic Usage
25
26
This plugin is designed to work within the semantic-release ecosystem. It's typically configured in the semantic-release configuration file:
27
28
```json
29
{
30
"plugins": [
31
[
32
"@semantic-release/commit-analyzer",
33
{
34
"preset": "angular",
35
"releaseRules": [
36
{ "type": "docs", "scope": "README", "release": "patch" },
37
{ "type": "refactor", "release": "patch" },
38
{ "type": "style", "release": "patch" }
39
],
40
"parserOpts": {
41
"noteKeywords": ["BREAKING CHANGE", "BREAKING CHANGES"]
42
}
43
}
44
],
45
"@semantic-release/release-notes-generator"
46
]
47
}
48
```
49
50
## Capabilities
51
52
### Commit Analysis
53
54
Analyzes commits using conventional-changelog to determine the appropriate release type.
55
56
```javascript { .api }
57
/**
58
* Determine the type of release to create based on a list of commits.
59
*
60
* @param {Object} pluginConfig - The plugin configuration
61
* @param {String} pluginConfig.preset - conventional-changelog preset ('angular', 'atom', 'codemirror', 'ember', 'eslint', 'express', 'jquery', 'jscs', 'jshint', 'conventionalcommits')
62
* @param {String} pluginConfig.config - Requireable npm package with a custom conventional-changelog preset
63
* @param {String|Array} pluginConfig.releaseRules - A String to load an external module or an Array of rules
64
* @param {Object} pluginConfig.parserOpts - Additional conventional-changelog-parser options that will overwrite ones loaded by preset or config
65
* @param {Object} pluginConfig.presetConfig - Additional configuration passed to the conventional-changelog preset
66
* @param {Object} context - The semantic-release context
67
* @param {Array<Object>} context.commits - The commits to analyze
68
* @param {String} context.cwd - The current working directory
69
* @param {Object} context.logger - Logger instance
70
* @returns {Promise<String|null>} The type of release to create or null if no release
71
*/
72
async function analyzeCommits(pluginConfig, context);
73
```
74
75
**Usage Example:**
76
77
```javascript
78
import { analyzeCommits } from "@semantic-release/commit-analyzer";
79
80
const pluginConfig = {
81
preset: "angular",
82
releaseRules: [
83
{ type: "docs", scope: "README", release: "patch" },
84
{ type: "refactor", release: "patch" }
85
]
86
};
87
88
const context = {
89
commits: [
90
{
91
hash: "abc123",
92
message: "feat: add new feature",
93
author: { name: "John Doe", email: "john@example.com" }
94
},
95
{
96
hash: "def456",
97
message: "fix: resolve bug",
98
author: { name: "Jane Smith", email: "jane@example.com" }
99
}
100
],
101
cwd: process.cwd(),
102
logger: console
103
};
104
105
const releaseType = await analyzeCommits(pluginConfig, context);
106
// Returns: "minor" (due to "feat:" commit)
107
```
108
109
## Configuration Options
110
111
### Plugin Configuration
112
113
```typescript { .api }
114
interface PluginConfig {
115
/** conventional-changelog preset name */
116
preset?: "angular" | "atom" | "codemirror" | "ember" | "eslint" | "express" | "jquery" | "jscs" | "jshint" | "conventionalcommits";
117
/** npm package name of a custom conventional-changelog preset */
118
config?: string;
119
/** External module path or array of release rules */
120
releaseRules?: string | ReleaseRule[];
121
/** Additional conventional-commits-parser options */
122
parserOpts?: ParserOptions;
123
/** Additional configuration passed to the conventional-changelog preset */
124
presetConfig?: object;
125
}
126
127
interface ReleaseRule {
128
/** Commit type (e.g., "feat", "fix") */
129
type?: string;
130
/** Commit scope */
131
scope?: string;
132
/** Whether commit has breaking changes */
133
breaking?: boolean;
134
/** Whether commit is a revert */
135
revert?: boolean;
136
/** Emoji in commit (for Atom preset) */
137
emoji?: string;
138
/** Tag in commit (for Ember/ESLint presets) */
139
tag?: string;
140
/** Component in commit (for Express preset) */
141
component?: string;
142
/** Release type to trigger */
143
release: "major" | "premajor" | "minor" | "preminor" | "patch" | "prepatch" | "prerelease" | false | null;
144
}
145
146
interface ParserOptions {
147
/** Keywords that indicate breaking changes */
148
noteKeywords?: string[];
149
/** Additional parser configuration */
150
[key: string]: any;
151
}
152
```
153
154
### Context Object
155
156
```typescript { .api }
157
interface Context {
158
/** Array of commit objects to analyze */
159
commits: Commit[];
160
/** Current working directory */
161
cwd: string;
162
/** Logger instance */
163
logger: Logger;
164
}
165
166
interface Commit {
167
/** Commit hash */
168
hash: string;
169
/** Commit message */
170
message: string;
171
/** Commit author information */
172
author: {
173
name: string;
174
email: string;
175
};
176
/** Additional commit properties */
177
[key: string]: any;
178
}
179
180
interface Logger {
181
log(message: string, ...args: any[]): void;
182
}
183
```
184
185
## Release Types
186
187
The plugin returns one of the following release types based on semantic versioning:
188
189
```typescript { .api }
190
type ReleaseType =
191
| "major" // Breaking changes
192
| "premajor" // Pre-release major
193
| "minor" // New features
194
| "preminor" // Pre-release minor
195
| "patch" // Bug fixes
196
| "prepatch" // Pre-release patch
197
| "prerelease" // Pre-release
198
| null; // No release needed
199
```
200
201
## Default Release Rules
202
203
The plugin includes built-in release rules for common commit conventions:
204
205
- **Breaking changes**: `major` release
206
- **Reverts**: `patch` release
207
- **Angular convention**:
208
- `feat:` → `minor` release
209
- `fix:` → `patch` release
210
- `perf:` → `patch` release
211
- **Atom convention**: Various emoji-based rules
212
- **Ember convention**: Tag-based rules (`BUGFIX`, `FEATURE`, `SECURITY`)
213
- **ESLint convention**: Tag-based rules (`Breaking`, `Fix`, `Update`, `New`)
214
- **Express convention**: Component-based rules
215
- **JSHint convention**: Type-based rules
216
217
## Error Handling
218
219
The plugin validates configuration and throws descriptive errors for:
220
221
- Invalid `releaseRules` format (must be array)
222
- Missing `release` property in rules
223
- Invalid release types
224
- Missing or invalid conventional-changelog presets
225
226
Common errors:
227
228
```javascript
229
// Invalid releaseRules configuration
230
throw new TypeError('Error in commit-analyzer configuration: "releaseRules" must be an array of rules');
231
232
// Missing release property
233
throw new Error('Error in commit-analyzer configuration: rules must be an object with a "release" property');
234
235
// Invalid release type
236
throw new Error('Error in commit-analyzer configuration: "invalid" is not a valid release type. Valid values are: ["major","premajor","minor","preminor","patch","prepatch","prerelease"]');
237
```
238
239
## Advanced Configuration Examples
240
241
### Custom Release Rules
242
243
```json
244
{
245
"plugins": [
246
[
247
"@semantic-release/commit-analyzer",
248
{
249
"preset": "angular",
250
"releaseRules": [
251
{ "type": "docs", "scope": "README", "release": "patch" },
252
{ "type": "refactor", "scope": "core-*", "release": "minor" },
253
{ "type": "refactor", "release": "patch" },
254
{ "scope": "no-release", "release": false },
255
{ "breaking": true, "release": "major" }
256
]
257
}
258
]
259
]
260
}
261
```
262
263
### Custom Parser Options
264
265
```json
266
{
267
"plugins": [
268
[
269
"@semantic-release/commit-analyzer",
270
{
271
"preset": "angular",
272
"parserOpts": {
273
"noteKeywords": ["BREAKING CHANGE", "BREAKING CHANGES", "BREAKING"],
274
"headerPattern": "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$"
275
}
276
}
277
]
278
]
279
}
280
```
281
282
### Conventionalcommits Preset with PresetConfig
283
284
For presets that require configuration, such as `conventionalcommits`, the `presetConfig` option must be set:
285
286
```json
287
{
288
"plugins": [
289
[
290
"@semantic-release/commit-analyzer",
291
{
292
"preset": "conventionalcommits",
293
"presetConfig": {
294
"types": [
295
{ "type": "feat", "section": "Features" },
296
{ "type": "fix", "section": "Bug Fixes" },
297
{ "type": "docs", "section": "Documentation", "hidden": true }
298
]
299
}
300
}
301
]
302
]
303
}
304
```
305
306
### External Release Rules Module
307
308
```json
309
{
310
"plugins": [
311
[
312
"@semantic-release/commit-analyzer",
313
{
314
"preset": "angular",
315
"releaseRules": "./config/release-rules.js"
316
}
317
]
318
]
319
}
320
```
321
322
Where `./config/release-rules.js` exports:
323
324
```javascript
325
export default [
326
{ type: "feat", release: "minor" },
327
{ type: "fix", release: "patch" },
328
{ type: "docs", release: "patch" },
329
{ scope: "no-release", release: false }
330
];
331
```