Unable to create a CI pipeline using "only / except : changes"

Viewed 351

I have the following git repo structure:

.
├── docker
│   ├── Dockerfile
│   └── requirements.txt
└── software
    ├── app
    │   └── app.py
    └── Dockerfile

The docker folder is responsible for create a docker image that will be used by my application.

Then if I change some file under the docker folder, I would like to recreate the base image and then create a new app image using the last base image created.

But if I only change my app, under the software folder, I would like to trigger only the stage for the app image.

Below my .gitlab-ci.yml file:

image: docker:latest

services:
    - docker:dind

stages:
    - buildDockerImage
    - buildAppImage

build docker image:
    stage: buildDockerImage
    script:
        - docker login -u $CI_DEPLOY_USER -p $CI_DEPLOY_PASSWORD $CI_REGISTRY
        - docker build --target final --build-arg docker_image_version=$CI_COMMIT_SHORT_SHA -t $DOCKER_IMAGE_NAME docker
        - docker tag $DOCKER_IMAGE_NAME $CI_REGISTRY/xx/$APP_IMAGE_NAME:base
        - docker push $CI_REGISTRY/xx/$APP_IMAGE_NAME
    only:
        changes:
          - docker/**/*

build app image:
    stage: buildAppImage
    script:
        - docker login -u $CI_DEPLOY_USER -p $CI_DEPLOY_PASSWORD $CI_REGISTRY
        - docker build --build-arg app_image_version=$CI_COMMIT_SHORT_SHA -t $APP_IMAGE_NAME software
        - docker tag $APP_IMAGE_NAME $CI_REGISTRY/xx/$APP_IMAGE_NAME:$CI_COMMIT_SHORT_SHA
        - docker push $CI_REGISTRY/xx/$APP_IMAGE_NAME
    except:
        changes:
          - docker/**/*

The only / except : changes works fine to recognize the place of the change, but is not creating a pipeline with both stages if I change the docker folder. It creates only the buildDockerImage.

If I delete the only / except : changes configuration, the pipeline works as expected.

It it possible to achieve what I need ? I mean, I don't want to run the buildDockerImage if I only change my application, but if I do change the base image I need to run both buildDockerImage and buildAppImage in a pipeline.

1 Answers

So if I understand correctly you want to:

  1. Build buildDockerImage only when docker/**/* location changes, so your current yaml for this stage is fine.
  2. Build buildAppImage

    • always, just remove except clause from buildAppImage stage,

    • only for changes to docker locations, replace except with only and 2 locations:

      only:
        changes:
          - docker/**/*
          - software/**/*
Related