Fully automated releases

Have you ever contributed a patch to an open-source project, got it merged, and then waited months for a new release that would include your patch? Me too, reader, I’ve been there.

Moreover, I’ve been the maintainer who hasn’t gotten around to cutting a release. Cutting releases is a chore. Usually it’s a fragile, multi-step process that is not especially fun.

As programmers, what is our answer to fragile, multi-step processes? We automate them.

How to do it

When creating a release, there are a couple of steps where human input and human judgement is needed.

  1. When to create a release?
  2. How much should the version number be incremented?
  3. What to write in the change log?

There’s an automation-enabling answer to the first question that is familiar for many developers from their work environment: embrace continuous delivery and continuous deployment. Each pull request should leave the project in a state where it can be released. Then you can automatically create a release every time you merge a pull request.

You still need a human to answer the second and third question, at least if you have a conventional versioning scheme. To move the burden away from the maintainer, you can ask the contributors to fill in this information during the contribution process.

I know of two actual implementations of this: Hypothesis continuous release process and semantic-release. Hypothesis asks you to include a special file in your pull requests that looks like this:

RELEASE_TYPE: minor

This release adds a function for printing the text "Hello, world!".

semantic-release relies on specially-formatted commit messages:

feat(core): add function for printing ”Hello, world!”

Here feat means this commit adds a new feature, implying a minor release if you’re following Semantic Versioning.

In both cases, after a pull request has been successfully merged, the CI server will read this information, update the change log, increment the version number, and push a new release to the package manager. As a contributor this means that if your patch gets merged, it will be released.

What about Clojure?

I’m not aware of anyone doing this in the Clojure community1 , but I believe it would be beneficial. There are a lot of small projects that would get contributions but the maintainers are not around to merge and release them. Automated releases would make the work of the existing maintainers easier and it would also make it simpler to onboard new maintainers.

I have implemented a proof-of-concept version of the Hypothesis process for cache-metrics, a small library of mine, but I haven’t yet dared to introduce it to any ”real” libraries. Many actively developed projects would need to change their ways of working as you couldn’t just merge or commit random things to master.

I hope this post acts a starting point for a discussion. What do you think?


  1. cljsjs/packages kind-of does it, but it is a a package repository and not a library.

Comments or questions? Tweet to me or send me an e-mail.