From 5989af89c3b450bc1abedc279ea12e0e757fd70f Mon Sep 17 00:00:00 2001
From: Philipp Stadler <hello@phstadler.com>
Date: Mon, 15 Jul 2024 18:08:21 +0200
Subject: [PATCH] feat: add changelog generation with git-cliff

---
 .gitignore     |  1 +
 .gitlab-ci.yml | 25 +++++++++++++-
 cliff.toml     | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 113 insertions(+), 1 deletion(-)
 create mode 100644 .gitignore
 create mode 100644 cliff.toml

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1b763b1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+CHANGELOG.md
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d9dc50b..343d510 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -18,9 +18,30 @@ build:
   artifacts:
     paths:
       - '*.apkg'
+      - LICENSE
+      - NOTICE
     reports:
       dotenv: build.env
 
+changelog:
+  image:
+    name: orhunp/git-cliff:latest
+    entrypoint: [""]
+  rules:
+    - if: $CI_PIPELINE_SOURCE == "schedule"
+      when: never
+    # tagging should only happen after the thing was merged, so do it on the main branch build
+    - if: $CI_COMMIT_BRANCH == "main"
+  variables:
+    GIT_STRATEGY: clone # clone entire repo instead of reusing workspace
+    GIT_DEPTH: 0 # avoid shallow clone to give cliff all the info it needs
+  stage: build
+  script:
+    - git-cliff --latest -o CHANGELOG.md
+  artifacts:
+    paths:
+      - CHANGELOG.md
+
 release-package-json-version-as-git-tag:
   stage: release
   rules:
@@ -54,6 +75,8 @@ create-gitlab-release:
   needs:
     - job: build
       artifacts: true
+    - job: changelog
+      artifacts: true
   variables:
     # we just need the artifacts and don't need up-to-date source, so don't even fetch
     GIT_STRATEGY: none
@@ -64,7 +87,7 @@ create-gitlab-release:
   release:
     tag_name: '$CI_COMMIT_TAG'
     name: '$CI_COMMIT_TAG'
-    description: 'Neue APKGS stehen zum Download bereit.' 
+    description: CHANGELOG.md
     assets:
       links:
         - name: 'Browse all APKGSโ€ฆ'
diff --git a/cliff.toml b/cliff.toml
new file mode 100644
index 0000000..8409542
--- /dev/null
+++ b/cliff.toml
@@ -0,0 +1,88 @@
+# git-cliff ~ default configuration file
+# https://git-cliff.org/docs/configuration
+#
+# Lines starting with "#" are comments.
+# Configuration options are organized into tables and keys.
+# See documentation for more information on available options.
+
+[changelog]
+# template for the changelog header
+header = """
+## Changelog\n
+"""
+# template for the changelog body
+# https://keats.github.io/tera/docs/#introduction
+body = """
+{% 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 | striptags | trim | upper_first }}
+    {% for commit in commits %}
+        - {% if commit.scope %}*({{ commit.scope }})* {% endif %}\
+            {% if commit.breaking %}[**breaking**] {% endif %}\
+            {{ commit.message | upper_first }}\
+    {% endfor %}
+{% endfor %}\n
+"""
+# template for the changelog footer
+footer = """
+<!-- generated by git-cliff -->
+"""
+# remove the leading and trailing s
+trim = true
+# postprocessors
+postprocessors = [
+  # { pattern = '<REPO>', replace = "https://github.com/orhun/git-cliff" }, # replace repository URL
+]
+
+[git]
+# parse the commits based on https://www.conventionalcommits.org
+conventional_commits = true
+# filter out the commits that are not conventional
+filter_unconventional = true
+# process each line of a commit as an individual commit
+split_commits = false
+# regex for preprocessing the commit messages
+commit_preprocessors = [
+  # Replace issue numbers
+  #{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/issues/${2}))"},
+  # Check spelling of the commit with https://github.com/crate-ci/typos
+  # If the spelling is incorrect, it will be automatically fixed.
+  #{ pattern = '.*', replace_command = 'typos --write-changes -' },
+]
+# regex for parsing and grouping commits
+commit_parsers = [
+  { message = "^feat", group = "<!-- 0 -->๐Ÿš€ Features" },
+  { message = "^fix", group = "<!-- 1 -->๐Ÿ› Bug Fixes" },
+  { message = "^doc", group = "<!-- 3 -->๐Ÿ“š Documentation" },
+  { message = "^perf", group = "<!-- 4 -->โšก Performance" },
+  { message = "^refactor", group = "<!-- 2 -->๐Ÿšœ Refactor" },
+  { message = "^style", group = "<!-- 5 -->๐ŸŽจ Styling" },
+  { message = "^test", group = "<!-- 6 -->๐Ÿงช Testing" },
+  { message = "^chore\\(release\\): prepare for", skip = true },
+  { message = "^chore\\(deps.*\\)", skip = true },
+  { message = "^chore\\(pr\\)", skip = true },
+  { message = "^chore\\(pull\\)", skip = true },
+  { message = "^chore|^ci", group = "<!-- 7 -->โš™๏ธ Miscellaneous Tasks" },
+  { body = ".*security", group = "<!-- 8 -->๐Ÿ›ก๏ธ Security" },
+  { message = "^revert", group = "<!-- 9 -->โ—€๏ธ Revert" },
+]
+# protect breaking changes from being skipped due to matching a skipping commit_parser
+protect_breaking_commits = false
+# filter out the commits that are not matched by commit parsers
+filter_commits = false
+# regex for matching git tags
+# tag_pattern = "v[0-9].*"
+# regex for skipping tags
+# skip_tags = ""
+# regex for ignoring tags
+# ignore_tags = ""
+# sort the tags topologically
+topo_order = false
+# sort the commits inside sections by oldest/newest order
+sort_commits = "oldest"
+# limit the number of commits included in the changelog.
+# limit_commits = 42
-- 
GitLab