GitLab CI如何检测提交变更顶层目录并设为跨阶段流水线变量
可行性结论
完全可以实现,不需要接入额外第三方工具,使用GitLab CI原生的跨任务变量传递能力配合基础Git命令即可满足需求。
实现步骤
核心原理
普通脚本内定义的Shell变量默认只在当前任务内生效,要跨阶段复用变量,需要使用GitLab CI原生支持的dotenv制品报告机制:前置任务将变量写入固定格式的env文件,声明为dotenv报告后,后续所有阶段的任务都可以直接读取到这些变量。
完整配置示例
首先调整流水线阶段顺序,把变更检测放在所有业务阶段最前面,配置参考如下:
stages: - detect-changes - deploy # 原有其他阶段(如build、test)可按顺序追加在后面 # 顶层目录检测任务 detect_changed_dir: stage: detect-changes image: alpine/git:latest script: # 区分合并请求、普通提交两种场景,获取本次变更的文件列表 - | if [ -n "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then # 合并请求场景:对比当前分支与目标分支的差异 git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME --depth=50 CHANGED_FILES=$(git diff --name-only origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME...HEAD) else # 普通分支提交场景:对比当前提交与上一版本的差异 if [ $CI_COMMIT_BEFORE_SHA == "0000000000000000000000000000000000000000" ]; then # 兜底处理分支首次提交无历史提交的场景 CHANGED_FILES=$(git diff --name-only HEAD) else CHANGED_FILES=$(git diff --name-only $CI_COMMIT_BEFORE_SHA HEAD) fi fi # 提取第一个变更文件的顶层目录,已确认不存在跨顶层目录多文件变更场景,直接取首个结果即可 - MYVAR=$(echo "$CHANGED_FILES" | grep -v '^$' | head -n1 | cut -d'/' -f1) # 异常校验:如果没提取到有效目录直接终止流水线 - if [ -z "$MYVAR" ]; then echo "未检测到有效顶层目录变更"; exit 1; fi # 将变量写入dotenv要求的格式文件 - echo "MYVAR=$MYVAR" > dir.env artifacts: reports: dotenv: dir.env expire_in: 3 days # 原有部署任务无需额外配置,直接调用变量即可 MEP: stage: deploy script: - echo $MYVAR # 后续业务逻辑可直接使用$MYVAR传参
效果验证
- 当提交修改
folder1/file1.txt时,检测任务会提取到顶层目录folder1,后续MEP任务中$MYVAR值即为folder1 - 当提交修改
folder2/folder3/file4.txt时,检测任务会提取到顶层目录folder2,后续MEP任务中$MYVAR值即为folder2
注意:如果你的流水线默认开启了浅克隆,在拉取代码的配置里不要把git fetch深度设得太小,避免对比差异时找不到历史提交记录导致检测失败。
内容的提问来源于stack exchange,提问作者Arckain
相关产品推荐
相关产品推荐

