chore: add changelog 76a785a7
Steve Simkins · 2026-08-08 17:20 2 file(s) · +106 −0
.github/workflows/changelog.yml (added) +50 −0
1 +
name: Changelog
2 +
3 +
# Regenerate CHANGELOG.md on every push to main.
4 +
# Tags (v*.*.*) are treated as release versions by git-cliff.
5 +
on:
6 +
  push:
7 +
    branches:
8 +
      - main
9 +
    tags-ignore:
10 +
      - '**'
11 +
12 +
permissions:
13 +
  contents: write
14 +
15 +
concurrency:
16 +
  group: changelog-${{ github.ref }}
17 +
  cancel-in-progress: true
18 +
19 +
jobs:
20 +
  changelog:
21 +
    runs-on: ubuntu-latest
22 +
    # Avoid loops: skip the commit this workflow itself pushes.
23 +
    if: github.actor != 'github-actions[bot]'
24 +
    steps:
25 +
      - name: Checkout
26 +
        uses: actions/checkout@v6
27 +
        with:
28 +
          fetch-depth: 0
29 +
          persist-credentials: true
30 +
31 +
      - name: Generate changelog
32 +
        uses: orhun/git-cliff-action@v4
33 +
        with:
34 +
          config: cliff.toml
35 +
          args: --verbose
36 +
        env:
37 +
          OUTPUT: CHANGELOG.md
38 +
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
39 +
40 +
      - name: Commit changelog
41 +
        run: |
42 +
          git config user.name "github-actions[bot]"
43 +
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
44 +
          if git diff --quiet CHANGELOG.md; then
45 +
            echo "No changelog changes."
46 +
            exit 0
47 +
          fi
48 +
          git add CHANGELOG.md
49 +
          git commit -m "chore: update changelog [skip ci]"
50 +
          git push
cliff.toml (added) +56 −0
1 +
# git-cliff ~ configuration file
2 +
# https://git-cliff.org/docs/configuration
3 +
4 +
[changelog]
5 +
header = """
6 +
# Changelog\n
7 +
All notable changes to this project will be documented in this file.\n
8 +
"""
9 +
body = """
10 +
{% if version %}\
11 +
    ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
12 +
{% else %}\
13 +
    ## [unreleased]
14 +
{% endif %}\
15 +
{% for group, commits in commits | group_by(attribute="group") %}
16 +
    ### {{ group | striptags | trim | upper_first }}
17 +
    {% for commit in commits %}
18 +
        - {% if commit.scope %}*({{ commit.scope }})* {% endif %}\
19 +
            {% if commit.breaking %}[**breaking**] {% endif %}\
20 +
            {{ commit.message | upper_first }}\
21 +
    {% endfor %}
22 +
{% endfor %}\n
23 +
"""
24 +
trim = true
25 +
footer = """
26 +
<!-- generated by git-cliff -->
27 +
"""
28 +
29 +
[git]
30 +
conventional_commits = true
31 +
filter_unconventional = true
32 +
split_commits = false
33 +
commit_preprocessors = []
34 +
commit_parsers = [
35 +
  { message = "^feat", group = "<!-- 0 -->Features" },
36 +
  { message = "^fix", group = "<!-- 1 -->Bug Fixes" },
37 +
  { message = "^doc", group = "<!-- 3 -->Documentation" },
38 +
  { message = "^perf", group = "<!-- 4 -->Performance" },
39 +
  { message = "^refactor", group = "<!-- 2 -->Refactor" },
40 +
  { message = "^style", group = "<!-- 5 -->Styling" },
41 +
  { message = "^test", group = "<!-- 6 -->Testing" },
42 +
  { message = "^chore\\(release\\): prepare for", skip = true },
43 +
  { message = "^chore\\(deps.*\\)", skip = true },
44 +
  { message = "^chore\\(pr\\)", skip = true },
45 +
  { message = "^chore\\(pull\\)", skip = true },
46 +
  { message = "^chore|^ci", group = "<!-- 7 -->Miscellaneous Tasks" },
47 +
  { body = ".*security", group = "<!-- 8 -->Security" },
48 +
  { message = "^revert", group = "<!-- 9 -->Revert" },
49 +
]
50 +
protect_breaking_commits = false
51 +
filter_commits = false
52 +
tag_pattern = "v[0-9].*"
53 +
skip_tags = ""
54 +
ignore_tags = ""
55 +
topo_order = false
56 +
sort_commits = "oldest"