diff --git a/.github/workflows/changelog_update.yml b/.github/workflows/changelog_update.yml new file mode 100644 index 0000000..dfc9be6 --- /dev/null +++ b/.github/workflows/changelog_update.yml @@ -0,0 +1,46 @@ +name: Changelog Update + +on: + push: + tags: + - 'v*.*.*' + workflow_dispatch: + inputs: + tag_name: + description: 'Tag name to simulate a push event (e.g. v1.2.3).' + required: true +permissions: + contents: write + +jobs: + change_log: + runs-on: ubuntu-latest + steps: + - name: Checkout Branch + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 + with: + fetch-depth: 0 + token: ${{ secrets.ACCESS_TOKEN }} + - name: Generate changelog + uses: orhun/git-cliff-action@f50e11560dce63f7c33227798f90b924471a88b5 + with: + config: cliff.toml + args: --verbose + env: + OUTPUT: CHANGELOG.md + GITHUB_REPO: ${{ github.repository }} + + - name: Commit and retag + run: | + git config user.name 'github-actions[bot]' + git config user.email 'github-actions[bot]@users.noreply.github.com' + git add CHANGELOG.md + if git diff --cached --quiet; then + echo "No changelog changes, skipping." + exit 0 + fi + TAG_NAME="${INPUT_TAG_NAME:-${GITHUB_REF#refs/tags/}}" + git commit -m "Update changelog for ${TAG_NAME}" + git push origin HEAD:main + git tag -f "${TAG_NAME}" + git push origin -f "${TAG_NAME}" diff --git a/.github/workflows/package-build.yml b/.github/workflows/package-build.yml index 3a53cf5..5f47863 100644 --- a/.github/workflows/package-build.yml +++ b/.github/workflows/package-build.yml @@ -11,8 +11,8 @@ jobs: build-package: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 with: python-version: "3.10" - name: Install build tools diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index fecf263..928a289 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -17,9 +17,9 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 - name: Set up Python 3.10 - uses: actions/setup-python@v5 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 with: python-version: "3.10" cache: pip @@ -46,9 +46,9 @@ jobs: python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 with: python-version: ${{ matrix.python-version }} cache: pip diff --git a/cliff.toml b/cliff.toml new file mode 100644 index 0000000..db5b880 --- /dev/null +++ b/cliff.toml @@ -0,0 +1,107 @@ +# git-cliff ~ configuration file +# https://git-cliff.org/docs/configuration + +[changelog] +# A Tera template to be rendered as the changelog's header. +# See https://keats.github.io/tera/#getting-started +header = """ +# Changelog\n +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n +""" +# A Tera template to be rendered for each release in the changelog. +# See https://keats.github.io/tera/#getting-started +body = """ +{%- macro remote_url() -%} + https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }} +{%- endmacro -%} + +{% if version -%} + ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }} +{% else -%} + ## [Unreleased] +{% endif -%} + +{% for group, commits in commits | group_by(attribute="group") %} + ### {{ group | upper_first }} + {%- for commit in commits %} + - {{ commit.message | split(pat="\n") | first | upper_first | trim }}\ + {% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif -%} + {% if commit.remote.pr_number %} in \ + [#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }}) \ + {%- endif -%} + {% endfor %} +{% endfor %} + +{%- if github.contributors | filter(attribute="is_first_time", value=true) | length != 0 %} + ### New Contributors +{%- endif -%} + +{% for contributor in github.contributors | filter(attribute="is_first_time", value=true) %} + * @{{ contributor.username }} made their first contribution + {%- if contributor.pr_number %} in \ + [#{{ contributor.pr_number }}]({{ self::remote_url() }}/pull/{{ contributor.pr_number }}) \ + {%- endif %} +{%- endfor %}\n + +{%- if github.contributors | filter(attribute="is_first_time", value=true) | length != 0 %}{% raw %}\n{% endraw -%}{% endif %} + +""" +# A Tera template to be rendered as the changelog's footer. +# See https://keats.github.io/tera/#getting-started +footer = """ +{%- macro remote_url() -%} + https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }} +{%- endmacro -%} + +{% for release in releases -%} + {% if release.version -%} + {% if release.previous.version -%} + [{{ release.version | trim_start_matches(pat="v") }}]: \ + {{ self::remote_url() }}/compare/{{ release.previous.version }}...{{ release.version }} + {% endif -%} + {% else -%} + [unreleased]: {{ self::remote_url() }}/compare/{{ release.previous.version }}...HEAD + {% endif -%} +{% endfor %} + +""" +# Remove leading and trailing whitespaces from the changelog's body. +trim = true + +[git] +# Parse commits according to the conventional commits specification. +# See https://www.conventionalcommits.org +conventional_commits = true +# Exclude commits that do not match the conventional commits specification. +filter_unconventional = false +# An array of regex based parsers to modify commit messages prior to further processing. +commit_preprocessors = [ + # Remove issue numbers. + { pattern = '\((\w+\s)?#([0-9]+)\)', replace = "" }, +] +# An array of regex based parsers for extracting data from the commit message. +# Assigns commits to groups. +# Optionally sets the commit's scope and can decide to exclude commits from further processing. +commit_parsers = [ + { message = "^[Aa]dd", group = "Added" }, + { message = "^[Ss]upport", group = "Added" }, + { message = "^[Rr]emove", group = "Removed" }, + { message = "^.*: add", group = "Added" }, + { message = "^.*: support", group = "Added" }, + { message = "^.*: remove", group = "Removed" }, + { message = "^.*: delete", group = "Removed" }, + { message = "^test", group = "Fixed" }, + { message = "^fix", group = "Fixed" }, + { message = "^.*: fix", group = "Fixed" }, + { message = "^.*", group = "Changed" }, +] +# Exclude commits that are not matched by any commit parser. +filter_commits = false +# Order releases topologically instead of chronologically. +topo_order = false +# Order of commits in each group/release within the changelog. +# Allowed values: newest, oldest +sort_commits = "newest" \ No newline at end of file