gitlabgitlab-ci

Does GitLab's `rules:changes` allow for both relative and absolute paths?


Taking this example directly from the documentation.

docker build:
  script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      changes:
        - Dockerfile
  1. Is this reference to Dockerfile is an absolute (from the root of the repository) reference to /Dockerfile or is it a reference to **/Dockerfile (zero or more directories deep)?
  2. If this is an absolute reference, how can I specify the **/Dockerfile version?
  3. Else, if this is aa reference to **/Dockerfile, how do I specify the absolute /Dockerfile version?

Solution

  • GitLab says artifact paths there are relative to the root of the project directory. Which you may think of as "absolute" for simplicity's sake.

    The path Dockerfile matches /Dockerfile with / being your project's directory.

    If you want to know the details

    Technically in a GitLab CI/CD pipeline your code gets checked out on some computer by a program called a GitLab Runner (program who runs your pipelines).

    The Runner does not copy your project files to the machine's filesystem root. So obviously, your Dockerfile is not /Dockerfile on the computer' or container's filesystem.

    The really absolute path would be /builds/my-group/my-project/Dockerfile inside the Runner's Docker container (source).

    How can you tell that path behaviour from the docs

    • it says it in rules:exists: "Paths are relative to the project directory ($CI_PROJECT_DIR) and can’t directly link outside it."

    • it says the same in artifacts:paths as well

    Under the hood in your example you're specifying a paths key, too: rules:changes:paths. You're just using the shorthand notation there as the last bullet point below the example states.


    Extra info about matching files

    To match files anywhere in the project (zero or more directories deep) you need to use wildcard characters and wrap the path in double quotes: "**/Dockerfile" (last point before the example in the linked docs).

    The wrapping in double quotes is prescribed by the documentation, because else the YAML parser might misinterpret your path as a YAML alias referencing a YAML anchor defined with &*/Dockerfile (yes, * and / are valid there). I guess you don't have such a YAML anchor defined, but it's good to take this precaution.