gitlabgitlab-ci

Can I run a job when the pipeline is an MR _and_ no changes are being made to a specified path?


In GitLab CI, I can specify that a job should run if the pipeline is for a merge request. I can also run a job if changes are being made to a certain file (or set of files). This I would do with the following rules:

Check Changelog Existence:
  script:
    - echo "Changelog files exist"
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      changes:
        - changelogs/unreleased/**/*

This is fine and dandy... but what I actually want to do is almost the exact opposite. That is, I want a job to fail if a merge request does NOT have changelog entry files.

Is there some way for me to do that, preferably using the GitLab CI DSL? I know I can perform some hoop jumping and do this in the script but that is a bit messy and I'd prefer to do it using only the GitLab CI YAML if possible.

The following GitLab CI YAML does work for me, but as I said, I would like to know if this can be achieved without resorting to manually run the git CLI in a script.

Check Changelog Existence:
  image: alpine/git
  variables:
    GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task
  script:
    - git --no-pager diff --name-status remotes/origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME | grep ^A | grep changelogs/unreleased/  # Ensure that some files have been added to the unreleased changelog path
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: always

Solution

  • You could use rules:variables to set variable that has suitable value depending on changes you want to check or use rules:when to skip job when changes exist. The problem with these is that you can not specify the type of changes, like you have done with git and grep, so you could not determine if the change added, modified or removed a file.

    Fail job if changes were not found:

    Check Changelog Changes:
      script:
        - if [ "$CHANGELOG_CHANGES" == "no" ]; then exit 1; fi;
      rules:
        # Matches merge requests that have the required changes
        - if: $CI_PIPELINE_SOURCE == "merge_request_event"
          changes:
            - changelogs/unreleased/**/*
          variables:
            CHANGELOG_CHANGES: "yes"
          # Or add 'when: never' here to not trigger this job at all
        # Matches all other merge requests
        - if: $CI_PIPELINE_SOURCE == "merge_request_event"
          variables:
            CHANGELOG_CHANGES: "no"
    

    Only run job if changes were not found:

    Check Changelog Changes:
      script:
        - echo "No specified changes found."
      rules:
        # Matches merge requests that have the required changes
        - if: $CI_PIPELINE_SOURCE == "merge_request_event"
          changes:
            - changelogs/unreleased/**/*
          when: never
        # Matches all other merge requests
        - if: $CI_PIPELINE_SOURCE == "merge_request_event"