如何在GitLab CI流水线中向rules规则传递动态变量控制作业执行
问题根因
GitLab CI 的 rules 规则会在流水线初始化阶段完成所有评估,早于任何作业的执行。你当前的写法是在 procession 类作业的 script 段才读取制品文件给 FINAL_FIXABLE 赋值,此时规则判断已经结束,变量值对 rules 完全不生效,因此出现赋值60后逻辑仍然不符合预期的问题。
解决方案
使用 GitLab CI 内置的 dotenv 制品报告能力,将漏洞数量变量从扫描阶段导出,后续作业的 rules 可以直接读取该变量值。具体修改如下:
步骤1:修改扫描结果获取阶段的作业,导出变量
把原来写普通txt文件的逻辑替换为写 .env 格式的变量文件,声明为 dotenv 报告类型:
get results (dev branch): stage: Results of scanning image image: alpine variables: RESULTS: "" STATUS: "" SEVERITY: "" FIXABLE: "" before_script: - apk update && apk upgrade - apk --no-cache add curl jq - chmod +x ./scan-script.sh script: - 'RESULTS=$(curl -H "Authorization: Basic `echo -n ${HARBOR_USER}:${HARBOR_PASSWORD} | base64`" -X GET "https://myregistry/projects/myproject/artifacts/latest?page=1&page_size=10&with_tag=true&with_label=true&with_scan_overview=true&with_signature=true&with_immutable_status=true")' - STATUS=$(./scan-script.sh "STATUS" "$RESULTS") - SEVERITY=$(./scan-script.sh "SEVERITY" "$RESULTS") - FIXABLE=$(./scan-script.sh "FIXABLE" "$RESULTS") - echo "Printing the results of the image scanning process on Harbor registry:" - echo "status of scan:$STATUS" - echo "severity of scan:$SEVERITY" - echo "number of fixable issues:$FIXABLE" - echo "For more information of scan results please visit Harbor registry!" - FINAL_FIXABLE=$FIXABLE # 测试用赋值,验证完成后删除即可 - FINAL_FIXABLE="60" - echo $FINAL_FIXABLE # 写入dotenv格式文件 - echo "FINAL_FIXABLE=$FINAL_FIXABLE" >> scan.env only: refs: - dev - some-test-branch artifacts: # 声明dotenv报告,变量会自动注入后续作业 reports: dotenv: scan.env get results (other branches): stage: Results of scanning image dependencies: - prep for build (other branches) image: alpine variables: RESULTS: "" STATUS: "" SEVERITY: "" FIXABLE: "" before_script: - apk update && apk upgrade - apk --no-cache add curl jq - chmod +x ./scan-script.sh script: - LATEST_TAG=$(cat tags.txt) - echo "Latest tag is $LATEST_TAG" - 'RESULTS=$(curl -H "Authorization: Basic `echo -n ${HARBOR_USER}:${HARBOR_PASSWORD} | base64`" -X GET "https://myregistry/myprojects/artifacts/"${LATEST_TAG}"?page=1&page_size=10&with_tag=true&with_label=true&with_scan_overview=true&with_signature=true&with_immutable_status=true")' - STATUS=$(./scan-script.sh "STATUS" "$RESULTS") - SEVERITY=$(./scan-script.sh "SEVERITY" "$RESULTS") - FIXABLE=$(./scan-script.sh "FIXABLE" "$RESULTS") - echo "Printing the results of the image scanning process on Harbor registry:" - echo "status of scan:$STATUS" - echo "severity of scan:$SEVERITY" - echo "number of fixable issues:$FIXABLE" - echo "For more information of scan results please visit Harbor registry!" - FINAL_FIXABLE=$FIXABLE # 测试用赋值,验证完成后删除即可 - FINAL_FIXABLE="60" - echo $FINAL_FIXABLE # 写入dotenv格式文件 - echo "FINAL_FIXABLE=$FINAL_FIXABLE" >> scan.env only: refs: - master - /^(([0-9]+)\.)?([0-9]+)\.x/ - rc artifacts: reports: dotenv: scan.env
步骤2:修改结果处理阶段的作业,直接使用导出的变量
注意修正正则匹配的写法,GitLab CI 规则里的正则不需要加引号:
procession results (dev branch, case one): stage: Scan results processing dependencies: - get results (dev branch) image: alpine script: - echo $CI_COMMIT_BRANCH - echo $FINAL_FIXABLE rules: - if: ($CI_COMMIT_BRANCH == "dev" || $CI_COMMIT_BRANCH == "some-test-branch") && ($FINAL_FIXABLE == "0") when: always procession results (dev branch, case two): stage: Scan results processing dependencies: - get results (dev branch) image: alpine script: - echo $CI_COMMIT_BRANCH - echo $FINAL_FIXABLE rules: - if: ($CI_COMMIT_BRANCH == "dev" || $CI_COMMIT_BRANCH == "some-test-branch") && ($FINAL_FIXABLE != "0") when: manual allow_failure: true procession results (other branch, case one): stage: Scan results processing dependencies: - get results (other branches) image: alpine script: - echo $CI_COMMIT_BRANCH - echo $FINAL_FIXABLE rules: # 正则不需要加引号 - if: ($CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH == "rc" || $CI_COMMIT_BRANCH =~ /^(([0-9]+)\.)?([0-9]+)\.x/) && ($FINAL_FIXABLE == "0") when: always procession results (other branch, case two): stage: Scan results processing dependencies: - get results (other branches) image: alpine script: - echo $CI_COMMIT_BRANCH - echo $FINAL_FIXABLE rules: # 正则不需要加引号 - if: ($CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH == "rc" || $CI_COMMIT_BRANCH =~ /^(([0-9]+)\.)?([0-9]+)\.x/) && ($FINAL_FIXABLE != "0") when: manual allow_failure: true
可选优化
你可以把4个结果处理作业合并为2个,减少冗余配置:
- 合并dev分支的两个作业,在script段判断变量值走不同逻辑
- 合并其他分支的两个作业,同理
内容的提问来源于stack exchange,提问作者Milica Nikolić
相关产品推荐
相关产品推荐

