Getting started with Gitlab CISep 10, 2019
Gitlab originally started out as a place to store your Git repositories. Over the past few years it has grown to be much more though. Just like competitor Github it offers project management tooling. However, unlike Github Gitlab also offers Continuous Integration (or CI for short).
With CI you can start automating your build and deploy system. No longer do you need to manually build each version of your project and then manually update running deployments.
Why use CI?
There are many reasons why adding CI to your project is a good idea. I've listed several convincing reasons below.
This one is obvious: once you automate something you won't have to spend time on it anymore. Automating your build and deploy process means you can spend more time doing actual programming. You know, the job you are actually paid for...
Minimize human mistakes
Humans make mistakes. Even the most focused individual will every now and then slip up. This means if you do a thousand deployments manually you are bound to mess up some of them. These mistakes could be innocent or they could really hurt you or the company you work for.
By automating even simple steps which are performed many times you cut out the human factor. Thereby you reduce the risk of messing up.
Every CI system uses some kind of scripting language, configuration file or interface to configure the build and deployment steps. Effectively this is a form of documentation! New programmers will be able to take a look at these tools and understand how a build is made or a deployment is done. This can help decrease the bus factor.
I'll quickly discuss the basics before using a real world example.
This may be obvious but you can only use Gitlab CI if you have your Git repository hosted on Gitlab (or self-hosted Gitlab).
Gitlab CI configuration file
Every CI system has to be configured. Gitlab CI makes use of a single configuration file part of your repository. This file is called
A simple Gitlab CI configuration file looks like this:
stages: - build build: stage: build script: - npm install - npm run build
We define a basic CI street with only one stage: a build stage. Next we define the build stage as the combination of two commands. First we install any NPM packages. Next we run a build command. The exact build command isn't relevant now. This will of course depend on the programming language and framework used.
Note how the build steps are just plain Shell commands. This is what makes Gitlab CI so easy to configure. If you are already comfortable building from a terminal you'll have an easy time porting the steps you currently do manually to Gitlab CI!
Gitlab CI runners
In order to automate your builds and deployments Gitlab CI needs something called a Gitlab Runner. A Gitlab Runner is nothing more than a computer which is accessible to Gitlab. This could be a hosted server on a service like Digital Ocean or AWS. It can also be a computer you've got running at home or at your company. As long as Gitlab can access it you are good to go.
Even better though: Gitlab offers a collection of shared runners free of charge! So if you do not want to set up your own Gitlab Runner at this point you don't even need to.
Because the Gitlab Shared Runners are shared with many other people your builds and deployment will most likely be slower. Also keep in mind if your builds and deployment contain sensitive data running them on a shared runner might not be smart.
A basic example
Gitlab CI doesn't care about which language or framework you use. To help us get started I have therefore chosen a very simple and basic example.
You can find the final code here. I suggest you fork this repository so you can experiment with it.
The configuration file
Let's first take a look at the Gitlab CI configuration file:
image: "node" stages: - build - test build: stage: build script: - npm install - npm run build artifacts: paths: - dist expire_in: 1 day test: stage: test dependencies: - build script: - npm install - npm run test
You'll find we have defined two stages at this point: a build and test stage. We have also defined an image to use when building (
image: "node"). This refers to the Docker NodeJS image we will use to run our build and test in.
build stage will simply install any NPM packages. Next it will run the build command we have defined in our
package.json. Lastly it will upload the build files to Gitlab. All our build files are outputted to the
dist folder so we can simply upload the entire folder. We specify we want these files to expire in 1 day because we don't need them any longer.
test stage will again install any NPM packages (these are lost between stages). Next it will run the test command we defined in our
package.json. Gitlab CI will automatically download any previous build artifacts. In our case this means the
dist folder we previously uploaded will be downloaded again. Because of this we do not need to run the build step again.
Triggering a build
To trigger a build all you need to do is push the repository to Gitlab. Once pushed you can go to the pipelines page to view the current (and previous) builds.
This web page shows you the current running build (and at which stage it is). It allows you to download any available build artifacts. Lastly it shows you previous builds (and if they succeeded or failed).
By selecting a current or previous pipeline you can also view the terminal output. This is useful if a build failed to determine the cause.
Deploying your changes
Actually deploying this application is a bit out of scope. In my opinion Gitlab CI shines when it comes to building and testing your project. As a deployment tool though it can feel a bit clunky at times.
It is certainly possible to handle your deployment with Gitlab CI as well. However Gitlab CI does not currently have any features which you might expect from a deployment tool (think scheduled deployment or automatic rollbacks).
If you are really committed to doing your deployments with Gitlab CI you could consider using a combination of SFTP and SSH to copy your files to your server and trigger a restart.
Looking at the configuration file we use now you would need to add a third stage called
deploy. This stage would run after the
test stage so only successfully built and tested commits are deployed.
I have shown you the basics on how to get started with Gitlab CI using a simple NodeJS application. The Gitlab CI configuration file used could easily be tweaked so it targets other languages or frameworks. The basics remain the same.
Want to learn more about Gitlab CI? Check out my other articles about this subject!