Foojay Today

Conditional Builds on GitLab

May 09, 2022

Regular readers of my articles know that I'm using Jekyll to generate my static blog site, together with GitLab. When I push on the master branch, it triggers the generation job.

However, Jekyll is Ruby-based and requires a couple of Gem dependencies. I've also added a few plugins. For this reason, I've created a Docker image with all required dependencies. Regularly, I update the versions in the Gemfile.lock via Bundler. Afterward, I need to rebuild the Docker image.

Hence, two jobs are necessary:

  1. After a push containing a change that influences the Docker image, build it.
  2. After any push, generate the site.

For the first, the trigger condition is whether any of the following files have been changed: Gemfile.lock, Dockerfile and .gitlab-ci.yml.

The problem is how to run a build only if the condition is met, as it's an expensive and time-consuming operation. GitLab's build file configuration offers a solution for this. In a job, you can configure an only clause to run only if a condition is met. The condition can be:

  • A reference, e.g., a branch, or a tag
  • A trigger, e.g., a push, the web UI or an API call
  • The value of a variable
  • A change on a specific file
  • A couple of others

The next to last option is the answer to our problem. We can configure a set of files, and if any of them has been changed, the build should run. Otherwise, do nothing.

It translates into the following structure:

stages:
  - image                                        # 1
  - deploy                                       # 1

build:                                           # 2
  stage: image                                   # 2
  image:
    name: gcr.io/kaniko-project/executor:debug
    entrypoint: [""]
  script: # Build the Docker image
  only:
    refs:
      - master                                   # 4
    changes:
      - Gemfile.lock                             # 5
      - Dockerfile                               # 5
      - .gitlab-ci.yml                           # 5

pages:                                           # 3
  stage: deploy                                  # 3
  image:
    name: registry.gitlab.com/nfrankel/nfrankel.gitlab.io:latest
  script: # Generate the site
  only:
    refs:
      - master
  1. Define the two stages
  2. Define the build job in the image stage. The job creates the Docker image (via Kaniko)
  3. Define the pages job in the deploy stage. The job generates the site via Jekyll
  4. Build the master branch only
  5. Only build the image if any of these files have changed

At this point, each change triggers the build: the image building job runs before the site generation, but GitLab skips the former if the image hasn't changed.

To go further:

Originally published at A Java Geek on May 8th, 2022

Topics:

Related Articles

View All

Author(s)

  • Nicolas Frankel

    Nicolas is a developer advocate with 15+ years experience consulting for many different customers, in a wide range of contexts (such as telecoms, banking, insurances, large retail and public sector). ... Learn more

Comments (0)

Your email address will not be published.

Highlight your code snippets using [code lang="language name"] shortcode. Just insert your code between opening and closing tag: [code lang="java"] code [/code]. Or specify another language.

Save my name, email, and website in this browser for the next time I comment.

Subscribe to foojay updates:

https://foojay.io/feed/
Copied to the clipboard