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:
- 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
build
job in theimage
stage. The job creates the Docker image (via Kaniko) - Define the
pages
job in thedeploy
stage. The job generates the site via Jekyll - Build the
master
branch 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