Skip to content

Commit a74a867

Browse files
committed
docs: the complete guide to conventional commits
1 parent 2ddcec5 commit a74a867

File tree

9 files changed

+385
-0
lines changed

9 files changed

+385
-0
lines changed

GUIDE.md

Lines changed: 380 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,380 @@
1+
# How to setup Conventional Commits in JavaScript project
2+
3+
[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) is a specification for adding human and machine readable meaning to commit messages. It provides an easy set of rules for creating an explicit commit history, which makes it easier to write automated tools on top of.
4+
5+
<p align="center">
6+
<img src="assets/commits.png" alt="Commits History" width="800px">
7+
</p>
8+
9+
## Basic Structure
10+
11+
The commit message should be structured as follows:
12+
13+
```
14+
<type>[optional scope]: <description>
15+
16+
[optional body]
17+
18+
[optional footer(s)]
19+
```
20+
21+
Examples:
22+
23+
```bash
24+
# Feature addition
25+
feat: add user authentication
26+
27+
# Bug fix
28+
fix: resolve login redirect issue
29+
30+
# Breaking change
31+
feat!: migrate to new API endpoint
32+
33+
# Also breaking change
34+
feat: add new payment method
35+
36+
BREAKING CHANGE: migrate to new payment gateway
37+
38+
# With scope
39+
feat(auth): add password reset functionality
40+
41+
# With body and footer
42+
fix: prevent racing of requests
43+
44+
Introduce a request id and a reference to latest request. Dismiss
45+
incoming responses other than from latest request.
46+
47+
Closes #123
48+
```
49+
50+
## Common Types
51+
52+
- **feat**: A new feature
53+
- **fix**: A bug fix
54+
- **docs**: Documentation changes
55+
- **style**: Code style changes (formatting, missing semicolons, etc.)
56+
- **refactor**: Code refactoring without changing functionality
57+
- **test**: Adding or updating tests
58+
- **chore**: Maintenance tasks, dependency updates
59+
60+
## Benefits of Conventional Commits
61+
62+
### 1. Automatic Version Determination
63+
64+
Conventional commits enable automatic semantic versioning:
65+
- **feat**: triggers a minor version bump (1.0.0 → 1.1.0)
66+
- **fix**: triggers a patch version bump (1.0.0 → 1.0.1)
67+
- **BREAKING CHANGE**: triggers a major version bump (1.0.0 → 2.0.0)
68+
69+
### 2. Automatic Changelog Generation
70+
71+
Tools can automatically generate changelogs by parsing commit messages, grouping them by type, and extracting relevant information.
72+
73+
<p align="center">
74+
<img src="assets/changelog.png" alt="Changelog Example" width="800px">
75+
</p>
76+
77+
### 3. Better Project History
78+
79+
Conventional commits create a more readable and searchable project history, making it easier to understand what changes were made and why.
80+
81+
## Setting Up Full Automation
82+
83+
To achieve complete automation of versioning and releases, you'll need several tools working together. Let's set them up step by step.
84+
85+
### 1. Commitlint
86+
87+
While not mandatory, [Commitlint](https://github.com/conventional-changelog/commitlint) helps enforce conventional commit standards by linting commit messages.
88+
89+
First, install Commitlint and the Conventional Commits plugin:
90+
91+
```bash
92+
npm install --save-dev @commitlint/cli @commitlint/config-conventional
93+
```
94+
95+
Then you need to set up a configuration.
96+
97+
#### Simple Project Configuration
98+
99+
For a basic project, create `.commitlintrc.json`:
100+
101+
```json
102+
{
103+
"extends": ["@commitlint/config-conventional"]
104+
}
105+
```
106+
107+
##### Git Hook
108+
109+
Now you can set up commit validation during `git commit`, for example using [simple-git-hooks](https://github.com/toplenboren/simple-git-hooks), though there are other similar tools available ([husky](https://github.com/typicode/husky), [pre-commit](https://github.com/observing/pre-commit), etc.).
110+
111+
Install simple-git-hooks:
112+
113+
```bash
114+
npm install --save-dev simple-git-hooks
115+
```
116+
117+
Create `.simple-git-hooks.json`:
118+
119+
```json
120+
{
121+
"commit-msg": "npx commitlint --edit \"$1\""
122+
}
123+
```
124+
125+
Now run `npx simple-git-hooks` to activate the hooks and you're ready to go!
126+
127+
##### GitHub Action
128+
129+
You can also set up commit linting via GitHub Actions when commits are pushed to the repository.
130+
131+
Create `.github/workflows/commit.yml`:
132+
133+
```yaml
134+
name: Commit Validation
135+
136+
on:
137+
pull_request:
138+
types: [opened, synchronize]
139+
140+
jobs:
141+
commitlint:
142+
runs-on: ubuntu-latest
143+
steps:
144+
- uses: actions/checkout@v4
145+
with:
146+
fetch-depth: 0
147+
148+
- name: Setup Node.js
149+
uses: actions/setup-node@v4
150+
with:
151+
node-version: '18'
152+
cache: 'npm'
153+
154+
- name: Install dependencies
155+
run: npm ci
156+
157+
- name: Validate commit messages
158+
run: npx commitlint --from=HEAD~1
159+
```
160+
161+
#### Monorepo Project Configuration
162+
163+
In monorepos, it's common practice to use scopes in Conventional Commits that correspond to workspace names in the monorepo. This helps identify which workspace(s) are affected by each commit. For example:
164+
165+
```bash
166+
feat(store): add user authentication state
167+
fix(ui): resolve button styling issue
168+
docs(router): update routing configuration guide
169+
```
170+
171+
You can use specialized packages to automatically get project scopes:
172+
173+
- [@commitlint/config-workspace-scopes](https://github.com/conventional-changelog/commitlint/tree/master/@commitlint/config-workspace-scopes) - for generic workspaces
174+
- [@commitlint/config-pnpm-scopes](https://github.com/conventional-changelog/commitlint/tree/master/@commitlint/config-pnpm-scopes) - for pnpm workspaces
175+
- [@commitlint/config-lerna-scopes](https://github.com/conventional-changelog/commitlint/tree/master/@commitlint/config-lerna-scopes) - for Lerna projects
176+
177+
Let's look at an example for pnpm workspaces:
178+
179+
Install the packages:
180+
181+
```bash
182+
pnpm add -D @commitlint/cli @commitlint/config-conventional @commitlint/config-pnpm-scopes
183+
```
184+
185+
Create `.commitlintrc.js`:
186+
187+
```javascript
188+
import scopes from '@commitlint/config-pnpm-scopes'
189+
190+
export default {
191+
extends: ['@commitlint/config-conventional', '@commitlint/config-pnpm-scopes'],
192+
rules: {
193+
'scope-enum': async (ctx) => {
194+
const scopeEnum = await scopes.rules['scope-enum'](ctx)
195+
return [
196+
scopeEnum[0],
197+
scopeEnum[1],
198+
[
199+
...scopeEnum[2],
200+
'deps', // for Dependabot or Renovate - dependency updates
201+
'dev-deps', // for Dependabot or Renovate - dev dependency updates
202+
'release' // for release commits
203+
]
204+
]
205+
}
206+
},
207+
prompt: {
208+
settings: {
209+
enableMultipleScopes: true
210+
}
211+
}
212+
}
213+
```
214+
215+
### 2. Commitizen
216+
217+
[Commitizen](https://github.com/commitizen/cz-cli) is an optional but very convenient tool that provides an interactive CLI for creating Conventional Commits.
218+
219+
<p align="center">
220+
<img src="assets/commitizen.gif" alt="Commitizen CLI Usage Example" width="800px">
221+
</p>
222+
223+
First, install Commitizen and the Commitlint adapter:
224+
225+
```bash
226+
npm install --save-dev commitizen @commitlint/cz-commitlint
227+
```
228+
229+
Then create `.czrc`:
230+
231+
```json
232+
{
233+
"path": "@commitlint/cz-commitlint"
234+
}
235+
```
236+
237+
Add a script to `package.json`:
238+
239+
```json
240+
{
241+
"scripts": {
242+
"commit": "cz"
243+
}
244+
}
245+
```
246+
247+
Now you can use `npm run commit` instead of `git commit` for interactive commit creation.
248+
249+
### 3. Simple Release Action
250+
251+
The [simple-release-action](https://github.com/marketplace/actions/simple-release-action) is a comprehensive GitHub Action that automates version updates, changelog generation, and releases. The project is based on [simple-release](https://github.com/TrigenSoftware/simple-release) and [conventional-changelog](https://github.com/conventional-changelog/conventional-changelog).
252+
253+
> [!NOTE]
254+
> If you are not using GitHub, you can write your own custom CI script using the [@simple-release/core](https://github.com/TrigenSoftware/simple-release/tree/main/packages/core) package.
255+
256+
Key Features:
257+
258+
- **First-class monorepo support** - A major differentiator from alternatives
259+
- **Automatic version bumping** based on Conventional Commits
260+
- **Changelog generation** with proper categorization
261+
- **Git tagging and GitHub releases**
262+
- **Configuration through adapters** for different project types
263+
264+
Currently npm and pnpm projects with workspaces are supported ([npm adapter](https://github.com/TrigenSoftware/simple-release/blob/main/packages/npm#readme), [pnpm adapter](https://github.com/TrigenSoftware/simple-release/blob/main/packages/pnpm#readme)).
265+
266+
Let's look at an example of configuring the action for a project with pnpm workspaces using [@simple-release/pnpm](https://github.com/TrigenSoftware/simple-release/blob/main/packages/pnpm#readme) addon:
267+
268+
Create `.simple-release.json` config file in repository root:
269+
270+
```json
271+
{
272+
"project": ["@simple-release/pnpm#PnpmWorkspacesProject", {
273+
"mode": "fixed"
274+
}],
275+
"bump": {
276+
"extraScopes": ["deps"]
277+
}
278+
}
279+
```
280+
281+
*`extraScopes` is used to trigger version bump by commits like `fix(deps): ...` from Dependabot or Renovate.*
282+
283+
Create `.github/workflows/release.yml`:
284+
285+
```yaml
286+
name: Release
287+
288+
on:
289+
issue_comment:
290+
types: [created, deleted]
291+
push:
292+
branches:
293+
- main
294+
295+
jobs:
296+
check:
297+
runs-on: ubuntu-latest
298+
name: Context check
299+
outputs:
300+
continue: ${{ steps.check.outputs.continue }}
301+
workflow: ${{ steps.check.outputs.workflow }}
302+
steps:
303+
- name: Checkout the repository
304+
uses: actions/checkout@v4
305+
- name: Context check
306+
id: check
307+
uses: TrigenSoftware/simple-release-action@v1
308+
with:
309+
workflow: check
310+
github-token: ${{ secrets.GITHUB_TOKEN }}
311+
312+
pull-request:
313+
runs-on: ubuntu-latest
314+
name: Pull request
315+
needs: check
316+
if: needs.check.outputs.workflow == 'pull-request'
317+
steps:
318+
- name: Checkout the repository
319+
uses: actions/checkout@v4
320+
- name: Create or update pull request
321+
uses: TrigenSoftware/simple-release-action@v1
322+
with:
323+
workflow: pull-request
324+
github-token: ${{ secrets.GITHUB_TOKEN }}
325+
326+
release:
327+
runs-on: ubuntu-latest
328+
name: Release
329+
needs: check
330+
if: needs.check.outputs.workflow == 'release'
331+
steps:
332+
- name: Checkout the repository
333+
uses: actions/checkout@v4
334+
- name: Install pnpm
335+
uses: pnpm/action-setup@v2
336+
with:
337+
version: 10
338+
- name: Install Node.js
339+
uses: actions/setup-node@v4
340+
with:
341+
node-version: 18
342+
cache: 'pnpm'
343+
registry-url: 'https://registry.npmjs.org'
344+
- name: Install dependencies
345+
run: pnpm install
346+
- name: Release
347+
uses: TrigenSoftware/simple-release-action@v1
348+
with:
349+
workflow: release
350+
github-token: ${{ secrets.GITHUB_TOKEN }}
351+
npm-token: ${{ secrets.NPM_TOKEN }}
352+
```
353+
354+
This workflow consists of three jobs:
355+
- **check** - performs context check to determine if release changes are needed and which workflow to run
356+
- **pull-request** - creates or updates a pull request with release changes
357+
- **release** - performs the actual release when the PR is merged
358+
359+
Every time you push to the main branch, the action will create or update a pull request with a version bump and updated changelog if necessary.
360+
361+
<p align="center">
362+
<img src="assets/pr.png" alt="Simple Release Action Pull Request Example" width="800px">
363+
</p>
364+
365+
When the pull request is merged, it will automatically release the project.
366+
367+
<p align="center">
368+
<img src="assets/release.png" alt="Simple Release Action Release Example" width="800px">
369+
</p>
370+
371+
## Conclusion
372+
373+
There is also a recommendation to use squash merge for pull requests to keep the commit history in the main branch clean and well-structured. This ensures that each merge commit follows conventional commit standards and makes the project history more readable.
374+
375+
By implementing Conventional Commits with this toolchain, you'll have a fully automated release pipeline that maintains consistency, improves project history readability, and reduces manual overhead in version management.
376+
377+
If you want to see real projects using Conventional Commits and their configurations, here are a few examples:
378+
- [browserslist-useragent-regexp](https://github.com/browserslist/browserslist-useragent-regexp)
379+
- [conventional-changelog](https://github.com/conventional-changelog/conventional-changelog)
380+
- [simple-release](https://github.com/TrigenSoftware/simple-release)

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ A simple tool to automate version bumps, changelogs, and releases using [Convent
1616
- 🧩 Flexible and extensible with custom addons for different project types.
1717
- 🚀 Has [GitHub Action](https://github.com/TrigenSoftware/simple-release-action) to automate releases in CI/CD pipelines.
1818

19+
> [!TIP]
20+
> New to Сonventional Сommits? [Check out The Complete Guide](./GUIDE.md).
21+
1922
## Available packages
2023

2124
| Name | Description | Version | Dependencies |

assets/changelog.png

283 KB
Loading

assets/commitizen.gif

863 KB
Loading

assets/commits.png

305 KB
Loading

assets/diff.png

885 KB
Loading

assets/pr.png

455 KB
Loading

assets/release.png

162 KB
Loading

packages/core/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ A simple tool to automate version bumps, changelogs, and releases using [Convent
3636
- 🧩 Flexible and extensible with custom addons for different project types.
3737
- 🚀 Has [GitHub Action](https://github.com/TrigenSoftware/simple-release-action) to automate releases in CI/CD pipelines.
3838

39+
*New to Сonventional Сommits? [Check out The Complete Guide](https://github.com/TrigenSoftware/simple-release/blob/main/GUIDE.md).*
40+
3941
<hr />
4042
<a href="#install">Install</a>
4143
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>

0 commit comments

Comments
 (0)