Skip to content

Commit b85de7b

Browse files
authored
chore: add release workflow (#194)
* chore: add release workflow Signed-off-by: Patrick Gehrsitz <[email protected]> * chore: fix GITHUB_TOKEN permissions * chore: fix broken commit links * chore: add post- and preprocessing for release workflow * chore: update cliff action version * chore: fix syntax error * chore: fix PR url * chore: bump to actions/checkout v4 --------- Signed-off-by: Patrick Gehrsitz <[email protected]>
1 parent ae2bc21 commit b85de7b

File tree

3 files changed

+257
-0
lines changed

3 files changed

+257
-0
lines changed

.github/workflows/release.yml

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
name: Release
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
type: string
8+
description: New version number in X.Y.Z
9+
required: true
10+
11+
jobs:
12+
update-master-branch:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: everlytic/[email protected]
16+
with:
17+
github_token: ${{ secrets.PAT }}
18+
source_ref: 'develop'
19+
target_branch: 'master'
20+
commit_message_template: '[Automated] Merged {source_ref} into target {target_branch}'
21+
22+
release:
23+
needs: [ 'update-master-branch' ]
24+
runs-on: ubuntu-latest
25+
permissions:
26+
contents: write
27+
steps:
28+
- name: Fetch repo
29+
uses: actions/checkout@v4
30+
with:
31+
ref: 'master'
32+
fetch-depth: 0
33+
34+
- name: Get latest tag
35+
id: latest_tag
36+
shell: bash
37+
run: |
38+
echo "TAG_NAME=$(git describe --tags $(git rev-list --tags --max-count=1))" >> $GITHUB_OUTPUT
39+
- name: Generate a changelog
40+
uses: orhun/git-cliff-action@v2
41+
id: generate-changelog
42+
with:
43+
config: ./cliff-release.toml
44+
args: ${{ steps.latest_tag.outputs.TAG_NAME }}..HEAD
45+
46+
- name: Create release and upload build
47+
uses: softprops/action-gh-release@v1
48+
id: create-release
49+
with:
50+
name: v${{ github.event.inputs.version }}
51+
tag_name: v${{ github.event.inputs.version }}
52+
token: ${{ secrets.GITHUB_TOKEN }}
53+
body: ${{ steps.generate-changelog.outputs.content }}
54+
55+
update-changelog:
56+
needs: [ 'release' ]
57+
name: Generate changelog
58+
runs-on: ubuntu-latest
59+
steps:
60+
- name: Checkout
61+
uses: actions/checkout@v4
62+
with:
63+
ref: 'master'
64+
token: ${{ secrets.PAT }}
65+
fetch-depth: 0
66+
67+
- name: Get latest tag
68+
id: latest_tag
69+
shell: bash
70+
run: |
71+
echo "TAG_NAME=$(git describe --tags $(git rev-list --tags --max-count=1))" >> $GITHUB_OUTPUT
72+
- name: Generate a changelog
73+
uses: orhun/git-cliff-action@v2
74+
id: git-cliff
75+
with:
76+
config: cliff.toml
77+
args: v0.0.0..${{ steps.latest_tag.outputs.TAG_NAME }}
78+
env:
79+
OUTPUT: ${{ github.workspace }}/CHANGELOG.md
80+
81+
- uses: stefanzweifel/git-auto-commit-action@v4
82+
with:
83+
commit_message: 'docs(changelog): update changelog'
84+
file_pattern: CHANGELOG.md
85+
86+
- uses: everlytic/[email protected]
87+
with:
88+
github_token: ${{ secrets.PAT }}
89+
source_ref: 'master'
90+
target_branch: 'develop'
91+
commit_message_template: '[Automated] Merged {source_ref} into target {target_branch}'

cliff-release.toml

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# configuration file for git-cliff (0.1.0)
2+
3+
[changelog]
4+
# changelog header
5+
header = """
6+
# What's Changed
7+
"""
8+
# template for the changelog body
9+
# https://tera.netlify.app/docs/#introduction
10+
body = """
11+
{% for group, commits in commits | group_by(attribute="group") %}\
12+
### {{ group | striptags | trim | upper_first }}
13+
{% for commit in commits
14+
| filter(attribute="scope")
15+
| sort(attribute="scope") %}
16+
- **{{commit.scope}}**: {{ commit.message | upper_first | trim }} | [{{ commit.id | truncate(length=7, end="") }}](<REPO>/commit/{{ commit.id }})\
17+
{%- if commit.breaking %}
18+
{% raw %} {% endraw %}- **BREAKING**: {{commit.breaking_description}}
19+
{%- endif -%}
20+
21+
{%- endfor -%}
22+
{%- for commit in commits %}
23+
{%- if commit.scope -%}
24+
{% else -%}
25+
{% raw %}\n{% endraw %}\
26+
- {{ commit.message | upper_first | trim }} | [{{ commit.id | truncate(length=7, end="") }}](<REPO>/commit/{{ commit.id }})\
27+
{%- if commit.breaking %}
28+
{% raw %} {% endraw %}- **BREAKING**: {{commit.breaking_description}}
29+
{%- endif -%}
30+
31+
{% endif -%}
32+
{% endfor -%}
33+
{% raw %}\n{% endraw %}
34+
{% endfor %}\n\
35+
"""
36+
# remove the leading and trailing whitespaces from the template
37+
trim = true
38+
# changelog footer
39+
footer = """
40+
"""
41+
42+
# postprocessors
43+
postprocessors = [
44+
{ pattern = '(\(<REPO>/pull/[0-9]+\)\)) \| .+', replace = "${1}" },
45+
{ pattern = '<REPO>', replace = "https://github.com/mainsail-crew/crowsnest" }, # replace repository URL
46+
]
47+
48+
[git]
49+
# allow only conventional commits
50+
# https://www.conventionalcommits.org
51+
conventional_commits = true
52+
filter_unconventional = true
53+
# regex for parsing and grouping commits
54+
commit_parsers = [
55+
# Commits to skip
56+
{ message = "^docs\\(changelog\\):", group = "Changelog", skip = true}, # Old redundant commits
57+
{ message = "^chore: push version number to", group = "9$Other", skip = true}, # Old redundant commits
58+
{ message = "^chore\\(changelog\\): update changelog", group = "Changelog", skip = true}, # Old redundant commits
59+
60+
# Commits to parse
61+
{ message = "^feat(\\(.*\\))?:", group = "<!-- 1 -->Features"},
62+
{ message = "^feature(\\(.*\\))?:", group = "<!-- 1 -->Features"},
63+
{ message = "^fix(\\(.*\\))?:", group = "<!-- 2 -->Bug Fixes and Improvements"},
64+
{ message = "^perf(\\(.*\\))?:", group = "<!-- 3 -->Performance"},
65+
{ message = "^refactor(\\(.*\\))?:", group = "<!-- 4 -->Refactor"},
66+
{ message = "^style(\\(.*\\))?:", group = "<!-- 5 -->Styling"},
67+
{ message = "^locale(\\(.*\\))?:", group = "<!-- 6 -->Localization"},
68+
{ message = "^docs(\\(.*\\))?:", group = "<!-- 7 -->Documentation"},
69+
{ message = "^test(\\(.*\\))?:", group = "<!-- 8 -->Other"},
70+
{ message = "^chore(\\(.*\\))?:", group = "<!-- 8 -->Other"},
71+
{ body = ".*security", group = "Security"},
72+
]
73+
commit_preprocessors = [
74+
{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/pull/${2}))" },
75+
]
76+
# filter out the commits that are not matched by commit parsers
77+
filter_commits = true
78+
ignore_tags="v*-(beta|rc)*"
79+
# glob pattern for matching git tags
80+
tag_pattern = "v[0-9]*"

cliff.toml

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# configuration file for git-cliff (0.1.0)
2+
3+
[changelog]
4+
# changelog header
5+
header = """
6+
<!-- THIS FILE IS UPDATED AUTOMATICALLY, ANY CHANGES WILL BE OVERRIDDEN -->
7+
# Changelog
8+
All notable changes to Crowsnest will be documented in this file.\n
9+
"""
10+
# template for the changelog body
11+
# https://tera.netlify.app/docs/#introduction
12+
body = """
13+
{% if version %}\
14+
## [{{ version | trim_start_matches(pat="v") }}](https://github.com/mainsail-crew/crowsnest/releases/tag/{{version}}) - {{ timestamp | date(format="%Y-%m-%d") }}
15+
\
16+
{% else %}\
17+
## [unreleased]
18+
{% endif %}\
19+
{% for group, commits in commits | group_by(attribute="group") %}\
20+
### {{ group | striptags | trim | upper_first }}
21+
{% for commit in commits
22+
| filter(attribute="scope")
23+
| sort(attribute="scope") %}
24+
- **{{commit.scope}}**: {{ commit.message | upper_first | trim }} | [{{ commit.id | truncate(length=7, end="") }}](<REPO>/commit/{{ commit.id }})\
25+
{%- if commit.breaking %}
26+
{% raw %} {% endraw %}- **BREAKING**: {{commit.breaking_description}}
27+
{%- endif -%}
28+
{%- endfor -%}
29+
{%- for commit in commits %}
30+
{%- if commit.scope -%}
31+
{% else -%}
32+
{% raw %}\n{% endraw %}\
33+
- {{ commit.message | upper_first | trim }} | [{{ commit.id | truncate(length=7, end="") }}](<REPO>/commit/{{ commit.id }})\
34+
{%- if commit.breaking %}
35+
{% raw %} {% endraw %}- **BREAKING**: {{commit.breaking_description}}
36+
{%- endif -%}
37+
{% endif -%}
38+
{% endfor -%}
39+
{% raw %}\n{% endraw %}
40+
{% endfor %}\n\
41+
"""
42+
# remove the leading and trailing whitespaces from the template
43+
trim = true
44+
# changelog footer
45+
footer = """
46+
"""
47+
48+
# postprocessors
49+
postprocessors = [
50+
{ pattern = '(\(<REPO>/pull/[0-9]+\)\)) \| .+', replace = "${1}" },
51+
{ pattern = '<REPO>', replace = "https://github.com/mainsail-crew/crowsnest" }, # replace repository URL
52+
]
53+
54+
[git]
55+
# allow only conventional commits
56+
# https://www.conventionalcommits.org
57+
conventional_commits = true
58+
filter_unconventional = false
59+
# regex for parsing and grouping commits
60+
commit_parsers = [
61+
# Commits to skip
62+
{ message = "^docs\\(changelog\\):", group = "Changelog", skip = true}, # Old redundant commits
63+
{ message = "^chore: push version number to", group = "9$Other", skip = true}, # Old redundant commits
64+
{ message = "^chore\\(changelog\\): update changelog", group = "Changelog", skip = true}, # Old redundant commits
65+
66+
# Commits to parse
67+
{ message = "^feat(\\(.*\\))?:", group = "<!-- 1 -->Features"},
68+
{ message = "^feature(\\(.*\\))?:", group = "<!-- 1 -->Features"},
69+
{ message = "^fix(\\(.*\\))?:", group = "<!-- 2 -->Bug Fixes and Improvements"},
70+
{ message = "^perf(\\(.*\\))?:", group = "<!-- 3 -->Performance"},
71+
{ message = "^refactor(\\(.*\\))?:", group = "<!-- 4 -->Refactor"},
72+
{ message = "^style(\\(.*\\))?:", group = "<!-- 5 -->Styling"},
73+
{ message = "^locale(\\(.*\\))?:", group = "<!-- 6 -->Localization"},
74+
{ message = "^docs(\\(.*\\))?:", group = "<!-- 7 -->Documentation"},
75+
{ message = "^test(\\(.*\\))?:", group = "<!-- 8 -->Other"},
76+
{ message = "^chore(\\(.*\\))?:", group = "<!-- 8 -->Other"},
77+
{ body = ".*security", group = "Security"},
78+
]
79+
commit_preprocessors = [
80+
{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/pull/${2}))" },
81+
]
82+
# filter out the commits that are not matched by commit parsers
83+
filter_commits = true
84+
ignore_tags="v*-(beta|rc)*"
85+
# glob pattern for matching git tags
86+
tag_pattern = "v[0-9]*"

0 commit comments

Comments
 (0)