GitLab CI/CD流水线两种rules规则写法是否等效?
结论
这两种写法完全不等效,绝对不能直接替换,二者的执行逻辑存在本质差异,错误替换会导致流水线job触发逻辑完全不符合预期。
两种配置的实际逻辑拆解
GitLab CI/CD的rules规则是从上到下顺序评估,命中第一条符合条件的规则后立刻终止匹配,不会继续评估后续规则;如果单条规则没有显式指定when参数,默认值为on_success(仅当前置依赖job全部执行成功时,当前job才会运行),不会继承后续规则的when配置。
原始配置的执行逻辑
job: script: echo "This job does NOT create double pipelines!" rules: - if: $CI_PIPELINE_SOURCE == "push" when: never - when: always
逻辑非常明确:
- 如果流水线是
push事件触发:命中第一条规则,when: never,当前job直接不加入流水线,不会执行 - 如果流水线是其他来源触发(比如合并请求、定时任务、API触发、手动触发等):第一条规则不命中,顺延命中第二条无判断条件的通用规则,
when: always,当前job一定会加入流水线,无论前置依赖job是成功、失败还是被取消,都会执行
待验证的“简化版”配置的执行逻辑
job: script: echo "This job does NOT create double pipelines!" rules: - if: $CI_PIPELINE_SOURCE != "push" - when: always
这个配置的实际逻辑和原始版本几乎完全相反:
- 如果流水线是
push事件触发:第一条$CI_PIPELINE_SOURCE != "push"判断不成立,顺延命中第二条规则,when: always,job无论前置状态如何都会执行——和原始配置“push事件下不执行job”的逻辑完全反过来了 - 如果流水线是其他来源触发:第一条判断直接命中,因为没有显式指定
when,取默认值on_success,当前job只有在所有前置依赖job都成功的情况下才会执行,根本不会走到第二条when: always规则——和原始配置“非push事件下无论前置状态如何都执行job”的逻辑也不一致
正确的简化写法
如果要简化原始配置,可以直接删掉多余的通用规则,给判断条件显式指定when: always即可,效果和原始配置完全一致:
job: script: echo "This job does NOT create double pipelines!" rules: - if: $CI_PIPELINE_SOURCE != "push" when: always
这个写法的逻辑是:非push触发时命中规则,when: always执行job;push触发时没有命中任何规则,GitLab CI默认会将job置为不执行(等价于when: never的效果),和原始配置逻辑完全对齐。
如果使用的GitLab版本较老,建议在规则末尾补一条
when: never做显式声明,避免不同版本默认行为差异带来的问题:job: script: echo "This job does NOT create double pipelines!" rules: - if: $CI_PIPELINE_SOURCE != "push" when: always - when: never
内容的提问来源于stack exchange,提问作者Huy Tran
相关产品推荐
相关产品推荐

