Limit Gitlab CI pipelines to specific branches
Sep 28, 2019We 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!