Skip to content

Commit e923548

Browse files
committed
feat(cxx): introduce auto release with release notes
1 parent 5e8e301 commit e923548

File tree

2 files changed

+192
-0
lines changed

2 files changed

+192
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: {{ cookiecutter.project_name | title }} Release
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*.*.*"
7+
8+
jobs:
9+
changelog:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout Code
13+
uses: actions/checkout@v4
14+
with:
15+
fetch-depth: 0
16+
17+
- name: Get Tag Version
18+
id: tag_version
19+
run: echo "CURRENT_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
20+
21+
- name: Generate Full Changelog
22+
uses: orhun/git-cliff-action@v4
23+
with:
24+
config: cliff.toml
25+
args: --verbose
26+
env:
27+
OUTPUT: CHANGELOG.md
28+
GITHUB_REPO: {{ "${{ github.repository }}" }}
29+
30+
- name: Commit Changelog
31+
run: |
32+
git config user.name 'github-actions[bot]'
33+
git config user.email 'github-actions[bot]@users.noreply.github.com'
34+
set +e
35+
git switch main
36+
git add CHANGELOG.md
37+
git commit -m "chore(release-bot): prepare for release notes on ${CURRENT_TAG}"
38+
git push
39+
40+
release:
41+
runs-on: ubuntu-latest
42+
steps:
43+
- name: Checkout Code
44+
uses: actions/checkout@v4
45+
with:
46+
fetch-depth: 0
47+
48+
- name: Generate Latest Release Notes
49+
id: latest_release_notes
50+
uses: orhun/git-cliff-action@v4
51+
with:
52+
config: cliff.toml
53+
args: --latest --strip all
54+
env:
55+
OUTPUT: CHANGELOG.txt
56+
57+
- name: Create GitHub Release
58+
uses: softprops/action-gh-release@v2
59+
with:
60+
body_path: CHANGELOG.txt
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
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+
[remote.github]
9+
owner = "{{cookiecutter.github_username}}"
10+
repo = "{{cookiecutter.project_slug}}"
11+
12+
[changelog]
13+
# template for the changelog footer
14+
header = """
15+
# Changelog\n
16+
All notable changes to this project will be documented in this file.\n
17+
"""
18+
# template for the changelog body
19+
# https://keats.github.io/tera/docs/#introduction
20+
{%- raw %}
21+
body = """
22+
{%- macro remote_url() -%}
23+
https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}
24+
{%- endmacro -%}
25+
26+
{% macro print_commit(commit) -%}
27+
- {% if commit.scope %}*({{ commit.scope }})* {% endif %}\
28+
{% if commit.breaking %}[**breaking**] {% endif %}\
29+
{{ commit.message | upper_first }} - \
30+
([{{ commit.id | truncate(length=7, end="") }}]({{ self::remote_url() }}/commit/{{ commit.id }}))\
31+
{% endmacro -%}
32+
33+
{% if version %}\
34+
{% if previous.version %}\
35+
## [{{ version | trim_start_matches(pat="v") }}]\
36+
({{ self::remote_url() }}/compare/{{ previous.version }}..{{ version }}) - {{ timestamp | date(format="%Y-%m-%d") }}
37+
{% else %}\
38+
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
39+
{% endif %}\
40+
{% else %}\
41+
## [unreleased]
42+
{% endif %}\
43+
44+
{% for group, commits in commits | group_by(attribute="group") %}
45+
### {{ group | striptags | trim | upper_first }}
46+
{% for commit in commits
47+
| filter(attribute="scope")
48+
| sort(attribute="scope") %}
49+
{{ self::print_commit(commit=commit) }}
50+
{%- endfor %}
51+
{% for commit in commits %}
52+
{%- if not commit.scope -%}
53+
{{ self::print_commit(commit=commit) }}
54+
{% endif -%}
55+
{% endfor -%}
56+
{% endfor -%}
57+
{%- if github -%}
58+
{% if github.contributors | filter(attribute="is_first_time", value=true) | length != 0 %}
59+
## New Contributors ❤️
60+
{% endif %}\
61+
{% for contributor in github.contributors | filter(attribute="is_first_time", value=true) %}
62+
* @{{ contributor.username }} made their first contribution
63+
{%- if contributor.pr_number %} in \
64+
[#{{ contributor.pr_number }}]({{ self::remote_url() }}/pull/{{ contributor.pr_number }}) \
65+
{%- endif %}
66+
{%- endfor -%}
67+
{%- endif %}
68+
69+
70+
"""
71+
{% endraw %}
72+
# template for the changelog footer
73+
footer = """
74+
<!-- generated by git-cliff -->
75+
"""
76+
# remove the leading and trailing s
77+
trim = true
78+
# postprocessors
79+
postprocessors = [
80+
{ pattern = '<REPO>', replace = "https://github.com/{{cookiecutter.__gh_slug}}" }, # replace repository URL
81+
]
82+
83+
[git]
84+
# parse the commits based on https://www.conventionalcommits.org
85+
conventional_commits = true
86+
# filter out the commits that are not conventional
87+
filter_unconventional = true
88+
# process each line of a commit as an individual commit
89+
split_commits = false
90+
# regex for preprocessing the commit messages
91+
commit_preprocessors = [
92+
# Replace issue numbers
93+
{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/issues/${2}))"},
94+
# Check spelling of the commit with https://github.com/crate-ci/typos
95+
# If the spelling is incorrect, it will be automatically fixed.
96+
#{ pattern = '.*', replace_command = 'typos --write-changes -' },
97+
]
98+
# regex for parsing and grouping commits
99+
commit_parsers = [
100+
{ message = "^feat", group = "<!-- 0 -->🚀 Features" },
101+
{ message = "^fix", group = "<!-- 1 -->🐛 Bug Fixes" },
102+
{ message = "^doc", group = "<!-- 3 -->📚 Documentation" },
103+
{ message = "^perf", group = "<!-- 4 -->⚡ Performance" },
104+
{ message = "^refactor", group = "<!-- 2 -->🚜 Refactor" },
105+
{ message = "^style", group = "<!-- 5 -->🎨 Styling" },
106+
{ message = "^test", group = "<!-- 6 -->🧪 Testing" },
107+
{ message = "^chore\\(release\\): prepare for", skip = true },
108+
{ message = "^chore\\(release-bot\\): prepare for", skip = true },
109+
{ message = "^chore: bump version to", skip = true },
110+
{ message = "^chore\\(deps.*\\)", skip = true },
111+
{ message = "^chore\\(pr\\)", skip = true },
112+
{ message = "^chore\\(pull\\)", skip = true },
113+
{ message = "^chore|^ci", group = "<!-- 7 -->⚙️ Miscellaneous Tasks" },
114+
{ body = ".*security", group = "<!-- 8 -->🛡️ Security" },
115+
{ message = "^revert", group = "<!-- 9 -->◀️ Revert" },
116+
]
117+
# protect breaking changes from being skipped due to matching a skipping commit_parser
118+
protect_breaking_commits = false
119+
# filter out the commits that are not matched by commit parsers
120+
filter_commits = false
121+
# regex for matching git tags
122+
# tag_pattern = "v[0-9].*"
123+
# regex for skipping tags
124+
# skip_tags = ""
125+
# regex for ignoring tags
126+
# ignore_tags = ""
127+
# sort the tags topologically
128+
topo_order = false
129+
# sort the commits inside sections by oldest/newest order
130+
sort_commits = "newest"
131+
# limit the number of commits included in the changelog.
132+
# limit_commits = 42

0 commit comments

Comments
 (0)