Run pipeline for files that changed in subdirectory

I have a single repo with a Dockerfile that serves as a template for my containers. In this repo are multiple subdirectories that each contain at least a ‘index.html’ file:


Now if I make changes to directory02/index.html I want to use the Dockerfile as a template, copy the index.html from ‘directory02’ and push an image named ‘directory02’ to some registry. The same should happen for ‘directory01’ but the name of the image should be ‘directory01’.
So far I’ve only found a way to hardcode a job for every directory and only run a pipeline if changes where made in this directory. This approach seems impractical as I might have a hundred directories.
Is there a way to create a pipeline that can do this?
Thank you

Hey there,

Huh, using only GitLab CI config keywords - impossible AFAIK (as with “changes” you need to strictly define either folder names or file names… so maybe you could somehow get away with this, depends)

But, I had similar situation and I’ve implemented manual git changes checking. Again, depends a bit when exactly are you running the pipeline (on a feature branch, on MR, or after merge to main, etc), but perhaps you can use it as inspo.

So, I’m running a pipeline on main and my logic was the following:

  1. Detect which folders have changed (comparing current commit and previous commit on main) using git diff / git rev-parse
  2. Filter this output if needed (remove unnecessary folders if any)
  3. Loop through folders and do whatever you need

Simplified version of my CI implementation:

  stage: package
  # I guess you will use docker if you're building docker image, but I think that does not matter, bash you still have ;)
  image: ubuntu:jammy
    - apt-get update && apt-get install -y git
    - prev_commit=$(git rev-parse origin/main~1)
    # with awk I'm taking the folder name out of the list of files and doing a unique on it so folders are not repeated, excluding folders with name test
    - n=($(git diff --name-only $CI_COMMIT_SHA $prev_commit | awk -F / '{ print $1 }' | uniq | awk '!/test/'))
    - |
      for i in "${n[@]}"
        if [[ -d $i ]] ; then
          echo "Preparing folder $i"
          # here you implement your logic for every folder, ie. copy Dockerfile into it, build it, whatever
    - main

Hope this helps! :slight_smile: