Skip to content

Commit 1d4f057

Browse files
committed
feat(changelog): Add git cliff for automatic changelog generation
1 parent f0c10b5 commit 1d4f057

File tree

2 files changed

+124
-0
lines changed

2 files changed

+124
-0
lines changed

.github/workflows/changelog.yml

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: Changelog
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
workflow_dispatch:
9+
10+
permissions:
11+
contents: write
12+
13+
jobs:
14+
changelog:
15+
name: Generate changelog
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Checkout
19+
uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 0
22+
23+
- name: Generate changelog
24+
uses: orhun/git-cliff-action@v4
25+
id: git-cliff
26+
with:
27+
config: cliff.toml
28+
args: --verbose
29+
env:
30+
OUTPUT: CHANGELOG.md
31+
GITHUB_REPO: ${{ github.repository }}
32+
33+
- name: Commit changes
34+
run: |
35+
git config user.name 'github-actions[bot]'
36+
git config user.email 'github-actions[bot]@users.noreply.github.com'
37+
git checkout -b git-cliff
38+
git add CHANGELOG.md
39+
git commit -m "docs: update changelog"
40+
git push -f https://${{ secrets.GITHUB_TOKEN }}@github.com/${GITHUB_REPOSITORY}.git git-cliff

cliff.toml

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# git-cliff ~ default configuration file
2+
# https://git-cliff.org/docs/configuration
3+
#
4+
# Lines starting with "#" are comments.
5+
# Configuration options are organized into tables and keys.
6+
# See documentation for more information on available options.
7+
8+
[changelog]
9+
# template for the changelog header
10+
header = """
11+
# Changelog\n
12+
All notable changes to this project will be documented in this file.\n
13+
"""
14+
# template for the changelog body
15+
# https://keats.github.io/tera/docs/#introduction
16+
body = """
17+
{% if version %}\
18+
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
19+
{% else %}\
20+
## [unreleased]
21+
{% endif %}\
22+
{% for group, commits in commits | group_by(attribute="group") %}
23+
### {{ group | striptags | trim | upper_first }}
24+
{% for commit in commits %}
25+
- {% if commit.scope %}*({{ commit.scope }})* {% endif %}\
26+
{% if commit.breaking %}[**breaking**] {% endif %}\
27+
{{ commit.message | upper_first }}\
28+
{% endfor %}
29+
{% endfor %}\n
30+
"""
31+
# template for the changelog footer
32+
footer = """
33+
<!-- generated by git-cliff -->
34+
"""
35+
# remove the leading and trailing s
36+
trim = true
37+
# postprocessors
38+
postprocessors = [
39+
# { pattern = '<REPO>', replace = "https://github.com/orhun/git-cliff" }, # replace repository URL
40+
]
41+
# render body even when there are no releases to process
42+
# render_always = true
43+
# output file path
44+
# output = "test.md"
45+
46+
[git]
47+
# parse the commits based on https://www.conventionalcommits.org
48+
conventional_commits = true
49+
# filter out the commits that are not conventional
50+
filter_unconventional = true
51+
# process each line of a commit as an individual commit
52+
split_commits = false
53+
# regex for preprocessing the commit messages
54+
commit_preprocessors = [
55+
# Replace issue numbers
56+
#{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/issues/${2}))"},
57+
# Check spelling of the commit with https://github.com/crate-ci/typos
58+
# If the spelling is incorrect, it will be automatically fixed.
59+
#{ pattern = '.*', replace_command = 'typos --write-changes -' },
60+
]
61+
# regex for parsing and grouping commits
62+
commit_parsers = [
63+
{ message = "^feat", group = "<!-- 0 -->🚀 Features" },
64+
{ message = "^fix", group = "<!-- 1 -->🐛 Bug Fixes" },
65+
{ message = "^doc", group = "<!-- 3 -->📚 Documentation" },
66+
{ message = "^perf", group = "<!-- 4 -->⚡ Performance" },
67+
{ message = "^refactor", group = "<!-- 2 -->🚜 Refactor" },
68+
{ message = "^style", group = "<!-- 5 -->🎨 Styling" },
69+
{ message = "^test", group = "<!-- 6 -->🧪 Testing" },
70+
{ message = "^chore\\(release\\): prepare for", skip = true },
71+
{ message = "^chore\\(deps.*\\)", skip = true },
72+
{ message = "^chore\\(pr\\)", skip = true },
73+
{ message = "^chore\\(pull\\)", skip = true },
74+
{ message = "^chore|^ci", group = "<!-- 7 -->⚙️ Miscellaneous Tasks" },
75+
{ body = ".*security", group = "<!-- 8 -->🛡️ Security" },
76+
{ message = "^revert", group = "<!-- 9 -->◀️ Revert" },
77+
{ message = ".*", group = "<!-- 10 -->💼 Other" },
78+
]
79+
# filter out the commits that are not matched by commit parsers
80+
filter_commits = false
81+
# sort the tags topologically
82+
topo_order = false
83+
# sort the commits inside sections by oldest/newest order
84+
sort_commits = "oldest"

0 commit comments

Comments
 (0)