Skip to content

Commit 35383d6

Browse files
authored
refactor: Rework changelog formatting in git-cliff-release action (#135)
* Rework changelog formatting in git-cliff-release action * Add print * Missing --context
1 parent 0598248 commit 35383d6

File tree

6 files changed

+129
-76
lines changed

6 files changed

+129
-76
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
.DS_Store
22
.idea
33
.vscode
4+
.venv
5+
.mise.toml

git-cliff-release/action.yaml

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,13 @@ runs:
8686
GIT_CLIFF_WORKDIR: ${{ github.action_path }}
8787
GITHUB_REPO: ${{ github.repository }}
8888
GH_TOKEN: ${{ github.token }}
89+
working-directory: ${{ github.action_path }}
8990
run: |
9091
echo 'release_notes<<EOF' >> $GITHUB_OUTPUT
91-
git-cliff --tag "${{ steps.version_number.outputs.tag_name }}" --unreleased --strip all | tee -a $GITHUB_OUTPUT
92+
git-cliff --tag "${{ steps.version_number.outputs.tag_name }}" --unreleased --context |
93+
python enhance_context.py --repo $GITHUB_REPO --release-notes |
94+
git-cliff --from-context - --strip all |
95+
tee -a $GITHUB_OUTPUT
9296
echo 'EOF' >> $GITHUB_OUTPUT
9397
- name: Generate changelog
9498
id: changelog
@@ -99,14 +103,19 @@ runs:
99103
GIT_CLIFF_WORKDIR: ${{ github.action_path }}
100104
GITHUB_REPO: ${{ github.repository }}
101105
GH_TOKEN: ${{ github.token }}
106+
working-directory: ${{ github.action_path }}
102107
run: |
103108
if [[ ${{ inputs.release_type }} = prerelease ]]; then
104109
echo 'changelog<<EOF' >> $GITHUB_OUTPUT
105-
git-cliff --with-tag-message "${{ steps.version_number.outputs.tag_name }}" >> $GITHUB_OUTPUT
110+
git-cliff --context |
111+
python enhance_context.py --repo $GITHUB_REPO --unreleased-version "${{ steps.version_number.outputs.tag_name }}" |
112+
git-cliff --from-context - >> $GITHUB_OUTPUT
106113
echo 'EOF' >> $GITHUB_OUTPUT
107114
else
108115
echo 'changelog<<EOF' >> $GITHUB_OUTPUT
109-
git-cliff --tag "${{ steps.version_number.outputs.tag_name }}" >> $GITHUB_OUTPUT
116+
git-cliff --tag "${{ steps.version_number.outputs.tag_name }}" --context |
117+
python enhance_context.py --repo $GITHUB_REPO |
118+
git-cliff --from-context - >> $GITHUB_OUTPUT
110119
echo 'EOF' >> $GITHUB_OUTPUT
111120
fi
112121
- name: Clean up

git-cliff-release/cliff.toml

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ All notable changes to this project will be documented in this file.\n
1414
# template for the changelog body
1515
# https://keats.github.io/tera/docs/#introduction
1616
body = """
17-
{% if version %}\
18-
## [{{ version | trim_start_matches(pat="v") }}](<REPO>/releases/tag/{{ version }}) ({{ timestamp | date(format="%Y-%m-%d") }})
19-
{% elif message %}\
20-
## {{ message | trim_start_matches(pat="v") }} - **not yet released**
17+
{% if version and extra.release_link %}\
18+
## [{{ version | trim_start_matches(pat="v") }}]({{ extra.release_link }}) ({{ timestamp | date(format="%Y-%m-%d") }})
19+
{% elif extra.unreleased_version %}\
20+
## {{ extra.unreleased_version | trim_start_matches(pat="v") }} - **not yet released**
21+
{% elif version %}
22+
## {{ version | trim_start_matches(pat="v") }}
2123
{% else %}\
2224
## unreleased
2325
{% endif %}\
@@ -26,8 +28,17 @@ body = """
2628
{% for commit in commits %}
2729
- {% if commit.scope %}*({{ commit.scope }})* {% endif %}\
2830
{% if commit.breaking %}[**breaking**] {% endif %}\
29-
{{ commit.message | upper_first }} ([{{ commit.id | truncate(length = 7, end = "") }}](<REPO>/commit/{{ commit.id }}))\
30-
{% if commit.remote.username %} by [@{{ commit.remote.username }}](https://github.com/{{ commit.remote.username }}){%- endif %}\
31+
{% if commit.extra.pr_link %}\
32+
{{ commit.message | upper_first | replace(from=commit.extra.raw_pr_link, to=commit.extra.pr_link) }}\
33+
{% else %}\
34+
{{ commit.message | upper_first }}\
35+
{% endif %}\
36+
{{" "}}([{{ commit.id | truncate(length = 7, end = "") }}]({{ commit.extra.commit_link }}))\
37+
{% if commit.remote.username and extra.is_release_notes %}\
38+
{{" "}}by @{{ commit.remote.username }}\
39+
{% elif commit.remote.username %}\
40+
{{" "}}by [@{{ commit.remote.username }}](https://github.com/{{ commit.remote.username }})\
41+
{%- endif %}\
3142
{% endfor %}
3243
{% endfor %}\n
3344
"""
@@ -38,9 +49,7 @@ footer = """
3849
# remove the leading and trailing s
3950
trim = true
4051
# postprocessors
41-
postprocessors = [
42-
{ pattern = '<REPO>', replace_command = 'sed "s^<REPO>^https://github.com/$GITHUB_REPO^g"' }, # replace repository URL
43-
]
52+
postprocessors = []
4453

4554
[bump]
4655
# With 0.x.y version, breaking commits should only increase the minor version and feature commits should only increase the patch version
@@ -55,13 +64,7 @@ filter_unconventional = true
5564
# process each line of a commit as an individual commit
5665
split_commits = false
5766
# regex for preprocessing the commit messages
58-
commit_preprocessors = [
59-
# Replace PR and issue numbers in commit messages
60-
{ pattern = '.*', replace_command = 'python $GIT_CLIFF_WORKDIR/preprocess_commit_message.py'},
61-
# Check spelling of the commit with https://github.com/crate-ci/typos
62-
# If the spelling is incorrect, it will be automatically fixed.
63-
#{ pattern = '.*', replace_command = 'typos --write-changes -' },
64-
]
67+
commit_preprocessors = []
6568
# regex for parsing and grouping commits
6669
commit_parsers = [
6770
{ message = "^feat", group = "<!-- 0 -->🚀 Features" },
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
from __future__ import annotations
2+
3+
from argparse import ArgumentParser, BooleanOptionalAction
4+
import json
5+
import subprocess
6+
import sys
7+
from pathlib import Path
8+
from typing import Any
9+
10+
11+
def load_pr_issues(owner: str, repo: str) -> dict[int, list[int]]:
12+
output = subprocess.check_output(
13+
[
14+
str(Path(__file__).parent / "fetch_pr_issues.sh"),
15+
owner,
16+
repo,
17+
]
18+
)
19+
20+
try:
21+
pr_issues = json.loads(output)
22+
except ValueError:
23+
print(f"fetch_pr_issues.sh output: {output}")
24+
raise
25+
26+
return {int(key): value for key, value in pr_issues.items()}
27+
28+
29+
def enhance_release(
30+
release: dict[str, Any], is_release_notes: bool, unreleased_version: str | None
31+
) -> None:
32+
release["extra"] = release["extra"] or {}
33+
release["extra"]["is_release_notes"] = is_release_notes
34+
35+
if release["version"]:
36+
release["extra"]["release_link"] = (
37+
f"{repo_url}/releases/tags/{release['version']}"
38+
)
39+
elif unreleased_version:
40+
release["extra"]["unreleased_version"] = unreleased_version
41+
42+
43+
def enhance_commit(commit: dict[str, Any], pr_issues: dict[int, list[int]]) -> None:
44+
pr_number = commit["remote"]["pr_number"]
45+
46+
commit["extra"] = commit["extra"] or {}
47+
commit["extra"]["commit_link"] = f"{repo_url}/commit/{commit['id']}"
48+
49+
if pr_number:
50+
commit["extra"]["closed_issues"] = pr_issues.get(pr_number, [])
51+
52+
commit["extra"]["raw_pr_link"] = f"(#{pr_number})"
53+
54+
pr_link = f"{repo_url}/pulls/{pr_number}"
55+
issue_links = [
56+
f"[#{issue}]({repo_url}/issues/{issue})"
57+
for issue in commit["extra"]["closed_issues"]
58+
]
59+
60+
if issue_links:
61+
commit["extra"]["pr_link"] = (
62+
f"([#{pr_number}]({pr_link}, closes {', '.join(issue_links)}))"
63+
)
64+
else:
65+
commit["extra"]["pr_link"] = f"([#{pr_number}]({pr_link}))"
66+
67+
68+
parser = ArgumentParser()
69+
parser.add_argument("--repo", type=str, required=True)
70+
parser.add_argument("--unreleased-version", nargs="?", default=None, type=str)
71+
parser.add_argument("--release-notes", action=BooleanOptionalAction)
72+
73+
74+
if __name__ == "__main__":
75+
args = parser.parse_args()
76+
repo_url = f"https://github.com/{args.repo}"
77+
owner, repo = args.repo.split("/")
78+
79+
pr_issues = load_pr_issues(owner, repo)
80+
context = json.load(sys.stdin)
81+
82+
for release in context:
83+
enhance_release(release, args.release_notes, args.unreleased_version)
84+
85+
for commit in release["commits"]:
86+
enhance_commit(commit, pr_issues)
87+
88+
json.dump(context, sys.stdout)

git-cliff-release/fetch_pr_issues.sh

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
#!/bin/sh
22

3-
owner=$(echo $GITHUB_REPO | cut -d / -f 1)
4-
repo=$(echo $GITHUB_REPO | cut -d / -f 2)
3+
owner=$1
4+
repo=$2
5+
6+
if [ -z "$owner" -o -z "$repo" ]; then
7+
echo "Missing arguments - owner and repo" >&2
8+
exit 1
9+
fi
510

611
gh api graphql --paginate --slurp \
712
-F owner="$owner" \
@@ -32,4 +37,4 @@ jq '
3237
(.number | tostring):
3338
[.closingIssuesReferences.nodes | .[] | .number]
3439
}
35-
] | add' > pullRequestIssues.json
40+
] | add'

git-cliff-release/preprocess_commit_message.py

Lines changed: 0 additions & 54 deletions
This file was deleted.

0 commit comments

Comments
 (0)