GitLab CI rules to fetch or clone

I want to have my pipeline to use “git fetch” most of the time, except when the branch name matches “release-[0-9]+.*$”: I want a “git clone” then. This applies only to merge requests.

I basically had the workflow example from the GitLab doc (only if: $CI_COMMIT_TAG was added):

workflow:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: $CI_COMMIT_TAG
    - if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
      when: never
    - if: '$CI_COMMIT_BRANCH'

To get the correct strategy, I made the following changes:

variables:
  GIT_STRATEGY: "clone"

workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_COMMIT_REF_NAME !~ /^release-[0-9]+.*$/
      variables:
        GIT_STRATEGY: "fetch"
    - if: $CI_COMMIT_TAG
    - if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
      when: never
    - if: '$CI_COMMIT_BRANCH'

It works as before, except it fetches. But it fails to clone when the branch name is “release-9.9.9” for example.

How can I acheive this?

I want to have my pipeline to use “git fetch” most of the time

In that case shouldn’t be fetch in the global variables? And just override with clone in the specific cases? I would also use CI_MERGE_REQUEST_SOURCE_BRANCH_NAME instead of CI_COMMIT_REF_NAME considering this is for MR pipelines (not a branch pipeline) and the source branch must be “release-[0-9]+.*$”.

Something like this?

variables:
  GIT_STRATEGY: "fetch"

workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME	 ~ /^release-[0-9]+.*$/
      variables:
        GIT_STRATEGY: "clone"
    - when: always

Thanks for the suggestion but it clones instead of fetching on commit on an MR.

One question I have is how exactly the if is executed. It seems to me that if none invoke when: never, the pipeline will run. My follow up question is what does it mean to have a variables instruction? Are all if evaluated? In which order?

when the branch name matches “release-[0-9]+.*$”: I want a “git clone” then

Thanks for the suggestion but it clones instead of fetching on commit on an MR.

isn’t it exactly what you asked for?

It seems to me that if none invoke when: never , the pipeline will run

if no rule matches, the pipeline will not run

Are all if evaluated? In which order?

rules are evaluated in the order you define them (from the top), first rule that matches is applied and no further rules are evaluated

@balonik , you had it right. I think other rules in jobs were causing interference, and the additional rules I had in there were triggering, muddying things futher.

Eventually I arrived at this:

variables:
  GIT_STRATEGY: "clone" # default to clone to be safe

workflow:
  # if are evaluated in order until the first match.
  # the job is added for an "if" rule when it also has a positive "when"
  # the job is not added if no rule matches or one says "never"
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_COMMIT_REF_NAME =~ /^release-[0-9]+.*$/
      variables:
        GIT_STRATEGY: "clone"
      when: always
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      variables:
        GIT_STRATEGY: "fetch"
      when: always
    - when: never