Releasing Keptn at the click of a button
How we streamlined our Keptn release process from 2 days to just a couple of minutes.
Half a year ago, when I joined Dynatrace, I got assigned with the task of improving the release experience of Keptn. I was pointed to a GitHub wiki page with over 130 checkboxes to fill until you could finally publish a notification post in the Keptn Slack workspace about the new release. All in all, it was a process that usually took 2 days for 2 developers(!!) and as I went through the checklist, I noticed a few notes in there saying, “Automation Wanted!”.
So, we started looking into how this process could be streamlined to the point where, ideally, humans would not need to interfere at all with the process. Not only to reduce the time/cost associated with cutting a release but also to reduce the potential for human errors during the whole process.
We had the following requirements in mind:
- Automatic generation of a changelog since the last release
- Automatic calculation of the new version number for the release
- Upload of docker images, helm charts and other artifacts to the different distribution channel like DockerHub, GitHub Container Registry, Quay.io, our helm charts repository, etc.
- Creation of a Git tag and release on GitHub with changelog and artifacts attached
After a few days of research, we came up with a plan that involved a restructuring of the release process and our general development process on GitHub.
Giving meaning to the Git history using Conventional Commits
The first milestone of the new solution was to make the whole commit history machine readable. Only then would it even be possible to have changelogs and version numbers be generated by a machine. We chose the conventional commits standard since it is the most widely used one (projects like Angular have been using it for a long time now with great success).
Conventional commits can have a few different forms:
feat: Some new and exciting feature
fix: Fixed a weird bug happening in Keptn CLI
Generally, this format gives every commit message semantics that are both readable by humans and computers. As you can probably already tell from the prefixes, every commit message now has a type that refers to the changes that were made in this commit. The most used types are fix and feat for bugfixes and features. In Keptn, we also defined a few other types to be able to generate a more meaningful changelog in the end. Those include the following:
Additionally, there are a few other features built into the conventional commit standard that denote, e.g., breaking changes or scopes or sub-projects that the changes belong to.
Building a changelog from Keptn’s Git history
Using the conventional changelog standard, we can build a changelog that groups different changes together according to their type and scope. This can of course be done in a custom way, but there are also a multitude of tools out there that will take over this operation and many more from you.
We chose to go with the Standard Version tool which is also developed under the Conventional Changelog GitHub Organization. Standard Version was the best fit for Keptn since it provided much more than just the auto-generated changelog, as you will read in the following paragraphs.
Semantic Versioning and automated releases
Standard Version is Keptn’s all-in-one solution to handle most tasks needed to release Keptn.
Most importantly, the tool takes calculating a new version number out of a human’s hands. From the now machine-readable changelog, Standard Version will calculate the new version number according to semantic versioning: If there were only bug fixes, the patch version is increased; if there were new features, but none of them were breaking changes, then the minor version number is increased.
In the case of Keptn, we configured Standard Version a little differently since we aren’t in full “GA” mode yet. Bugfixes and non-breaking features increase the patch version. Breaking features increase the minor version since all Keptn versions for now are 0.* versions.
This already shows another great advantage of Standard Version. It has configuration options where users need them, but not so many that you drown in them and lose sight of what’s important.
All in all, Standard Version, together with a few changes to our Git work processes, gives the Keptn team the power to release Keptn with the single click of a button.
We wrote an automated pipeline that will do all necessary steps to release Keptn and its different artifacts over a few different release channels such as Helm Chart repositories, CLI binaries and Docker images in multiple registries.
Simplified maintenance for old releases
With the automation of releases in place, we tackled our branching model. We were adhering to a slightly adapted version of Git Flow, and we wanted to simplify it.
Normal development in feature branches generally stayed the same as before, but release branching changed a lot.
Instead of creating a separate, long-living branch for every release, we now have so-called maintenance branches that are only created on demand.
Generally, releases happen on master directly, but a new maintenance branch is created for bugfix releases. This branch takes the 0.*.0 release as its base and any bug fixes for that release can be pushed onto the new maintenance branch. Our naming scheme for those branches follows a structure like the following:
Base release: 0.10.0
Maintenance branch name: 0.10.x
All bugfixes for 0.10.0 will be pushed onto that new maintenance branch and they will be released directly from there. This means that any bugfix releases like 0.10.1or 0.10.2will happen from that 0.10.x branch.
To keep the bugfixes in sync with master, we merge the bugfixes first into master and then backport them onto the respective maintenance branch(es).
A final recap
The Keptn team historically had to put lots of time into creating a new release with a long checklist of tasks to do before the release could be announced.
Now, this process is simplified a lot by one-button-click releases that already generate the new version number and changelog for you and then release all the different artifacts to the places where they need to go.
The checklist still exists of course, but it was heavily reduced. All that remains are manual testing steps and release announcements.
In addition to introducing the new release process in the Keptn main repo, we have also added it to the different auxiliary repositories around Keptn, like keptn/kubernetes-utils, keptn/go-utils and keptn/examples. Keptn-contrib is also currently using it (with some adaptations).