You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

GitLab CI中如何通过Rules实现「合并请求至Master分支且存在Commit Tag」双条件触发Job执行?

解决GitLab CI中rules条件同时满足的问题

首先,咱们得先搞清楚你遇到问题的核心原因——GitLab的不同流水线类型是互斥的,对应的环境变量也不会同时存在

  • CI_MERGE_REQUEST_TARGET_BRANCH_NAME 这个变量只在合并请求(MR)流水线里生效(也就是创建或更新MR时触发的流水线);
  • CI_COMMIT_TAG 这个变量只在标签流水线里生效(给提交打tag并推送后触发的流水线)。

这两种流水线是完全独立的,不会同时运行,所以你第一个写法里的&&条件永远不可能成立——根本不存在一个流水线同时包含这两个变量的情况,这就是配置失效的直接原因。

再说说你拆分的两个if规则写法:这种写法其实是逻辑或的效果,完全不是你想要的“同时满足”。GitLab的rules是按顺序匹配的,只要有一个规则符合条件,job就会执行(默认when: on_success)。所以这个配置会导致:只要有MR到master,或者只要有tag流水线,job都会跑,完全不符合你的需求。

正确的解决方案(分场景)

首先得明确你的真实需求,因为“MR到master且提交有tag”在GitLab的流水线模型里本身是矛盾的,下面是两种常见的修正后的需求及实现:

场景1:MR目标分支是master,且MR源分支的最新提交被打了tag

如果你是想在MR流水线里,检查当前MR的源分支最新提交是否带有tag,那可以在job的脚本里手动检查(因为MR流水线里没有CI_COMMIT_TAG变量):

job1:
  script:
    - |
      # 获取当前MR源分支最新提交的SHA,查询是否有tag指向它
      TAG=$(git ls-remote --tags origin | grep "$CI_MERGE_REQUEST_SOURCE_BRANCH_SHA" | awk '{print $2}' | sed 's/refs\/tags\///')
      if [ -z "$TAG" ]; then
        echo "当前MR的源提交没有关联tag,终止job"
        exit 1
      fi
    - echo "Do some stuff ..."
  rules:
    - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'
      when: on_success
    - when: never # 其他情况不执行job

场景2:调整需求为“MR到master,或者提交有tag时执行”

如果你其实是想两种场景都执行job(只是之前表述错了),那可以用||把条件合并成一个rule:

job1:
  script:
    - echo "Do some stuff ..."
  rules:
    - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" || $CI_COMMIT_TAG != ""'

排查思路总结

  1. 先确认变量的生效范围:GitLab的CI变量都有特定的适用流水线类型,一定要先明确变量的适用场景,避免把互斥变量放在同一个条件里。
  2. 理解rules的匹配逻辑:rules是按顺序匹配的,每个rule是独立判断,多个rule默认是“或”的关系;如果要实现“与”的逻辑,要么把条件写在同一个if里(前提是变量能同时存在),要么在脚本里补充检查。
  3. 梳理真实需求:如果原需求的两个条件在GitLab流水线模型里互斥,那得调整需求或者换用脚本检查的方式实现。

内容的提问来源于stack exchange,提问作者evermean

火山引擎 最新活动