You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在合并请求事件中按分支推送方式计算Pipeline的only: changes规则?

GitLab Pipeline 按分支提交历史计算变更的配置方案

问题背景

GitLab Pipeline 的 only: changes 规则在两种事件下的行为存在差异:

  • 分支push事件:变更基于上一次提交计算
  • Merge Request(MR)事件:变更基于当前分支与目标分支的合并基准提交(分叉点或最后一次合并提交)计算

当前场景是分支包含业务代码目录app/src和测试代码目录,需要实现以下触发逻辑:

  • 无MR时:仅当app/src目录有提交时触发构建阶段,测试目录变更不触发任何阶段
  • 有MR时:app/src目录提交触发构建+测试;测试目录变更仅触发测试阶段

原配置因为MR事件默认对比合并基准,导致仅提交测试代码时,会误识别出目标分支与当前分支的代码差异,进而触发构建阶段,不符合需求。

解决方案:用rules+compare_to实现自定义变更基准

通过GitLab Pipeline的rules替代only,并利用compare_to参数指定变更对比的基准为当前分支的上一次提交(和push事件逻辑一致),就能实现需求。

修改后的完整配置:

stages:
  - build
  - test

build_job:
  stage: build
  script:
    - echo App building
  rules:
    # 无MR的push事件:仅app/src目录变更时触发
    - if: '$CI_OPEN_MERGE_REQUESTS == null && $CI_PIPELINE_SOURCE == "push"'
      changes:
        - app/src/**/*
    # MR事件:仅当前提交相对于分支上一次提交有app/src变更时触发
    - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^dev\/.*/ && $CI_PIPELINE_SOURCE == "merge_request_event"'
      changes:
        - app/src/**/*
      # 指定对比基准为当前分支的上一次提交,而非合并基准
      compare_to: $CI_COMMIT_BEFORE_SHA
    # web/api手动触发的管道,直接运行构建
    - if: '$CI_PIPELINE_SOURCE == "web" || $CI_PIPELINE_SOURCE == "api"'

tests_job:
  stage: test
  script:
    - echo App testing
  rules:
    # MR事件:app/src变更或测试目录变更时触发
    - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^dev\/.*/ && $CI_PIPELINE_SOURCE == "merge_request_event"'
      changes:
        - app/src/**/*
        - tests/**/*  # 替换为你的实际测试目录路径
      compare_to: $CI_COMMIT_BEFORE_SHA
    # 无MR的push事件:仅当构建触发时(即app/src变更)才运行测试
    - if: '$CI_OPEN_MERGE_REQUESTS == null && $CI_PIPELINE_SOURCE == "push"'
      changes:
        - app/src/**/*
    # web/api手动触发的管道,直接运行测试
    - if: '$CI_PIPELINE_SOURCE == "web" || $CI_PIPELINE_SOURCE == "api"'

关键说明

  1. compare_to参数:在MR事件的规则中指定compare_to: $CI_COMMIT_BEFORE_SHA,让变更对比逻辑和push事件一致——只看当前分支的上一次提交差异,而非和目标分支的合并基准差异。
  2. rules替代only:rules比only更灵活,支持结合条件判断、变更检查和自定义基准,能精准控制任务触发逻辑。
  3. 测试任务触发逻辑:MR下同时监听app/src和测试目录的变更,确保两种场景都能触发测试;无MR时仅在构建触发的前提下运行测试,符合“测试目录变更不触发任何阶段”的要求。

注意事项

  • 请将配置中的tests/**/*替换为你项目实际的测试目录路径
  • compare_to参数要求GitLab版本在13.9及以上,请确认你的GitLab实例版本符合要求
  • 首次提交时CI_COMMIT_BEFORE_SHA为空,但MR场景下分支刚创建,合并基准即为初始提交,不会影响变更计算逻辑

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 19:50:42