Hedgehog
Hedgehog

Reputation: 97

Gitlab MR pipeline to run all regular pipelines

stages:
  - format
  - test

formatter:
  stage: format
  only:
      - merge_requests
  script:
    - echo ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}
    - ancestor=$(git merge-base origin/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME} HEAD)
    - "do some formatting for "git-diff -name-only $ancestor HEAD"

unit_test:
  stage: test
  script:
    - "do some test"

For example, I have the above .gitlab-ci.yml.

Right now

  1. unit-test only runs for the regular commit
  2. format only runs for MR.

As https://docs.gitlab.com/ee/ci/merge_request_pipelines/ says,
"If you use this feature with merge when pipeline succeeds, pipelines for merge requests take precedence over the other regular pipelines.".

What I want is,

  1. Only "test" runs for each commit.
  2. Both "test" and "format" runs for MR, and merge can be approve only if both pipeline succeeds.

How may I achieve this?
Another pre-condition is that I want to use "CI_MERGE_REQUEST_TARGET_BRANCH_NAME" variable, which is only defined with only:[merge-requests] or any similar sorts.

Upvotes: 0

Views: 972

Answers (2)

Reza Ebrahimpour
Reza Ebrahimpour

Reputation: 924

In addition to @danielnelz's answer, I suggest you use workflows and rules to control how the stages should be triggered. (workflow documentation)

Using workflow you can control how pipelines should work or be triggered. For instance, consider the following .gitlab-ci.yml code snippet. With the following workflow, when there is no open merge request for the branch, every stage that is related to branches will be triggered, but none of the merge request-related stages will be triggered. Whenever you create a new merge or open a closed one, the merge request pipeline will be triggered. When you add a commit to an open merge request, by default two pipelines (regular branch and merge request pipelines) will be triggered. But, you can disable duplicate pipelines by adding

- if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
      when: never 

to your workflow. In that case, while the merge request is open, only the merge request-related stages will be triggered. In the following sample, I've provided different types of stages and I hope it can help you to build your own workflow.

...

image: ...

workflow:
  rules:
    - if: '$CI_COMMIT_BRANCH' # All branches
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' # Merge requests
    - if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS' # Disable duplicate pipelines
      when: never
    - if: '$CI_COMMIT_TAG' # All tags

stages:
  ...
  - build
  - test
  - code-analysis
  ...

build:
  stage: build
  script:
    ...
  rules:
    - if: '$CI_COMMIT_BRANCH'
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

test:
  stage: test
  script:
    ...
  rules:
    - if: '$CI_COMMIT_BRANCH'
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: '$CI_COMMIT_TAG'

code-analysis:
  stage: code-analysis
  script:
    ...
  rules:
    - if: '$CI_COMMIT_BRANCH == "develop"'
    - if: '$CI_COMMIT_BRANCH == "master"'
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

Upvotes: 0

danielnelz
danielnelz

Reputation: 5154

You should use rules instead of only as only/except are not in active development any more. And with rules your pipeline will look like this:

stages:
  - format
  - test

formatter:
  stage: format
  script:
    - echo ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}
    - ancestor=$(git merge-base origin/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME} HEAD)
    - "do some formatting for "git-diff -name-only $ancestor HEAD"
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

unit_test:
  stage: test
  script:
    - "do some test"
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: '$CI_COMMIT_BRANCH'

formatter stage is only run on merge-requests and the unit_test stage is run on merge-requests and commits on all branches.

Upvotes: 1

Related Questions