不同 GitLab CI 合并请求规则之间的区别

Posted

技术标签:

【中文标题】不同 GitLab CI 合并请求规则之间的区别【英文标题】:Difference between different GitLab CI Merge Request rules 【发布时间】:2022-01-14 08:05:24 【问题描述】:

作为其他几位用户,我遇到了duplicate pipelines in GitLab CI/CD 的问题。虽然有一些关于如何防止这种分散在 GitLab 文档中的文档, 我的印象是各个文档页面和部分相当不一致。

我的问题是,以下规则有什么区别?或者,更具体地说,是否存在对这些规则进行不同评估的情况?

Switch between branch pipelines and merge request pipelines 建议这样做来识别合并请求管道:

if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

此外,Switch between branch pipelines and merge request pipelines 也将此规则与$CI_COMMIT_BRANCH && 结合使用:

if: '$CI_OPEN_MERGE_REQUESTS'

此外,MergeRequest-Pipelines.gitlab-ci.yml 使用第三条规则:

if: $CI_MERGE_REQUEST_IID

非常感谢我可能忽略的文档页面的任何解释或提示。

【问题讨论】:

【参考方案1】:

为了避免重复创建管道以及您想要在分支管道和合并请求管道之间切换的要求,我建议使用这些workflow rules

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

还有另一个 SO-question 询问如何防止重复管道here

解释:

在下一节中,我将尝试解释您的不同规则以及 GitLab CI 在管道创建期间将如何评估它们。

merge_request_event-规则

使用这条规则:

if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

每次创建/更新合并请求时都会创建一个管道,但如果您没有其他预防机制(规则),也会为分支创建一个管道。 正如变量命名所指出的,这是关于管道触发器的来源,其他来源可能是schedulepushtrigger 等。

CI_OPEN_MERGE_REQUESTS 变量:

使用如下规则:

if: '$CI_OPEN_MERGE_REQUESTS'

如果此分支有开放的合并请求,GitLab 将创建新的管道。管道,因为将有一个合并请求管道(用 detached 标志表示)和一个分支管道用于您推送更改的分支。

if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'

当且仅当该分支上存在打开的 MR 时,上述规则将为您的分支创建管道。

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

使用上述组合时,如果该分支上有打开的合并请求,则不会创建管道,这也可能是不可取的,因为 CI 应该为分支和/或合并请求运行测试。

但是如何能够为 MR 和 Branches 提供管道,同时防止管道创建中的重复?

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

使用上面设置的这条规则,GitLab 将为分支和合并请求(detached 的)创建管道,以及为 git-tags 创建管道,但它会阻止 GitLab 复制管道。 当有提交到分支或有 git-tag 时,最后一条规则评估为 true。

更多链接

官方docs 在 MR 和 Branch-Pipelines 之间切换 有关如何avoid 使用规则示例复制管道的文档

【讨论】:

谢谢,我想我知道$CI_PIPELINE_SOURCE == "merge_request_event"$CI_OPEN_MERGE_REQUESTS 之间的区别。您的答案未解决的一点是$CI_MERGE_REQUEST_IID 变量,在official workflow for MR pipelines 中使用。你知道$CI_MERGE_REQUEST_IID$CI_OPEN_MERGE_REQUESTS有什么区别吗? 对于我们的工作流程,我们使用以下规则yaml workflow: rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"' when: never - when: always 这样,我们还希望运行计划的或手动的管道。这个配置会不会有什么问题? 使用规则if: $CI_MERGE_REQUEST_IID与对变量进行非空检查基本相同。这意味着,如果变量不为空(当当前分支不存在 MR 时就是这种情况),则将创建一个管道。您的工作流程是处理工作限制的有效方式,但我认为在某些情况下您的工作流程可能会创建重复的管道,例如一个标记的提交被推送到一个没有打开 MR 的分支。但可能是我对这个假设有误

以上是关于不同 GitLab CI 合并请求规则之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

来自 gitlab-ci 的状态不再显示在 gitlab 合并请求中

在 GitLab CI 中,合并请求的目标分支是不是有变量?

为合并请求触发的管道运行应用 GitLab CI/CD 管道更改

如何让 Gitlab CI 管道始终运行一些作业,而其他作业仅在合并请求上运行?

GitLab Runner CI/CD 中用户模式和系统模式之间的区别

gitlab-ci 运行器中具有不同到期时间的多条路径