Templates#
The changelog is generated with over-ridable Jinja templates. You don’t have to override all the templates, simply the ones you want to.
You can configure where generate-changelog
looks for custom templates.
The core of the changelog is the commit. The rest is just a grouping of the commits in a desired method.
base.md.jinja#
The base template is rendered when generating the changelog from scratch. Incremental generations will only use the heading and versions templates.
{% include "heading.md.jinja" %}
{% include "versions.md.jinja" %}
{% include "footer.md.jinja" %}
heading.md.jinja#
The heading template is rendered for the title of the changelog.
# Changelog
versions.md.jinja#
{% for version in versions -%}
{% include "version_heading.md.jinja" %}
{% for grp_commit in version.grouped_commits -%}
{% if loop.previtem is defined %}
{% set heading_level = diff_index(loop.previtem.grouping, grp_commit.grouping) %}
{% else %}
{% set heading_level = 0 %}
{%- endif %}
{% for level in range(heading_level, group_depth) -%}
{% include "section_heading.md.jinja" %}
{% endfor %}
{% for commit in grp_commit.commits %}
{% include "commit.md.jinja" %}
{% endfor %}
{%- endfor %}
{%- endfor %}
To understand how this template works, understanding how the commits are processed and grouped will help.
The commits are enriched with metadata and sorted by the version and grouping values. In this table you can see the commit version and the values of the group_by
configuration, sorted.
version |
committer, metadata.category |
Commit |
---|---|---|
1.0.1 |
Alice, Changes |
commit8 |
1.0.1 |
Alice, New |
commit2 |
1.0.1 |
Alice, New |
commit5 |
1.0.1 |
Bob, Changes |
commit7 |
1.0.1 |
Bob, Fixes |
commit10 |
1.0.1 |
Bob, New |
commit1 |
1.0.1 |
Bob, New |
commit4 |
1.0.1 |
Charly, Changes |
commit6 |
1.0.1 |
Charly, Fixes |
commit9 |
1.0.1 |
Charly, New |
commit3 |
This is consolidated into the context that looks something like this (See the VersionContext for better information):
simplified_version_context = {
"label": "1.0.1",
"grouped_commits": {
("Alice", "Changes"): ["commit8"],
("Alice", "New"): ["commit2", "commit5"],
("Bob", "Changes"): ["commit7"],
("Bob", "Fixes"): ["commit10"],
("Bob", "New"): ["commit1", "commit4"],
("Charly", "Changes"): ["commit6"],
("Charly", "Fixes"): ["commit9"],
("Charly", "New"): ["commit3"],
}
}
The template looks for changes in the grouping values and renders section headings for the new value. The result is somthing like:
## 1.0.1 (2022-01-01)
### Alice
#### Changes
- commit8
#### New
- commit2
- commit5
...
version_heading.md.jinja#
The version heading template is rendered for the title of each tagged version.
## {{ version.label }} ({{ version.date_time.strftime("%Y-%m-%d") }})
section_heading.md.jinja#
The section heading template is rendered for the value changes in the grouping. The heading level is adjusted based on the level
parameter set in the version_heading.md.jinja
template.
###{{ "#" * level }} {{ grp_commit.grouping[level] or "Other" }}
commit.md.jinja#
This template is rendered for each commit.
- {{ commit.summary }}
{{ commit.body|indent(2, first=True) }}
{% for key, val in commit.metadata["trailers"].items() %}
{% if key not in valid_author_tokens %}
**{{ key }}:** {{ val|join(", ") }}
{% endif %}
{% endfor %}