Conditional build on GitLab

Technologist focusing on cloud-native technologies, DevOps, CI/CD pipelines, and system observability. His focus revolves around creating technical content, delivering talks, and engaging with developer communities to promote the adoption of modern software practices. With a strong background in software, he has worked extensively with the JVM, applying his expertise across various industries. In addition to his technical work, he is the author of several books and regularly shares insights through his blog and open-source contributions.
Regular readers of this blog know that I'm using Jekyll to generate the static site. I'm using 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:
- After a push containing a change that influences the Docker image, build it
- 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
- Define the two stages
- Define the
buildjob in theimagestage. The job creates the Docker image (via Kaniko) - Define the
pagesjob in thedeploystage. The job generates the site via Jekyll - Build the
masterbranch only - 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:
- only:changes / except:changes
- only:changes / except:changes examples
- GitHub: Running your workflow only when a push affects specific files
Originally published at A Java Geek on May 8th, 2022




