skip to Main Content

I am trying to create a base image for my repo that is optionally re-built when branches (merge requests) make changes to dependencies.

Let’s say I have this pipeline configuration:

stages:
  - Test
  - Build

variables:
  - image: main

Changes A:
  stage: Test
  rules:
    - if: '$CI_PIPELINE_SOURCE == "push"'
      changes:
        - path/to/a
  script:
    - docker build -t a .
    - docker push a
    - echo 'image=a' > dotenv
  artifacts:
    reports:
      dotenv: dotenv

Build:
  stage: Build
  image: $image
  script:
    - echo build from $image

Let’s say I push to a new branch and the first commit changes /path/to/a, the docker image is build and pushed, the dotenv is updated and the Build job successfully uses image=a.

Now, let’s say I push a new commit to the same branch. However, the new commit does not change /path/to/a so the Changes A job does not run. Now, the Build stage pulls the "wrong" default image=main while I would like it to still pull image=a since it builds on top of the previous commit.

Any ideas on how to deal with this?

  • Is there a way to make rules.changes refer to origin/main?
  • Any other ideas on how to achieve what I am trying to do?

2

Answers


  1. There is a project setting, which defines how your MR pipelines are setup. This is only working for Merge requests and can be found in Settings -> Merge Requests under the section Merge options

    enter image description here

    1. each commit individually – nothing checked

      this means, each commit is treated on its own, and changes checks are done against the triggering commit on it’s own

    2. Enabled merged results pipeline

      This will merge your MR with the target branch before running the CI Jobs. This also will evaluate all your changes, and take a look at all of them within the MR and not commit wise.

    3. Merge trains

      This is a whole different chapter, and for this usecase not relevant. But for completeness i have to mention it see https://gitlab.com/help/ci/pipelines/merge_trains.md

    What you are looking for is Option 2 – Merged pipeline results. but as i said, this will only work in Merge Request pipelines and not general pipelines. So you would also need to adapt your rules to something like:

    
      rules:
        - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
          changes:
            - path/to/a
        - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    
    
    Login or Signup to reply.
  2. Is there a way to make rules.changes refer to origin/main?

    Yes, there is, since GitLab 15.3 (August 2022):

    Improved behavior of CI/CD changes with new branches

    Improved behavior of CI/CD changes with new branches

    Configuring CI/CD jobs to run on pipelines when certain files are changed by using rules: changes is very useful with merge request pipelines.
    It compares the source and target branches to see what has changed, and adds jobs as needed.

    Unfortunately, changes does not work well with branch pipelines.
    For example, if the pipeline runs for a new branch, changes has nothing to compare to and always returns true, so jobs might run unexpectedly.

    In this release we’re adding compare_to to rules:changes for both jobs and workflow:rules, to improve the behavior in branch pipelines.

    You can now configure your jobs to check for changes between the new branch and the defined comparison branch.
    Jobs that use rules:changes:compare will work the way you expect, comparing against the branch you define.

    This is useful for monorepos, where many independent jobs could be configured to run based on which component in the repo is being worked on.

    See Documentation and Issue.

    You can use it only as part of a job, and it must be combined with rules:changes:paths.

    Example:

    docker build:
     script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
     rules:
       - if: $CI_PIPELINE_SOURCE == "merge_request_event"
         changes:
           paths:
             - Dockerfile
           compare_to: 'refs/heads/branch1'
    

    In this example, the docker build job is only included when the Dockerfile has changed relative to refs/heads/branch1 and the pipeline source is a merge request event.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search