最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

gitlab - Auto merge happens without waiting for all pipelinesjobs to finish - Stack Overflow

programmeradmin3浏览0评论

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
  • This sounds very weird. I was expecting to find a optional keyword or something, but that is not the case. I only saw that you are using except and only, 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
  • @MichaelKotzjan can you write an example what would be an equivalent to run two parallel jobs that must both be successful for auto-merge to work with those rules? – Andrius Commented Mar 18 at 11:51
Add a comment  | 

1 Answer 1

Reset to default 0

As 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

发布评论

评论列表(0)

  1. 暂无评论