合并后GitLab流水线中CI_MERGE_REQUEST系列变量缺失问题咨询
问题背景
尝试通过CI_MERGE_REQUEST_LABELS和CI_MERGE_REQUEST_DESCRIPTION预定义变量,控制合并请求(MR)合并到master分支时流水线的执行逻辑。MR包含标签NO_DEPLOY、描述THIS_IS_A_DESCRIPTION,但合并后触发的master分支push流水线中,执行env命令未找到这两个变量,CI配置如下:
image: alpine:latest stages: - test test-merge-request: stage: test script: - $CI_MERGE_REQUEST_DESCRIPTION - $CI_MERGE_REQUEST_LABELS - env rules: - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "master"'
问题解答
1. 这些变量在合并触发的流水线中是否不可用?
是的,CI_MERGE_REQUEST_*系列预定义变量仅在合并请求上下文的流水线中存在,包括:
- MR创建/更新时触发的分支流水线
- MR的合并结果流水线(模拟合并到目标分支的流水线)
当MR合并到master后,触发的是push类型流水线(CI_PIPELINE_SOURCE=push),此时MR已完成合并,相关的MR上下文变量会被清除,因此在这类流水线中无法获取到CI_MERGE_REQUEST_LABELS和CI_MERGE_REQUEST_DESCRIPTION。
2. 是否需要额外配置才能让这些变量生效?
不需要额外配置,但需要调整流水线的触发逻辑:
方案一:在MR流水线中提前处理逻辑(推荐)
如果你的目标是基于MR标签/描述控制合并前的行为(比如决定是否允许合并、是否执行部署),直接将流水线逻辑绑定到MR流水线即可,修改rules条件为MR事件:
image: alpine:latest stages: - test test-merge-request: stage: test script: - echo "MR Description: $CI_MERGE_REQUEST_DESCRIPTION" - echo "MR Labels: $CI_MERGE_REQUEST_LABELS" # 这里可以添加基于标签/描述的逻辑判断,比如判断是否包含NO_DEPLOY标签 - if echo "$CI_MERGE_REQUEST_LABELS" | grep -q "NO_DEPLOY"; then echo "跳过部署"; fi rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
方案二:合并后通过API获取MR信息(如果必须在master流水线中处理)
如果一定要在合并后的master流水线中获取MR的标签和描述,可以通过GitLab API查询当前提交关联的MR信息:
- 提前在项目的设置 > CI/CD > 变量中添加
GITLAB_TOKEN,值为拥有项目API权限的个人访问令牌。 - 修改CI配置如下:
image: alpine:latest stages: - test test-merge-request: stage: test before_script: - apk add --no-cache curl jq script: # 查询当前提交关联的已合并MR MR_RESPONSE=$(curl --silent --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ "$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests?state=merged&sha=$CI_COMMIT_SHA") # 提取MR ID、标签和描述 MR_ID=$(echo "$MR_RESPONSE" | jq -r '.[0].iid') MR_LABELS=$(echo "$MR_RESPONSE" | jq -r '.[0].labels | join(",")') MR_DESCRIPTION=$(echo "$MR_RESPONSE" | jq -r '.[0].description') echo "MR ID: $MR_ID" echo "MR Labels: $MR_LABELS" echo "MR Description: $MR_DESCRIPTION" rules: - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "master"'
方案三:通过合并提交信息传递MR数据
在MR合并时,将标签和描述写入合并提交信息(可通过MR模板或CI自动生成),然后在master流水线中从CI_COMMIT_MESSAGE提取信息。比如设置MR模板要求合并提交包含Labels: NO_DEPLOY,之后在script中用grep提取。
内容的提问来源于stack exchange,提问作者Lucas Raphael

