Semantic Release Survival Guide

This is a collection of tips and things I learned from using semantic release in various scenarios

Roman Labunsky
Datree
4 min readOct 17, 2017

--

I first came across semantic release when working on an npm module (currently private but will be public soon) for my company, datree.io.

The benefits were immediately clear to me: easy releases, version bumping, release notes, clear and structured commit messages. The flow was elegant and easy to integrate as we host our code on GitHub and build with Travis CI.

The simple use case is clear and well documented on the readme. I encountered some problems with semantic release when i needed to release locally and when working on a project that doesn’t include publishing a module to npm. All these problems are fixable but solutions are scattered and it’s hard to pinpoint the source of the problem. Messages like semantic-release ERR! pre ENOTINHISTORY Commit not in history Error don’t give too much insight into the underlying problem or the possible solution. Let’s look at some of the use cases:

  1. Releasing from a local machine
  2. Releasing without publishing to NPM
  3. Releasing during Travis build stages
  4. recovering from ENOTINHISTORY error

Releasing Locally

Releasing locally is hardly the recommended way of releasing but sometimes it’s needed, even if only for fixing another problem with semantic release (more on that later on).

To release locally you need 3 things:

  • running the commands with debug=false .
    I added another script to my package.json called semantic-release-local that does just that

Having the right environment variables. semantic release requires a GH_TOKEN environment variable which you can acquire from GitHub and an NPM_TOKEN environment variable, that can be acquired by taking the part following_authToken= in .npmrc after younpm login

  • The final part for a successful local release is disabling the verifyConditions plugin to prevent semantic release from checking that it’s run on a CI Server. This is done by pointing verifyConditions to a special plugin-noop . Add the following to your package.json

Once this is done you can npm run semantic-release-local to release locally. Avoid committing the verifyConditions part since you want all the checks semantic release provides in that plugin.

Releasing without publishing to NPM

That was by far the hardest and the most useful use case. Once I saw the benefits of semantic release and started using it in my npm modules, I wanted to apply the same comfort and ease to my web servers and other repositories that are not npm modules. This proved to be very hard as semantic release relies on the previously published version to detect changes and if you don’t publish you can only do a single release and in the subsequent attempts to release you’ll get this useful message: semantic-release ERR! post Failed to publish release notes. { [Error: {“message”:”Reference already exists”,”documentation_url”:”https://developer.github.com/v3/git/refs/#create-a-reference"}]

To release without publishing you need 2 things:

  • A plugin to detect the changes from git tags instead of npm publishes. semantic release have a stub repo for it, last-release-git-tag, but it has nothing in it and it obviously doesn’t work. What does work is last-release-git. You add it to the release part of package.json after you install it as a dev dependency.
  • Remove the npm publish part of your semantic-release npm script

Releasing in Travis build stages

Build stages is a new feature in travis that in it’s simplest form allows to run a job once other jobs complete. If the “normal” way of releasing with semantic release is to do it in the after_success part of travis.yml this method doesn’t work well if, for example, you only have a single build agent and your build process tests on several node versions. In that case the first job, running tests on node 6, waits for the rest of the jobs to complete before running the after_success part. But, the other jobs, node 8 for example, can’t run because you only have a single agent and it’s busy-waiting. You’re in a deadlock! Another case is when you have a build process that consists of many jobs, in that case you have an agent that busy-waits for who knows how long till all the other jobs complete and it may resume the after_success step. In this case you’d want to release in the jobs part of travis.yml.

To release in Travis Build Stages you need 2 things:

  • The plugin-noop part from the first section. You need it because one of the things verifyConditions checks is that it’s run in the after_success stage of the build. To run it in build stages you need to disable this check and that’s the easiest way I found to do it:
  • The job configuration in your travis.yml . This is an example job I use.

That’s it, you’re done. In travis you’ll see it at the bottom as a separate job and all your agents will be free to actually do some real work.

ENOTINHISTORY Commit not in history Error

This is one of the most annoying messages you get when using semantic release and the hardest to pinpoint IMHO. I don’t have a definite solution but these are the tips and solutions that worked for me in several cases.

  1. Deleting the last tag and release in GitHub and trying to push again.
  2. Sometimes you’ll find a suggestion to release manually, that’s what the “Release Locally” part is for. It worked for me, once.
  3. Make sure you also publish to npm or use a release that doesn’t publish to npm (see above)

Before you leave…

If you found this article helpful, hit the👏 button below and share the article. If you have something to add or correct please comment below

--

--