Async Drink

Limit Gitlab CI pipelines to specific branches

Sep 28, 2019

We previously talked about how to setup Gitlab CI for your project. In this article we will discuss how to limit pipelines to certain branches.

Limiting pipelines to certain branches is, in my experience, most useful if you use a Git branching model like this one. In short you'd have set up your projects to have a master and develop branch. Next you also use feature, hotfix and release branches to write, fix and release functionality.

Say we have a simple project with three types of branches:

  • master: this is our tested and ready to release work.
  • develop: contains new finished features which have not yet been released.
  • feature/*: these are new features which are currently being build.

For each of these branches we want our build process to look slightly different. In fact we'd want the following behavior:

  • For feature/* branches we want to create a development build and test the project.
  • For the develop branch we want to create a development build, test the project and do a deployment to the staging environment.
  • For the master branch we want to build a production build, test the project and create a deployment to the production environment.

As you'll see all branches share a similar pipe line. All branches will build and test the project. The develop and master branches on top of this will also do a deployment.

Let's take a look at the Gitlab CI configuration file before we introduce branch limitations.

stages:
  - build
  - test
  - deploy

build:
  stage: build
  script:
    - ./build.sh development
  artifacts:
    paths:
      - dist

test:
  stage: test
  script:
    - ./test.sh

deploy:
  stage: deploy
  script:
    - ./deploy.sh staging

We've defined a configuration which includes three stages: build, test and deploy. We've also defined three jobs reflecting these stages. The script which is run is not relevant. Just pretend it runs super complex logic to build, test and deploy the project.

All jobs are now run for every branch. To get started let's limit the deploy stage so it only runs for the develop branch:

deploy:
  stage: deploy
  only:
    - develop # Limit this job to the develop branch
  script:
    - ./deploy.sh staging

We use the only keyword here. This indicates we only want this specific job to run for the given list of branches. The opposite of the only keyword is the except keyword. This indicates we want to run a job for every branch except the ones we defined.

The above implementation isn't complete yet. We want the deploy job to also run for the master branch. Here is what you can do:

deploy_develop:
  stage: deploy
  only:
    - develop # Limit this job to the develop branch
  script:
    - ./deploy.sh staging # Deploy to the staging environment

deploy_master:
  stage: deploy
  only:
    - master # Limit this job to the master branch
  script:
    - ./deploy.sh production # Deploy to the production environment

We've split the job into two version. One for the develop branch and the other for the master branch. Next we've changed the script tag so it does a deployment to the staging environment for the develop branch and to the production environment for the master branch.

To finish up we also need to change the build stage:

build_development:
  stage: build
  except:
    - master # All branches except master
  script:
    - ./build.sh development
  artifacts:
    paths:
      - dist

build_production:
  stage: build
  only:
    - master # Only on the master branch
  script:
    - ./build.sh production
  artifacts:
    paths:
      - dist

Again we've created two version of the build job. The first will run for all branches except the master branch. The second will run for only the master branch.

When we put everything together our new Gitlab CI configuration file will look like this:

build_development:
  stage: build
  except:
    - master # All branches except master
  script:
    - ./build.sh development
  artifacts:
    paths:
      - dist

build_production:
  stage: build
  only:
    - master # Only on the master branch
  script:
    - ./build.sh production
  artifacts:
    paths:
      - dist

test:
  stage: test
  script:
    - ./test.sh

deploy_develop:
  stage: deploy
  only:
    - develop # Limit this job to the develop branch
  script:
    - ./deploy.sh staging # Deploy to the staging environment

deploy_master:
  stage: deploy
  only:
    - master # Limit this job to the master branch
  script:
    - ./deploy.sh production # Deploy to the production environment

That's it! We've touched on the basics of branch limiting in Gitlab CI. Using these techniques you will quickly be able to create complex pipelines for all your development needs!

Got any feedback or questions? Or just want to send me a message? You can contact me at info@asyncdrink.com
© Copyright 2019 by Mathyn