GitLab CI如何同时触发合并请求与指定分支流水线?
解决GitLab CI中同时触发分支更新和合并请求的问题
这个问题我之前也碰到过,GitLab CI的only: refs确实存在特殊的行为限制——当你把merge_requests这类特殊触发关键字和具体分支引用放在同一组refs配置里时,它只会生效第一个匹配的规则,剩下的会被忽略。这是因为merge_requests并不是普通的分支引用,它属于GitLab专门的合并请求流水线触发上下文,和分支直接推送的上下文是分开处理的。
为什么你的配置不生效?
你原来的写法:
only: refs: - /^develop$/ - merge_requests
在这种配置下,当develop分支直接更新时,GitLab匹配到第一个refs项就会触发流水线,但不会检查后面的merge_requests;而当有合并请求时,合并请求的上下文里不存在名为/^develop$/的分支引用,所以会跳过第一个规则,但GitLab并不会继续匹配merge_requests(因为它把整个refs数组视为同一类匹配条件)。反之,如果调换顺序,合并请求会触发,但分支更新不会。
正确的解决方案
推荐使用GitLab CI现在主推的rules语法(only/except已被标记为过时特性),它的条件判断更灵活,每个规则独立生效:
face-build: stage: build image: docker:19.03.8 services: - docker:19.03.8-dind script: - sh some-scripts.sh rules: # 匹配develop分支的直接推送 - if: '$CI_COMMIT_BRANCH == "develop"' when: always # 匹配所有合并请求事件 - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' when: always
如果坚持使用旧的only语法,也可以去掉refs嵌套,直接把分支和merge_requests放在only的顶层数组里(GitLab会自动识别不同的触发类型):
face-build: stage: build image: docker:19.03.8 services: - docker:19.03.8-dind script: - sh some-scripts.sh only: - /^develop$/ - merge_requests
额外说明
- 使用
rules时,你还能添加更细粒度的控制,比如仅触发目标分支为develop的合并请求:- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop"' when: always - GitLab预定义的CI变量(比如
CI_COMMIT_BRANCH、CI_PIPELINE_SOURCE)都可以在规则中使用,用来精准控制流水线的触发时机。
内容的提问来源于stack exchange,提问作者Jake
相关产品推荐
相关产品推荐

