Improve your changelogs
Categories:
Background
A standard part of the Jenkins X pipelines since a long time is the execution of jx changelog create
that takes the
commit messages between the release currently being created and the previous one and creates a change log from these.
The change log is then stored as a release note in GitHub or other git provider.
During the last year some improvements have landed in various Jenkins X components to improve the changelogs and their usefulness. So I’ll take this opportunity to describe these improvements and also in general give hints to how to get useful changelogs.
Overview of major improvements
Changelogs haven’t been very informative with regard to upgrades, ie those applied with jx promote
or jx updatebot
. One example of this is the release notes of jx after the
split out of most functionality to plugins. Lately these have improved due to new functionality to propagate
changelogs via pull requests.
One place where changelogs have been completely lacking is in cluster repositories. But using the functionality for propagation of changelogs and some changes in jx boot job you can now a get a changelog for every successful application of changes in a cluster.
Example
An example of what this functionality achieves can be seen in a release of jx:
https://github.com/jenkins-x/jx/releases/tag/v3.10.81
If you scroll past the boilerplate installation instructions you first see the changelog of jx itself generated from commit messages: https://github.com/jenkins-x/jx/compare/v3.10.80...v3.10.81
Then there is a separator followed by the changelog of jx-gitops. If you look in the commit messages referred to above
you will see a link to the pull request on jx for this upgrade: https://github.com/jenkins-x/jx/pull/8564. As you can
see this pull request includes the changelog for version 0.14.8 of jx-gitops as generated by jx changelog create
.
Essentially what happens is that jx changelog create
apart from storing the release information of jx-gitops also stores it
in a file. This file is then put in the pull request on jx by jx updatebot
. Finally jx changelog create
looks
for changelogs in the pull requests referred to in the merge commit.
How to write commit messages
To get a good changelog the first requisite is to write good commit messages. jx changelog create
expects commit
messages to adhere to the Conventional commits standard.
It is the first line of each commit message that is used, with a couple of exceptions I’ll describe below.
When following this standard the first line should adhere to this format:
<type>[optional scope]: <description>
While jx changelog create
can handle any type some will be expanded for a better looking changelog:
feat
: New Featuresfix
: Bug Fixesperf
: Performance Improvementsrefactor
: Code Refactoringdocs
: Documentationtest
: Testsrevert
: Revertsstyle
: Styles
Since the description is used verbatim in the changelog it should be meaningful to the audience of the changelog. Is
for example fixed typo
meaningful? Maybe it is better to write what you try to achieve. While doing this it is
good to know that duplicate descriptions are ignored by changelog. So if you add the same description again when
doing a fix doesn’t mean that you get duplicate lines in the changelog.
An optional scope is prefixed to the description in the changelog.
The other common part of the commit message that is reflected in the changelog are references to issues. These can be put anywhere in the commit message. These issues are then linked to both for the specific commit and in a separate list of affected issues.
An example:
feat: support dependency updates
fixed typo
relates to #1234
A less common part of a commit message that affects the changelog regards breaking changes. A footer to a commit
message of the format BREAKING CHANGE: <description>
can be added and this description will be put at the top of
the changelog under the heading BREAKING CHANGES. If you add an exclamation mark before the colon in the first line
without the breaking change footer the ordinary description will be put under this heading.
A couple of examples regarding braking changes:
fix: upgraded library foo
BREAKING CHANGE: don't support http anymore
#98765
fix!: removed insecure method fubar
resolves #56789
Good to know is that jx release version
also conforms
to Conventional Commits so the commit messages also affects which part of the semantic version is increased for a
release.
There are of course other uses of good commit messages than to generate changelogs. While code itself together with
comments should be self-explanatory with regard to what is done and how I often resort to commit messages to
understand why a change was made. I typically use the git blame functionality for this. This is another reason to
not use messages only saying something like fixed typo
, since that typically isn’t a useful answer to the question
of why for a future developer.
For more tips regarding writing good commit messages see for example How to Write Better Git Commit Messages.
Manually edit changelog
Note that since changelogs for dependencies are propagated through pull requests you can edit the changelog for an application manually in the pull request before it is merged.
Configuration
Some of the features described above work out-of-the-box while others require some tweaking.
Changelog for cluster repository
Apart from the other advantages of switching from kubectl apply
to kpt live apply
for reconciliation of cluster
repository with the cluster you also get a changelog generated for each successful reconciliation.
This changelog also includes a list of upgraded / added / deleted releases and the associated versions.
See a previous blogpost for more information.
Reuse pull requests
With the default settings one pitfall with the propagating the changelog via pull requests is if not all pull requests are merged. Let’s say version 1.0.0 of an application is released and pull request with a big changelog is created for the production namespace. But before it is merged an error is detected and version 1.0.1 is released and a PR for the version is created which only includes the changelog for the bug fix. When that PR is merged only the changelog for the bug fix ends up in the changelog for the cluster.
To mitigate this you can enable reuse of pull requests. This means that if a PR for upgrading a dependency already
exists when executing jx promote
or jx updatebot
the commits for that PR are replaced with one for the new
upgrade. The existing changelog in the PR is kept though and the changelog for the new version is appended. This way
no changelog is missed.
Enabling reuse of pull requests for jx promote
is done in jx-requirements.yaml
by setting reusePullRequest
to
true
for an environment. It can also be done in the same way when configuring environments others ways. See
https://jenkins-x.io/v3/develop/environments/config/ for more details about configuring environments.
More information about reuse of pull requests in a future blog post.
Custom pipelines
In the pipelines defined in https://github.com/jenkins-x/jx3-pipeline-catalog/ the necessary incantations of jx changelog
, jx promote
and jx updatebot
are made for promoting changelogs. But if you have a custom release
pipeline you might need to do some modifications. In particular jx changelog create
need to save the changelog to a file.
This is done by adding an argument like --output-markdown=../changelog.md
. To have this changelog added to the PR
the option --add-changelog=../changelog.md
needs to be added to jx promote
(or jx updatebot
if applicable).
Jira as issue tracker
In the examples of commit messages above the references to issues are to the git provider. This is the default, so if you for example are using GitHub as your git provider and also use the issue tracker in GitHub no extra configuration is needed.
But there also is support for Jira as issue tracker. If you enable this support you can refer to issues both at the git provider and in Jira.
You enable Jira support and configure it in the jx-requirements.yaml of the cluster repository. The
issueProvider
field is added under spec.cluster
:
@@ -13,5 +13,9 @@ spec:
gitKind: github
gitName: github
gitServer: https://github.com
+ issueProvider:
+ jira:
+ serverUrl: https://myjira.atlassian.net
+ userName: jirauser@example.com
project: "123456789"
provider: eks
For security reasons the credentials for the user that will fetch data from Jira is not put there. Instead jx changelog
expects it in the environment variable JIRA_API_TOKEN
. The easiest way to supply this environment
variable is by adding it to the secret jx-boot-job-env-vars
in namespace jx
since the content av this secret are
exposed as environment variables to all standard build pipelines. If the secret doesn’t exist you can create it
yourself like this:
# lets make sure we are in the jx-git-operator namespace
jx ns jx-git-operator
kubectl create secret generic jx-boot-job-env-vars --from-literal=JIRA_API_TOKEN='S!B*d$zDsb'
The Terraform module for Jenkins X in EKS also have support for
adding variables to jx-boot-job-env-vars
.
More customizations
In the documentations for jx changelog create
information about more customisations can be found.