It wasn’t until recently I realized GitLab, the opensource alternative to GitHub, has an amazing CI/CD platform. In my last post on How to Choose a Continuous Integration Tool I outlined my key criteria to choosing a CI tool. More often than not, CI tools end in developer frustration at the complexity, poor UX, and high amounts of effort to tune it just right. CI shouldn’t be that complicated.

On the flip side there are many CI tools out that put a high emphasis on simplicity and well thought out design but they leave the developer just as frustrated with the lack of flexibility (*ahem*.. TravisCI).

GitLab has won me over. It offers a well thought out balance of a elegance and power. Let’s take a close look at how GitLab stacks up to my criteria mentioned last post for evaluating a CI tool.

Deployment Model: Is it SaaS?

Yes! GitLab have a SaaS version of their CI platform that makes simple to get going without any installations, hardware, or the overhead of about upgrades and security patches. They have a very generous free tier that includes private repos and lots of CI minutes. The one caveat, and maybe it’s a big caveat, is that you need to also be using GitLab as an origin for your source code. What makes this bearable is that GitLab as an all-in-one solution is really good. I’ll get to that later.

For the on-prem lovers, it also gives you that option if you need to really scale it or put it behind a firewall. There is even a clever hybrid option to have the CI service as SaaS but communicating with a local dev machine as a CI Runner. Helpful if you run out of time on the GitLab provided runners I suppose.

Configuration: Is it YML?

Yes! GitLab has an extremely easy to use declarative YML configuration. It’s in source control, no complicated UIs to navigate and lots of flexibility. Here is the YML for the Weather Hunt backend:

image: piohhmy/weatherhunt-primary:0.0.1

before_script:
  - pip install -r requirements-dev.txt

stages:
  - test
  - deploy

unit_tests:
  stage: test
  script:
    - nosetests

deploy_staging:
  stage: deploy
  script:
    - npm install
    - npm run deploy-test
  except:
    - master

deploy_production:
  stage: deploy
  script:
    - npm install
    - npm run deploy-prod
  only:
    - master

Personally, I find it very intuitive to have the CI/CD rules based on branch. Check something into a feature branch and it gets deployed to a staging environment for exploratory testing. Check it into master and it’s deploy to production after the checks pass. If you prefer deploy on tag, it supports that too.

CI Runners: Is it Docker?

Yes! Note in the above CI configuration I’m using a custom Docker image for the CI runner. For this application I need both Python and Node to test and deploy the app. Rather than install Python and Node everytime the CI runs, a simple Dockerfile can be written and uploaded to Dockerhub. Here’s the Dockerfile used for the referenced image: piohhmy/weatherhunt-primary in the above config.

FROM python:2.7
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
RUN apt-get install -y nodejs

This Dockerfile creates a simple Node + Python prebaked image that is ready to rock everytime the CI runs. This keeps the CI feedback cycles quick and the CI configuration simple.

Pipelines: Is it Flexible?

Yes! The pipelines support a multitude of different continuous delivery, branching, and tagging models. The core concept is there are “stages” which are composed of “jobs”. All the jobs in a stage will run in parallel. If all the jobs in a stage complete, then the next stage executes. This provides a simple yet flexible model for mapping out the pipeline.

The icing on the cake with the pipelines is that it has a great visualization of the CI progress once it’s running.

GitLab Pipeline

The Gotcha. It’s all or nothing

Admittedly, I was at first skeptical thinking GitLab was the Github knockoff for those wanting to tinker and be pained by a half baked open source project. I was wrong. GitLab is a fantastic central platform to manage source code. Code viewing, issue management, and pull requests (they call them merge requests.. which actually makes a bit more sense) are all there. They have markdown support everywhere, ability to host static pages (ala this blog), emoji reactions (crucial), and unlimited private repos.

It’s a bit of an ask to migrate everything to GitLab to take advantage of the CI. Though, the process is surprisingly smooth. GitLab supports Github as an OAuth provider with a simple import process for all your existing projects.

I’ve been using GitLab now for a few months and have only found a few places where there is slightly less polish than GitHub. They are minor gripes though, like sometimes the pages require a refresh to get updated. The fantastic built-in CI, the open source model, the generous hosted free tier for hobby projects, and the on-prem option for enterprise work makes it a joy to work with.

Check out the the GitLab CI Docs and compare it to your CI tool of choice. What impresses you? What’s lacking?