Skip to content

Commit 5c7674e

Browse files
Mlaz-codeclaude
andcommitted
ci: add git-cliff changelog generation to prod deploy pipeline
Creates a GitHub Release with a categorized changelog after each successful production deploy, using date-based version tags. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent ea896a8 commit 5c7674e

2 files changed

Lines changed: 99 additions & 0 deletions

File tree

.github/workflows/deploy-prod.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,47 @@ jobs:
129129
echo "## Rollback" >> $GITHUB_STEP_SUMMARY
130130
echo "**Promoted**: ${{ steps.target.outputs.target_url }}" >> $GITHUB_STEP_SUMMARY
131131
132+
changelog:
133+
name: Changelog & Release
134+
needs: deploy-production
135+
runs-on: ubuntu-latest
136+
timeout-minutes: 5
137+
if: inputs.dry_run != true && inputs.rollback != true
138+
permissions:
139+
contents: write
140+
steps:
141+
- uses: actions/checkout@v5
142+
with:
143+
fetch-depth: 0
144+
145+
- name: Determine version tag
146+
id: version
147+
run: |
148+
TAG="v$(date -u +%Y.%m.%d)"
149+
# Append run number suffix if tag already exists
150+
if git rev-parse "$TAG" >/dev/null 2>&1; then
151+
TAG="${TAG}.${{ github.run_number }}"
152+
fi
153+
echo "tag=$TAG" >> $GITHUB_OUTPUT
154+
155+
- name: Generate changelog
156+
uses: orhun/git-cliff-action@v4
157+
id: cliff
158+
with:
159+
config: cliff.toml
160+
args: --latest --strip header
161+
env:
162+
OUTPUT: CHANGES.md
163+
GITHUB_REPO: ${{ github.repository }}
164+
165+
- name: Create GitHub Release
166+
uses: softprops/action-gh-release@v2
167+
with:
168+
tag_name: ${{ steps.version.outputs.tag }}
169+
name: ${{ steps.version.outputs.tag }}
170+
body: ${{ steps.cliff.outputs.content }}
171+
generate_release_notes: false
172+
132173
health-check:
133174
name: Health Check
134175
needs: deploy-production

cliff.toml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# git-cliff configuration — https://git-cliff.org/docs/configuration
2+
3+
[changelog]
4+
header = """
5+
# Changelog\n
6+
"""
7+
body = """
8+
{%- macro remote_url() -%}
9+
https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}
10+
{%- endmacro -%}
11+
12+
{% if version -%}
13+
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
14+
{% else -%}
15+
## [Unreleased]
16+
{% endif -%}
17+
18+
{% for group, commits in commits | group_by(attribute="group") %}
19+
### {{ group | striptags | trim | upper_first }}
20+
{% for commit in commits %}
21+
- {% if commit.scope %}**{{ commit.scope }}**: {% endif %}{{ commit.message | upper_first }}\
22+
{% if commit.github.username %} by @{{ commit.github.username }}{%- endif -%}
23+
{% if commit.github.pr_number %} in \
24+
[#{{ commit.github.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.github.pr_number }}) \
25+
{%- endif -%}
26+
{% endfor %}
27+
{% endfor %}
28+
"""
29+
trim = true
30+
footer = ""
31+
postprocessors = [
32+
{ pattern = '\$REPO', replace = "https://github.com/sharpapi/docs.sharpapi.io" },
33+
]
34+
35+
[git]
36+
conventional_commits = true
37+
filter_unconventional = false
38+
split_commits = false
39+
commit_parsers = [
40+
{ message = "^feat", group = "Features" },
41+
{ message = "^fix", group = "Bug Fixes" },
42+
{ message = "^docs", group = "Documentation" },
43+
{ message = "^seo", group = "SEO" },
44+
{ message = "^perf", group = "Performance" },
45+
{ message = "^refactor", group = "Refactoring" },
46+
{ message = "^style", group = "Styling" },
47+
{ message = "^ci", group = "CI/CD" },
48+
{ message = "^chore", group = "Miscellaneous" },
49+
{ message = "^build", group = "Build" },
50+
]
51+
protect_breaking_commits = false
52+
filter_commits = false
53+
topo_order = false
54+
sort_commits = "newest"
55+
56+
[remote.github]
57+
owner = "sharpapi"
58+
repo = "docs.sharpapi.io"

0 commit comments

Comments
 (0)