Branching workflow: git-flow and github-flow

Choosing a branching model for macchiato

Lately, I’ve been working on Macchiato to bring web application development libraries for ClojureScript on Node.js. Get a few people of different backgrounds involved on a project, and pretty soon a discussion about methodology will emerge.

Since both Dmitri Sotnikov and myself are working on some libraries at the same time, we had to decide which approach to use.

There are two major alternatives: Git-flow and Github-flow (with Gitlab-flow being a slightly more elaborate version).

Let’s review them.

Deploying a Clojure application from Gitlab CI to Heroku

Now that we have our Clojure application tested every time we push it to Gitlab, let’s configure another stage to deploy it to Heroku.

This assumes that:

  • Anything you merge to master is ready to deploy,
  • You have your Heroku API key handy, and
  • You already have a Heroku app configured, with all the necessary environment variables.

There’s two ways we can do this.

Using Gitlab CI with a Clojure project

Gitlab allows you not only to have free private repositories, but also to test them using free runners. These can run automatically, on push, for any branch or tag.

I keep a few private repositories with them, for personal projects and small experiments. I decided to give Gitlab CI a shot for a PostgreSQL-backed Clojure project.

There’s a basic example on the Gitlab CI repository. It gets and installs lein, which isn’t necessary. Instead, we’ll build use the clojure:lein Docker image.

git flow releases with ClojureScript

While we’re on the topic of Clojure being useful

I use git flow for all my projects. It’s relaxing to know that, even when you’re working solo, you have zero chance of screwing yourself over because - say - you need to make a hotfix but can’t because of a dirty master branch state.

In some projects like khroma I’ll use major/minor version for the release numbers. But in a lot of cases, like this very site, there’s no concept of a major or minor release - you just want to time-stamp each one. I may even need to start several releases a day.

I wrote a small ClojureScript helper to remove the chance of human error.