Log4j Changelog
This project contains tools to maintain changelogs. It is designed for Apache Log4j, but can be used for any Java project.
Dependencies
You need to have the org.apache.logging.log4j:log4j-changelog
dependency in your classpath:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-changelog</artifactId>
<version>0.9.0</version>
</dependency>
Java module name and OSGi Bundle-SymbolicName
are set to org.apache.logging.log4j.changelog
.
Why yet another changelog tool?
Existing changelog practices (e.g., Keep a changelog, maven-changes-plugin) store changelog entries in the same file.
This creates merge conflicts between different branches.
Imagine multiple people working on multiple branches each containing a change to CHANGELOG.md
.
Whoever succeeds in merging their branch to main
first will cause a merge-conflict for the others, even though their work might be totally unrelated from each other.
This project embraces a model where changelog entries are kept in separate files and hence are not prone to merge conflicts.
Similar to maven-changes-plugin
, changelog sources and their exports (e.g., AsciiDoc-formatted) are split by design.
What does it look like?
All changelog sources and templates used to export them are stored in folders under the changelog directory (e.g., /src/changelog
):
$ tree -a src/changelog
├── 2.18.0 (1)
│ ├── LOG4J2-3424_Properties_defined_in_configuration_using_a_value_attribute.xml (4)
│ ├── LOG4J2-3425_Syslog_appender_lacks_the_SocketOptions_setting.xml (4)
│ ├── LOG4J2-3426_Log4j_1_2_bridge_should_not_wrap_components_unnecessarily.xml (4)
│ ├── LOG4J2-3427_Improves_ServiceLoader_support_on_servlet_containers.xml (4)
│ ├── .release-notes.adoc.ftl (5)
│ └── .release.xml (3)
├── 2.19.0 (1)
│ ├── LOG4J2-3588_Allow_PropertySources_to_be_added.xml (4)
│ ├── LOG4J2-3590_Remove_SLF4J_1_8_x_binding.xml (4)
│ ├── LOG4J2-3614_Harden_InstantFormatter_against_delegate_failures.xml (4)
│ ├── LOG4J2-3556_JsonTemplateLayout_stack_trace_truncation_fix.xml (4)
│ ├── .release-notes.adoc.ftl (5)
│ └── .release.xml (3)
├── .2.x.x (2)
│ ├── LOG4J2-1284_redirect_old_javadoc_urls.xml (4)
│ └── .release-notes.adoc.ftl (5)
├── .changelog.adoc.ftl (5)
└── .index.adoc.ftl (5)
1 | Changelog sources of released versions are stored in <changelogDirectory>/<releaseVersion> folders (e.g., src/changelog/2.19.0 ) |
2 | Changelog sources of upcoming releases are stored in <changelogDirectory>/.<releaseVersionMajor>.x.x folders (e.g., /src/changelog/.2.x.x ) |
3 | .release.xml contains the information about the associated release.
Note that upcoming release folders (e.g., src/changelog/.2.x.x ) don’t contain a .release.xml , since these releases are by definition not done yet. |
4 | All XML files not prefixed with a . (e.g., src/changelog/.2.x.x/LOG4J2-3628_new_changelog_infra.xml ) constitute changelog entries |
5 | FreeMarker templates are used to export this information to various forms; AsciiDoc-formatted pages for the website, Markdown-formatted files for GitHub Releases, etc. |
Release entry file
A release entry file, .release.xml
, consists of meta information regarding a particular release.
A sample release entry file is shared below.
src/changelog/2.19.0/release.xml
file contents<?xml version="1.0" encoding="UTF-8"?>
<release xmlns="https://logging.apache.org/xml/ns"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
https://logging.apache.org/xml/ns
https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
date="2022-09-09"
version="2.19.0"/>
Note that upcoming release folders (e.g., src/changelog/.2.x.x
) don’t contain a .release.xml
, since these releases are by definition not done yet.
Changelog entry file
A changelog entry file consists of short meta information regarding a particular change.
They are named following the [<issueId>_]<shortSummary>.xml
pattern.
Consider the following examples:
-
LOG4J2-3556_JsonTemplateLayout_stack_trace_truncation_fix.xml
-
LOG4J2-3578_Generate_new_SSL_certs_for_testing.xml
-
Update_jackson_2_11_0_2_11_2.xml
A sample changelog entry file is shared below.
src/changelog/2.19.0/LOG4J2-3556_JsonTemplateLayout_stack_trace_truncation_fix.xml
file contents<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns="https://logging.apache.org/xml/ns"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
https://logging.apache.org/xml/ns
https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
type="fixed">
<issue id="2443" link="https://github.com/apache/logging-log4j2/pull/2443"/>
<description format="asciidoc">
Make `JsonTemplateLayout` stack trace truncation operate for each label block
</description>
</entry>
Some remarks about the structure of changelog entry files:
-
The root element must be named
entry
-
entry.type
attribute is required and must be one of the change types:-
added
– for new features -
changed
– for changes in existing functionality -
deprecated
– for soon-to-be removed features -
fixed
– for any bug fixes -
removed
– for now removed features -
updated
– for dependency updates
-
-
issue
element is optional, can occur multiple times, and, if present, must containid
andlink
attributes -
There must be a single
description
element with non-blank content andformat
attribute
Exporting changelogs
Exporting changelogs is the act of feeding provided changelog and release information into FreeMarker templates to generate certain files; e.g., release notes for the website. There are two types template files supported:
- Changelog templates
-
These templates are rendered with the release and changelog information of a particular release. These are generally used to generate release notes for a particular release.
- Index templates
-
These templates are rendered with the release information of all releases. These are generally used to generate the index page referencing to release notes of each release.
ChangelogExporter
is responsible for performing the export operation.
Changelog templates
Changelog template files (e.g., src/changelog/2.19.0/.release-notes.adoc.ftl
) are rendered with the release and changelog information of a particular release using the following input data hash:
-
release
→ChangelogRelease
-
entriesByType
→Map<ChangelogEntry.Type, List<ChangelogEntry>>
See ChangelogRelease
and ChangelogEntry
for details.
These templates are generally used to generate release notes for a particular release. A sample changelog template file is shared below.
src/changelog/2.19.0/.release-notes.adoc.ftl
file contents= ${release.version}<#if release.date?has_content> (${release.date})</#if>
This release primarily contains bug fixes and minor enhancements.
<#if entriesByType?size gt 0>== Changes
<#list entriesByType as entryType, entries>
=== ${entryType?capitalize}
<#list entries as entry>
* ${entry.description.text?replace("\\s+", " ", "r")}
(<#list entry.issues as issue>${issue.link}[${issue.id}]<#if issue?has_next>, </#if></#list>)
</#list>
</#list>
</#if>
Index templates
Index template files (e.g., src/changelog/.index.adoc.ftl
) are rendered with the release information of all releases using the following input data hash:
-
releases
→ list of hashes containing following keys:-
version
-
date
-
These template files are generally used to generate the index page referencing to release notes of each release. A sample index template file is shared below.
src/changelog/.index.adoc.ftl
file contents= Release changelogs
<#list releases as release>
* xref:${release.version}.adoc[${release.version}]<#if release.date?has_content> (${release.date})</#if>
</#list>
Q&A
How can I add an entry for a change I am about to commit?
You have just committed, or better, about to commit a great feature you have been working on. Simply create a Changelog entry file and commit it along with your change!
How can I export changelogs to AsciiDoc, Markdown, etc. files?
You need to use the export
goal the Maven plugin.
I am about to deploy a new release. What shall I do?
Just before a release, three things need to happen in the changelog sources:
-
Changelog entry files needs to be moved from the upcoming release changelog directory
<changelogDirectory>/.<releaseVersionMajor>.x.x
to the new release changelog directory<changelogDirectory>/<releaseVersion>
-
Templates need to be copied from the upcoming release changelog directory to the new release changelog directory, unless it already exists in the target
-
.release.xml
needs to be created in the new release changelog directory
Due to the nature of release candidates, above steps might need to be repeated multiple times.
Log4j releases and release candidates all get deployed to the same staging repository.
Their |
How to carry out aforementioned changes are explained below in steps:
-
Populate the
<changelogDirectory>/<releaseVersion>
directory (e.g.,/src/changelog/2.19.0
) from the upcoming release changelog directory (e.g.,<changelogDirectory>/.2.x.x
) using therelease
Maven goal:./mvnw log4j-changelog:release \ -Dlog4j.changelog.directory=/path/to/changelog/directory \ -Dlog4j.changelog.releaseVersion=X.Y.Z
-
Verify that all changelog entry files are moved from
<changelogDirectory>/.<releaseVersionMajor>.x.x
directory (e.g.,/src/changelog/.2.x.x
) -
Verify that
<changelogDirectory>/<releaseVersion>
directory (e.g.,/src/changelog/2.19.0
) is created, and it contains templates, changelog entry files, and a.release.xml
If
<changelogDirectory>/<releaseVersion>
directory (e.g.,/src/changelog/2.19.0
) already exists with certain content,ChangelogReleaser
will only move new changelog entry files and override.release.xml
; templates will not be overridden. This allows one to runChangelogReleaser
multiple times, e.g., to incorporate changes added to a release candidate. -
Edit the populated templates (e.g., update the release notes with a short summary paragraph)
-
git add
the changes in the changelog directory (e.g.,/src/changelog
) and commit them