1# Documentation: https://git-cliff.org/docs/configuration
  2[changelog]
  3header = """# Changelog
  4
  5All notable changes to the project will be documented in this file. It is
  6non-exhaustive by design, and only contains public-facing application and API
  7changes. Internal, developer-centric changes can be seen by looking at the
  8commit log.
  9"""
 10body = """
 11{% if version %}
 12  {% set git_log_ref = version -%}
 13  {% set v = version | trim_start_matches(pat="v") -%}
 14  {% set ts = timestamp | date(format="%Y-%m-%d") -%}
 15  ## {{ v ~ " (" ~ ts ~ ")" }}
 16  {% if message %}\n{{ message | trim_start_matches(pat="v") }}\n{% endif -%}
 17{%- else -%}
 18  {% set git_log_ref = "origin/HEAD" %}
 19  ## Unreleased
 20
 21  This section documents the commits which are not yet associated with a
 22  released version.
 23{% endif %}
 24To view the full set of changes, including internal developer-centric changes,
 25run the following command:
 26
 27```
 28git log --oneline {%- raw %} {% endraw -%}
 29  {% if previous.version %}{{ previous.version }}..{% endif -%}
 30  {{ git_log_ref }}
 31```
 32{% for group, commits in commits
 33| filter(attribute="merge_commit",value=false)
 34| group_by(attribute="group") %}
 35  ### {{ group | striptags | trim | upper_first }}
 36  {% for commit in commits
 37  | filter(attribute="breaking",value=true)
 38  | filter(attribute="scope")
 39  | sort(attribute="scope") %}
 40    - **BREAKING CHANGE**: **{{ commit.scope }}**:{% raw %} {% endraw -%}
 41      {{ commit.message | trim }}{% raw %} {% endraw -%}
 42      {%- if commit.remote.username and commit.remote.pr_number -%}
 43        by @{{ commit.remote.username }} in #{{ commit.remote.pr_number }}
 44      {%- else -%}
 45        ({{ commit.id | truncate(length=8,end="") }})
 46      {%- endif -%}
 47      {%- if commit.breaking_description != commit.message %}
 48        {% raw %}  - {% endraw -%}
 49        {{ commit.breaking_description | trim | indent(prefix="   ",blank=true) }}
 50      {%- endif -%}
 51  {% endfor %}
 52  {%- for commit in commits | filter(attribute="breaking",value=true) -%}
 53    {% if not commit.scope %}
 54      - **BREAKING CHANGE**: {{ commit.message | trim }}{% raw %} {% endraw -%}
 55        {%- if commit.remote.username and commit.remote.pr_number -%}
 56          by @{{ commit.remote.username }} in #{{ commit.remote.pr_number }}
 57        {%- else -%}
 58          ({{ commit.id | truncate(length=8,end="") }})
 59        {%- endif -%}
 60        {%- if commit.breaking_description != commit.message %}
 61          {% raw %}  - {% endraw -%}
 62          {{ commit.breaking_description | trim | indent(prefix="   ",blank=true) }}
 63        {%- endif -%}
 64    {%- endif -%}
 65  {% endfor %}
 66  {%- for commit in commits
 67  | filter(attribute="scope")
 68  | sort(attribute="scope") -%}
 69    {% if not commit.breaking %}
 70      - **{{commit.scope}}**:{% raw %} {% endraw -%}
 71        {{ commit.message | trim }}{% raw %} {% endraw -%}
 72        {%- if commit.remote.username and commit.remote.pr_number -%}
 73          by @{{ commit.remote.username }} in #{{ commit.remote.pr_number }}
 74        {%- else -%}
 75          ({{ commit.id | truncate(length=8,end="") }})
 76        {%- endif -%}
 77    {%- endif -%}
 78  {%- endfor -%}
 79  {%- for commit in commits -%}
 80    {% if not commit.scope and not commit.breaking %}
 81      - {{ commit.message | trim }}{% raw %} {% endraw -%}
 82        {%- if commit.remote.username and commit.remote.pr_number -%}
 83          by @{{ commit.remote.username }} in #{{ commit.remote.pr_number }}
 84        {%- else -%}
 85          ({{ commit.id | truncate(length=8,end="") }})
 86        {%- endif -%}
 87    {%- endif -%}
 88  {% endfor %}
 89{% endfor -%}
 90"""
 91trim = true
 92
 93[bump]
 94features_always_bump_minor = true
 95breaking_always_bump_major = false  # TODO: set this to true for 1.0.0
 96
 97[git]
 98conventional_commits = true
 99filter_unconventional = true
100protect_breaking_commits =  true
101sort_commits = "oldest"
102topo_order = true
103
104commit_preprocessors = [
105  # map various older scopes to new scopes
106  # TODO: remove after init (because we will enforce an append-only workflow)
107  { pattern = '^([^\(]+)\(commands\):', replace = '$1 (cli):' },
108  { pattern = '^[^\(]+\(ci\)', replace = 'ci:' },
109  { pattern = '^[^\(]+\(TestCache\)', replace = 'test:' },
110  { pattern = '^doc: (.+ \(#1395\))', replace = 'docs(dev-infra): $1' },
111  { pattern = '^fix: (.+ \(#1403\))', replace = 'fix(completion): $1' },
112  { pattern = '^docs: (correct mispelled words)', replace = 'fix(dev-infra): $1' },
113  { pattern = '^(.+) \[fix\]$', replace = 'docs: $1' },
114  { pattern = '^fix ', replace = 'fix: ' },
115
116  # remove errata from old commit messages
117  # TODO: remove after init (because we will enforce an append-only workflow)
118  { pattern = '^([^\(]+)\((?:#?\d+|opencollective|git-bug-863)\)', replace = '$1' },
119  { pattern = ', fix https://.+/issues/653', replace = '' },
120
121  # remove quotes from reversions
122  # we do this to clean up the changelog output, since the raw message would
123  # otherwise be surrounded in quotes
124  { pattern = '^[Rr]evert: "(.+)"', replace = 'revert: $1' },
125
126  # convert quotes in subjects to graves
127  # TODO: remove after init (because we will enforce an append-only workflow)
128  { pattern = '"', replace = '`' },
129
130  # escape backslashes
131  # we do this because mdformat will remove isolated backslashes, and there is a
132  # historical commit that contains one
133  # TODO: remove after init (because we will enforce an append-only workflow)
134  { pattern = '\\', replace = '\\' },
135
136  # remove PR references from commit messages, to remove a hard dependency on
137  # github. by default, we show the commit hash (although github usernames and
138  # PR references are added in dynamically during release, for the changes
139  # shown on the release page)
140  { pattern = '\s+\(\#[0-9]+\)', replace = '' },
141]
142
143# these matches are applied in order, so be conscious of any changes you make
144commit_parsers = [
145  # skip commits generated by bots
146  { message = '^[^(]+\(changelog\)', skip = true },
147  { message = '^build\(deps(-dev)?\)', skip = true },
148  { message = '^deps?', skip = true },
149
150  # skip internal changes (non-consumer-facing changes)
151  # note that breaking changes will still be shown
152  { message = '^(?:revert: )?(?:ci|build|test|refactor)', skip = true },
153  { message = '^(?:revert: )?.+\(dev-infra\)', skip = true },
154
155  # assign group based on type
156  { message = '^docs?', group = 'Documentation' },
157  { message = '^feat', group = 'Features' },
158  { message = '^fix', group = 'Bug fixes' },
159  { message = '^perf', group = 'Performance' },
160  { message = '^revert', group = 'Reversions' },
161
162  # catch all other commits
163  { message = '^.+', group = 'Other changes' },
164]