I have two different "stages" that run in parallel and I want both of them to be successful, to merge the merge request. But I am not sure which options or what kind of CI setup to use, to achieve that.
If I specify "auto merge" then it automatically merge PR just after first successful "stage" that was running, without waiting for other parallel jobs to finish.
In GitHub, it's quite straightforward. You can simply specify which workflows are required to be successful and have to actually run. If any of those fail, auto merge does not happen. Is there something similar with GitLab?
This is my .gitlab-ci.yml
:
---
image: MY-IMAGE
services:
- name: docker:dind
variables:
DOCKER_DRIVER: overlay2
DOCKER_HOST: tcp://docker:2375
stages:
- pre-commit
- build_test
- push
pre-commit:
stage: pre-commit
image: python:3.9
needs: [] # to start without waiting for any other stage.
variables:
PRE_COMMIT_HOME: ${CI_PROJECT_DIR}/.cache/pre-commit
before_script:
- pip install pre-commit
- pre-commit install
cache:
paths:
- ${PRE_COMMIT_HOME}
script:
- >
CHANGED_FILES=$(git diff --name-only $CI_MERGE_REQUEST_DIFF_BASE_SHA
$CI_COMMIT_SHA)
- echo "CHANGED_FILES is $CHANGED_FILES"
- echo "CI_COMMIT_SHA is $CI_COMMIT_SHA"
- echo "CI_MERGE_REQUEST_DIFF_BASE_SHA $CI_MERGE_REQUEST_DIFF_BASE_SHA"
- >
pre-commit run --show-diff-on-failure --color=always
--files $CHANGED_FILES
except:
- "15.0"
only:
- merge_requests
build_test:
stage: build_test
needs: [] # to start without waiting for any other stage.
variables:
GIT_SUBMODULE_STRATEGY: normal
script:
- >
docker buildx build
--pull
--cache-from $CR_REPO_NAME:15.0
--build-arg GIT_COMMIT_SHA=$CI_COMMIT_SHORT_SHA
--tag local/my-myapp:dev
.
- docker compose -f docker-compose.test.yml run --rm sut /opt/myapp/test-myapp
- docker tag local/my-myapp:dev $CR_REPO_NAME:cmt-$CI_COMMIT_SHA
- docker push $CR_REPO_NAME:cmt-$CI_COMMIT_SHA
So when pre-commit
finishes, auto-merge is triggered, without waiting for build_test
stage. I could add dependency for build_test
, to start after pre-commit finishes, but then it would take it longer, because these stages are independent and I don't really need to wait before starting the other.
I also checked "Pipelines must succeed" option, but I guess the way my CI is set up, it treats it as a single pipeline, so whenever first stage finishes, GitLab thinks whole pipeline succeeded.
I have two different "stages" that run in parallel and I want both of them to be successful, to merge the merge request. But I am not sure which options or what kind of CI setup to use, to achieve that.
If I specify "auto merge" then it automatically merge PR just after first successful "stage" that was running, without waiting for other parallel jobs to finish.
In GitHub, it's quite straightforward. You can simply specify which workflows are required to be successful and have to actually run. If any of those fail, auto merge does not happen. Is there something similar with GitLab?
This is my .gitlab-ci.yml
:
---
image: MY-IMAGE
services:
- name: docker:dind
variables:
DOCKER_DRIVER: overlay2
DOCKER_HOST: tcp://docker:2375
stages:
- pre-commit
- build_test
- push
pre-commit:
stage: pre-commit
image: python:3.9
needs: [] # to start without waiting for any other stage.
variables:
PRE_COMMIT_HOME: ${CI_PROJECT_DIR}/.cache/pre-commit
before_script:
- pip install pre-commit
- pre-commit install
cache:
paths:
- ${PRE_COMMIT_HOME}
script:
- >
CHANGED_FILES=$(git diff --name-only $CI_MERGE_REQUEST_DIFF_BASE_SHA
$CI_COMMIT_SHA)
- echo "CHANGED_FILES is $CHANGED_FILES"
- echo "CI_COMMIT_SHA is $CI_COMMIT_SHA"
- echo "CI_MERGE_REQUEST_DIFF_BASE_SHA $CI_MERGE_REQUEST_DIFF_BASE_SHA"
- >
pre-commit run --show-diff-on-failure --color=always
--files $CHANGED_FILES
except:
- "15.0"
only:
- merge_requests
build_test:
stage: build_test
needs: [] # to start without waiting for any other stage.
variables:
GIT_SUBMODULE_STRATEGY: normal
script:
- >
docker buildx build
--pull
--cache-from $CR_REPO_NAME:15.0
--build-arg GIT_COMMIT_SHA=$CI_COMMIT_SHORT_SHA
--tag local/my-myapp:dev
.
- docker compose -f docker-compose.test.yml run --rm sut /opt/myapp/test-myapp
- docker tag local/my-myapp:dev $CR_REPO_NAME:cmt-$CI_COMMIT_SHA
- docker push $CR_REPO_NAME:cmt-$CI_COMMIT_SHA
So when pre-commit
finishes, auto-merge is triggered, without waiting for build_test
stage. I could add dependency for build_test
, to start after pre-commit finishes, but then it would take it longer, because these stages are independent and I don't really need to wait before starting the other.
I also checked "Pipelines must succeed" option, but I guess the way my CI is set up, it treats it as a single pipeline, so whenever first stage finishes, GitLab thinks whole pipeline succeeded.
Share Improve this question edited Mar 16 at 14:25 jonrsharpe 122k30 gold badges268 silver badges476 bronze badges asked Mar 16 at 14:12 AndriusAndrius 21.2k47 gold badges154 silver badges264 bronze badges 2 |1 Answer
Reset to default 0As I have no idea why gitlab is behaving like it is I can only suspect the usage of except
and only
as they are deprecated according to the documentation.
I tried to rewrite you configuration to use rules:
---
image: MY-IMAGE
services:
- name: docker:dind
variables:
DOCKER_DRIVER: overlay2
DOCKER_HOST: tcp://docker:2375
stages:
- pre-commit
- build_test
- push
pre-commit:
stage: pre-commit
image: python:3.9
needs: [] # to start without waiting for any other stage.
variables:
PRE_COMMIT_HOME: ${CI_PROJECT_DIR}/.cache/pre-commit
before_script:
- pip install pre-commit
- pre-commit install
cache:
paths:
- ${PRE_COMMIT_HOME}
script:
- >
CHANGED_FILES=$(git diff --name-only $CI_MERGE_REQUEST_DIFF_BASE_SHA
$CI_COMMIT_SHA)
- echo "CHANGED_FILES is $CHANGED_FILES"
- echo "CI_COMMIT_SHA is $CI_COMMIT_SHA"
- echo "CI_MERGE_REQUEST_DIFF_BASE_SHA $CI_MERGE_REQUEST_DIFF_BASE_SHA"
- >
pre-commit run --show-diff-on-failure --color=always
--files $CHANGED_FILES
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- when: never
build_test:
stage: build_test
needs: [] # to start without waiting for any other stage.
variables:
GIT_SUBMODULE_STRATEGY: normal
script:
- >
docker buildx build
--pull
--cache-from $CR_REPO_NAME:15.0
--build-arg GIT_COMMIT_SHA=$CI_COMMIT_SHORT_SHA
--tag local/my-myapp:dev
.
- docker compose -f docker-compose.test.yml run --rm sut /opt/myapp/test-myapp
- docker tag local/my-myapp:dev $CR_REPO_NAME:cmt-$CI_COMMIT_SHA
- docker push $CR_REPO_NAME:cmt-$CI_COMMIT_SHA
I left out the except
keyword as I do not know what you intended to do with
except:
- "15.0"
This answer is untested, but pre-commit
should now only run in merge requests
optional
keyword or something, but that is not the case. I only saw that you are usingexcept
andonly
, but according to the documentation these are deprecated: docs.gitlab/ci/yaml/#only--except You should use rules instead docs.gitlab/ci/yaml/#rulesif – Michael Kotzjan Commented Mar 18 at 8:58