GitLab CI在`changes:`字段无匹配文件时仍执行的问题
GitLab CI任务仅在文档变更时触发的配置修正
问题描述
希望GitLab CI任务仅在docs/**/*.md或docs/**/*.mdx文件变更时执行,但配置rules:changes:后,即便无对应文件变更(比如初始创建MR时分支无任何MD/MDX改动),任务仍会运行,调用GitLab API获取变更文件时返回空值。
用户原CI配置:
image: alpine:3.21.2 stages: - test tests: stage: test image: node:20 # Run only if the MR changed some MD or MDX files # But it always runs on the initial MR creation rules: - changes: - 'docs/**/*.md' when: on_success script: # Get comma-separated list of changed files - apt update && apt install -y jq # Call gitlab API to get MR metadata - curl "$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/changes" > results.json # Get all changed files - jq -r '.changes[].new_path' results.json > all_changed_files.txt # Filter to MD/MDX files - touch changed_md_files.txt - grep -E '^.*\.mdx?$' all_changed_files.txt > changed_md_files.txt || echo "NULL" > changed_md_files.txt # Change to comma-separated list - tr < changed_md_files.txt '\n' ',' > comma_separated.txt # Remove trailing comma (important, or else it shows up as a blank item at the end of the list and includes every file) - sed -i 's/,$//' comma_separated.txt # Set an environment variable to use later - export CHANGED_FILES=$(cat comma_separated.txt) - echo $CHANGED_FILES
解决方案
1. 修正rules配置(核心修复)
修改rules部分,补充MDX文件匹配规则,限定仅在MR场景下触发,并添加兜底规则确保非目标场景不执行:
rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' changes: - 'docs/**/*.md' - 'docs/**/*.mdx' when: on_success - when: never
关键说明:
if: '$CI_PIPELINE_SOURCE == "merge_request_event"':限定任务只在MR流水线中触发,避免分支推送等其他场景的误触发- 补全
docs/**/*.mdx匹配规则,覆盖需求中的所有文档类型 - 最后一条
- when: never作为兜底,确保不符合条件的场景下任务完全不运行,解决初始MR创建时的误触发问题
2. 简化脚本(可选优化)
GitLab 13.9及以上版本内置了CHANGED_FILES环境变量,直接包含所有变更文件的逗号分隔列表,无需通过API调用和手动处理。可以将脚本简化为:
# 直接使用内置变量过滤MD/MDX文件 export CHANGED_MD_FILES=$(echo $CHANGED_FILES | tr ',' '\n' | grep -E '^docs/.*\.mdx?$' | tr '\n' ',' | sed 's/,$//') echo $CHANGED_MD_FILES
这样可以省去安装jq、调用API等步骤,提升流水线效率。
原配置失效原因
- 初始创建MR时,GitLab的
changes对比逻辑可能会将分支与目标分支的初始状态(如空分支)对比,导致误判有文件变更 - 原规则未包含
docs/**/*.mdx文件,且没有限定MR场景,也没有兜底规则,导致非目标场景下任务仍会触发
内容的提问来源于stack exchange,提问作者Tim McMackin
相关产品推荐
相关产品推荐

