Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/changelog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: update-changelog
on:
push:
branches:
- main
permissions:
contents: write
jobs:
changelog:
name: Update CHANGELOG
runs-on: ubuntu-latest
timeout-minutes: 15
if: |
!startsWith(github.event.head_commit.message, '[Release]') &&
!startsWith(github.event.head_commit.message, 'chore(changelog): update CHANGELOG.md') &&
github.event.head_commit.author.name != 'github-actions[bot]'
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: jdx/mise-action@v3
with:
experimental: true
- name: Generate CHANGELOG.md
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: git cliff --config ./cliff.toml -o ./CHANGELOG.md
- name: Check for CHANGELOG changes
id: changelog-changes
run: |
if git diff --quiet CHANGELOG.md; then
echo "No changes in CHANGELOG.md"
echo "has-changes=false" >> $GITHUB_OUTPUT
else
echo "CHANGELOG.md has changes"
echo "has-changes=true" >> $GITHUB_OUTPUT
fi
- name: Commit CHANGELOG
uses: stefanzweifel/git-auto-commit-action@v7
if: steps.changelog-changes.outputs.has-changes == 'true'
with:
commit_message: "chore(changelog): update CHANGELOG.md"
commit_options: '--no-verify'
file_pattern: CHANGELOG.md
commit_user_name: github-actions[bot]
commit_user_email: github-actions[bot]@users.noreply.github.com
48 changes: 38 additions & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,47 @@
# Change Log
# Changelog

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).

#### 1.x Releases
- `1.0.x` Releases - [1.0.0](#100) | [1.0.1](#101)
- `1.0.x` Releases - [1.0.1](#101) | [1.0.0](#100)

---
## [Unreleased]

### Features
- Implement interruptable animator
- Implemented by [@ns-vasilev](https://github.com/ns-vasilev) in Pull Request [#7](https://github.com/space-code/transitions/pull/7).

### Miscellaneous Tasks
- Switch from Makefile to Mise
- Contributed by [@ns-vasilev](https://github.com/ns-vasilev) in Pull Request [#8](https://github.com/space-code/transitions/pull/8).

## [1.0.1](https://github.com/space-code/transitions/releases/tag/1.0.1)
Released on 2025-02-10.

#### Added
- Implement `CoreTransition`.
- Added in Pull Request [#93](https://github.com/space-code/transitions/pull/3)
Released on 2025-02-10. All issues associated with this milestone can be found using this [filter](https://github.com/space-code/transitions/milestones?state=closed&q=1.0.1).

### Uncategorized Changes
- Release `1.0.1`
- Contributed by [@ns-vasilev](https://github.com/ns-vasilev) in Pull Request [#4](https://github.com/space-code/transitions/pull/4).
- Implement `CoreTransition`
- Contributed by [@ns-vasilev](https://github.com/ns-vasilev) in Pull Request [#3](https://github.com/space-code/transitions/pull/3).

## [1.0.0](https://github.com/space-code/transitions/releases/tag/1.0.0)
Released on 2025-01-13.

#### Added
- Initial release of Transitions.
- Added by [Nikita Vasilev](https://github.com/ns-vasilev).
Released on 2025-01-13. All issues associated with this milestone can be found using this [filter](https://github.com/space-code/transitions/milestones?state=closed&q=1.0.0).

### Uncategorized Changes
- Release `1.0.0`
- Contributed by [@ns-vasilev](https://github.com/ns-vasilev) in Pull Request [#2](https://github.com/space-code/transitions/pull/2).
- Bump actions/checkout from 2 to 4
- Contributed by [@dependabot[bot]](https://github.com/dependabot[bot]) in Pull Request [#1](https://github.com/space-code/transitions/pull/1).

### New Contributors
* @dependabot[bot] made their first contribution in [#1](https://github.com/space-code/transitions/pull/1)

[unreleased]: https://github.com/space-code/transitions/compare/1.0.1..HEAD
[1.0.1]: https://github.com/space-code/transitions/compare/1.0.0..1.0.1

268 changes: 268 additions & 0 deletions cliff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
# git-cliff ~ configuration file
# https://git-cliff.org/docs/configuration

[remote.github]
owner = "space-code"
repo = "transitions"
# If you are using a token to fetch GitHub usernames, uncomment below:
# token = "${GITHUB_TOKEN}"

[changelog]
# GUARANTEE: Skip releases if they contain no commits (for tagged versions)
skip_empty_releases = true
# Maximum number of releases to display in the changelog
# number_of_releases = 10

header = """
# Changelog

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).

{#- LOGIC: Generate table of contents - group versions by major version -#}
{%- set_global major_versions = [] -%}
{%- for release in releases -%}
{%- if release.version -%}
{%- set version_clean = release.version | trim_start_matches(pat="v") -%}
{%- set major = version_clean | split(pat=".") | first -%}
{%- if major not in major_versions -%}
{%- set_global major_versions = major_versions | concat(with=major) -%}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
{%- set sorted_majors = major_versions | sort | reverse -%}

{#- MAIN LOOP: Iterate over major versions -#}
{%- for major in sorted_majors -%}
{#- VISUAL: Add double newline before the header to separate from previous block -#}
{{ "\n\n" }}#### {{ major }}.x Releases

{#- LOGIC: Filter releases for the current major version -#}
{%- set_global major_releases = [] -%}
{%- for release in releases -%}
{%- if release.version -%}
{%- set version_clean = release.version | trim_start_matches(pat="v") -%}
{%- set rel_major = version_clean | split(pat=".") | first -%}
{%- if rel_major == major -%}
{%- set_global major_releases = major_releases | concat(with=version_clean) -%}
{%- endif -%}
{%- endif -%}
{%- endfor -%}

{#- LOGIC: Separate into Stable, RC, and Beta -#}
{%- set_global stable_versions = [] -%}
{%- set_global rc_versions = [] -%}
{%- set_global beta_versions = [] -%}
{%- for version in major_releases -%}
{%- if version is containing("-rc") -%}
{%- set_global rc_versions = rc_versions | concat(with=version) -%}
{%- elif version is containing("-beta") -%}
{%- set_global beta_versions = beta_versions | concat(with=version) -%}
{%- else -%}
{%- set_global stable_versions = stable_versions | concat(with=version) -%}
{%- endif -%}
{%- endfor -%}

{#- LOGIC: Group stable versions by minor version -#}
{%- set_global minor_versions = [] -%}
{%- for version in stable_versions -%}
{%- set parts = version | split(pat=".") -%}
{%- set minor_key = parts | slice(end=2) | join(sep=".") -%}
{%- if minor_key not in minor_versions -%}
{%- set_global minor_versions = minor_versions | concat(with=minor_key) -%}
{%- endif -%}
{%- endfor -%}
{%- set sorted_minors = minor_versions | sort | reverse -%}

{#- OUTPUT: Stable releases -#}
{%- for minor_key in sorted_minors -%}
{%- set_global minor_release_versions = [] -%}
{%- for version in stable_versions -%}
{%- set parts = version | split(pat=".") -%}
{%- set ver_minor = parts | slice(end=2) | join(sep=".") -%}
{%- if ver_minor == minor_key -%}
{%- set_global minor_release_versions = minor_release_versions | concat(with=version) -%}
{%- endif -%}
{%- endfor -%}
{%- set versions_list = minor_release_versions | sort | reverse -%}
{{ "\n" }}- `{{ minor_key }}.x` Releases - {% for version in versions_list -%}
[{{ version }}](#{{ version | replace(from=".", to="") | replace(from="-", to="") | lower }})
{%- if not loop.last %} | {% endif -%}
{%- endfor -%}
{%- endfor -%}

{#- OUTPUT: RC versions -#}
{%- if rc_versions | length > 0 -%}
{%- set rc_versions_sorted = rc_versions | sort | reverse -%}
{%- set rc_base = rc_versions_sorted | first | split(pat="-") | first -%}
{{ "\n" }}- `{{ rc_base }}` Release Candidates - {% for version in rc_versions_sorted -%}
[{{ version }}](#{{ version | replace(from=".", to="") | replace(from="-", to="") | lower }})
{%- if not loop.last %} | {% endif -%}
{%- endfor -%}
{%- endif -%}

{#- OUTPUT: Beta versions -#}
{%- if beta_versions | length > 0 -%}
{%- set beta_versions_sorted = beta_versions | sort | reverse -%}
{%- set beta_base = beta_versions_sorted | first | split(pat="-") | first -%}
{{ "\n" }}- `{{ beta_base }}` Betas - {% for version in beta_versions_sorted -%}
[{{ version }}](#{{ version | replace(from=".", to="") | replace(from="-", to="") | lower }})
{%- if not loop.last %} | {% endif -%}
{%- endfor -%}
{%- endif -%}
{%- endfor -%}{{ "\n" }}
---
"""

body = """
{%- macro remote_url() -%}
https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}
{%- endmacro -%}

{%- set_global renderable_commits = [] -%}
{%- for commit in commits -%}
{# Filter commits that have a Conventional Commit type or a PR number (your rendering condition) #}
{%- if commit.conventional or commit.remote.pr_number -%}
{%- set_global renderable_commits = renderable_commits | concat(with=commit) -%}
{%- endif -%}
{%- endfor -%}

{%- if renderable_commits | length > 0 -%}
{#- LOGIC: Version Header with Link -#}
{%- if version -%}
{{ "\n" }}
## [{{ version | trim_start_matches(pat="v") }}]({{ self::remote_url() }}/releases/tag/{{ version | trim_start_matches(pat="v") }})
{{ "\n" }}Released on {{ timestamp | date(format="%Y-%m-%d") }}. All issues associated with this milestone can be found using this [filter]({{ self::remote_url() }}/milestones?state=closed&q={{ version }}).
{%- else -%}
## [Unreleased]
{%- endif -%}

{#- LOGIC: Loop through commit groups -#}
{%- for group, commits_in_group in renderable_commits | group_by(attribute="group") -%}
{%- if group == "Uncategorized Changes" and commits_in_group | length == 0 -%}
{%- continue -%}
{%- endif -%}

{# We also check that it is not the system group 'Other', which might be empty #}
{%- if group == "Other" and commits_in_group | length == 0 -%}
{%- continue -%}
{%- endif -%}

{%- set action_verb = "Contributed by" -%}
{%- if group == "Features" -%}
{%- set action_verb = "Implemented by" -%}
{%- elif group == "Bug Fixes" -%}
{%- set action_verb = "Fixed by" -%}
{%- elif group == "Performance" -%}
{%- set action_verb = "Optimized by" -%}
{%- elif group == "Documentation" -%}
{%- set action_verb = "Documented by" -%}
{%- endif -%}

{{ "\n" }}{{ "\n" }}### {{ group | upper_first }}

{#- THE LOOP NOW USES FILTERED COMMITS AND DOESN'T NEED AN INNER IF -#}
{%- for commit in commits_in_group -%}
{%- set message = commit.message | split(pat="\n") | first | upper_first | trim -%}

{#- VISUAL: Commit message line -#}
{{ "\n" }}- {{ message }}

{%- if commit.remote.username and commit.remote.pr_number -%}
{#- VISUAL: Dynamic verb line -#}
{{ "\n" }} - {{ action_verb }} [@{{ commit.remote.username }}](https://github.com/{{ commit.remote.username }}) in Pull Request [#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }}).
{%- endif -%}
{%- endfor -%}
{%- endfor -%}

{#- LOGIC: New Contributors Section -#}
{%- set new_contributors = github.contributors | filter(attribute="is_first_time", value=true) -%}

{%- if new_contributors | length > 0 -%}
{%- set_global real_new_contributors = [] -%}
{%- for contributor in new_contributors -%}
{#- IMPORTANT: Filtering out your login "ns-vasilev" and Renovate -#}
{%- set username_lower = contributor.username | default(value="") | lower | trim -%}
{%- if username_lower != "ns-vasilev" and username_lower != "renovate" -%}
{%- set_global real_new_contributors = real_new_contributors | concat(with=contributor) -%}
{%- endif -%}
{%- endfor -%}

{%- if real_new_contributors | length > 0 -%}
{{ "\n" }}{{ "\n" }}### New Contributors
{%- for contributor in real_new_contributors -%}
{{ "\n" }}* @{{ contributor.username }} made their first contribution in{{ " " }}
{%- if contributor.pr_number -%}
[#{{ contributor.pr_number }}]({{ self::remote_url() }}/pull/{{ contributor.pr_number }})
{%- endif -%}
{%- endfor -%}
{%- endif -%}
{%- endif -%}
{%- endif -%}
"""

footer = """
{%- macro remote_url() -%}
https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}
{%- endmacro -%}

{{ "\n" }}
{% 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 %}
"""
trim = true
postprocessors = []

[git]
conventional_commits = true
# SET TO false to include old (unconventional) commits
filter_unconventional = false
split_commits = false
commit_preprocessors = [
{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "" },
]
commit_parsers = [
{ message = "^chore\\(changelog\\)", skip = true },
{ message = "^chore.*changelog", skip = true },
{ message = "^docs: update CHANGELOG\\.md \\[skip ci\\]$", skip = true },
{ message = "^feat", group = "Features" },
{ message = "^fix", group = "Bug Fixes" },
{ message = "^doc", group = "Documentation" },
{ message = "^perf", group = "Performance" },
{ message = "^refactor", group = "Refactor" },
{ message = "^style", group = "Styling" },
{ message = "^test", group = "Testing" },
{ message = "^chore\\(spm.*\\)", skip = false },
{ message = "^chore\\(deps.*\\)", skip = true },
{ message = "^chore\\(pr\\)", skip = true },
{ message = "^chore\\(pull\\)", skip = true },
{ message = "^chore\\(release\\): prepare for", skip = true },
{ message = "^chore|^ci", group = "Miscellaneous Tasks" },
{ body = ".*security", group = "Security" },
# CATCH-ALL PARSER for old (unconventional) commits
{ message = ".*", group = "Uncategorized Changes" },
]

# SET TO false to avoid filtering out Uncategorized Changes
filter_commits = false
protect_breaking_commits = false
tag_pattern = "^[0-9].*"
skip_tags = "beta|alpha|cli-.*"
ignore_tags = "rc|web-.*"
topo_order = false
sort_commits = "newest"

[bump]
breaking_always_bump_major = true
features_always_bump_minor = true
initial_tag = "0.1.0"