Lars Kappert
Sep 4, 2015 · 5 min read

Introduction: Tags & Releases

Many projects use Git for their codebase. In a Git repository, you can tag a specific point in history (a commit). This is usually done to indicate a certain state of the code and mark it as a release point, a specific version of the code. Once a tag is set, that state of the code can always be retrieved. No matter how many commits and branches follow, that state is set in stone. A tag can then be used to get that specific version of the codebase, and distribute it as a package, or deploy it on a server, or to rollback a failing release.

This process of tagging and publishing, can be referred to as creating a release, or just “releasing”. It can be as simple as tagging a commit, and push the tag to the remote repository. But it might also involve things like running tests, and compilation of the source code to build a package to release.

Release Steps

Creating a release can be a tedious task, a number of steps might be involved:

  • Update the version number somewhere, e.g. in some other manifest file such as package.json.
  • Write a changelog.
  • Lint and/or test source code.
  • Compile and/or build the code.
  • Commit some changes, to save the version number.
  • Tag the latest commit.
  • Push the commit and the tag.

Automation

This is why I’ve created Release It!, a tool to speed up and automate the boring steps to create a release. It performs the steps above for you, and some more. Using your intervention with each step, or completely automated in one run. Here’s a default, interactive run:

A default, interactive run

The tool was originally built for projects using GitHub and npm in mind, but the only requirement is actually just a Git repository. Without a package.json file, it will read the latest tag from the Git repository:

Reading the latest tag from the Git repository

Or have it increment the minor version number:

Incrementing the minor version number

Node modules

Release It! supports Node modules. More specifically, it bumps the version in package.json, and asks if the package should be published to npm. No configuration is needed.

Build

Let’s take a look at an example that involves building or compiling code that should go with the release. No generated code should be in the source repository. But in practice there are many exceptions to this rule of thumb. Exceptions included compiled or transpiled code, documentation, coverage or performance reports, etcetera. Sometimes it’s not worth it to have a separate branch or repository for such build artifacts. As a side note, Release It! does support a separate branch or repository for this, but we’ll get into that later.

Another useful process is to run tests prior to the release. The tool will stop running if your tests fail, so you still have an opportunity to fix things, and try again.

In the next example, there’s a source repository that uses a build step to generate an artifact that should go with the release. We’ll use a very simple build command that concatenates two files into one new file. In the next screen dump, you can see exactly which commands are executed with verbose output. The release steps include getting the latest tag, the remote url, executing the build command, and staging the changes:

(edit: buildCommand is now scripts.beforeStage)

Execute a build command (in verbose mode)

GitHub Release

If your project is on GitHub, you might have seen each tag has a dummy “release” placeholder. A release can be enriched with a title, release notes, and additional binaries.

An example GitHub release

If the repository is on GitHub, you can create a Github Release right from Release It!. The tool currently supports creating releases with a title and a Git log as release notes. See the dyson releases page for an example.

By the way, Release It! reads arguments from the command line, but options can also be put in a JSON file named .release-it.json. Creating a GitHub release requires only little configuration:

{
"github": {
"release": true
}
}

Now, the tool will ask whether it should create a release on GitHub:

Creating a GitHub release

Some related default options are outlined below.

{
"git": {
"changelog": "git log --pretty=format:'* %s (%h)' [REV_RANGE]"
},
"github": {
"release": true,
"releaseName": "Release %s",
"tokenRef": "GITHUB_TOKEN"
}
}
  • The releaseName can be configured here (with %s being replaced by the version). You can also override it from the command line and provide the release title from there. E.g. release-it github.releaseName=”Awesome Ants”.
  • The tokenRef string is the name of the environment variable that is used as the GitHub access token. You can set it with export GITHUB_TOKEN=”f941e0…”, or set GITHUB_TOKEN=”f941e0…” on Windows.
  • The git.changelog is used to create the changelog. The default is a formatted git log of all commits between the previous and the new tag. The [REV_RANGE] is replaced with e.g. 2.0.7…HEAD. Example output with the default changelog command looks like this:
* Improve some git command handling (d6561a2)
* Fix up git.release from previous commits (e4704d0)
* Add deprecated options and deprecation notice (ec77ce3)
* Fix util.format helper (4df941b)

Distribution Repository

Some projects are using a separate repository to distribute build artifacts. This allows to keep clean source and distribution repositories, and provide only the relevant files in both.

One example is the open-source project Ember (a JavaScript framework), which maintains its source files in https://github.com/emberjs/ember.js, and distributes via https://github.com/components/ember. The distribution repository is then used as the source for package managers like Bower and Composer.

Edit: this feature has been removed, please see https://github.com/release-it/release-it/blob/master/docs/recipes/distribution-repo.md for more details on how to do the same.


Do you have any feedback, questions, or ideas? Please do not hesitate to open a ticket on GitHub, or ping me on Twitter: @webprolific!

Lars Kappert

Written by

JavaScript, Performance, Automation, Open Source @webprolific https://webpro.nl