如何能够将变量传递给 gitlab ci 管道中的规则?
Posted
技术标签:
【中文标题】如何能够将变量传递给 gitlab ci 管道中的规则?【英文标题】:How to be able to pass variable to rules in gitlab ci pipeline? 【发布时间】:2021-12-24 17:30:42 【问题描述】:我想在我的 GitLab CI 管道中使用规则来检查是否从所需的分支提交了提交,以及我在 Harbor 注册表上推送的图像中是否有任何可修复的问题。
我将该映像推送到注册表并在 Harbor 注册表上扫描该映像,然后在之前的阶段获得这些结果,现在我希望能够检查该映像中是否有任何可修复的问题,如果有的话我会喜欢手动创建该作业,但留下继续执行管道和此后其他阶段的可能性。如果我没有发现任何这些问题(我的 API 输出表单中没有它),我只需将该变量设置为 0,然后我将继续正常执行管道。用于管道中可修复问题的变量称为 FIXABLE,我尝试了多种方法来为该变量分配值,因此规则可以读取该变量的值,但这些都不起作用。我将在下面发布 mu 的最新作品,以便任何有想法或建议的人都可以查看。任何帮助对我来说都意义重大。我知道规则是在管道本身创建后立即创建的,所以目前我不确定如何处理这个问题。 提前致谢!
我已将 60 的值添加到变量 FINAL_FIXABLE 以检查作业是否会手动运行。
问题是即使 FINAL_FIXABLE 设置为 60,也只有此作业 procession results (dev branch, case one)
正在运行。
在我构建和推送图像之后,这些是与此问题相关的管道阶段:
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
- apk add 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 "$FIXABLE">fixableValue.txt
- 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
- echo $FINAL_FIXABLE
- FINAL_FIXABLE="60"
- echo $FINAL_FIXABLE
- echo "$FINAL_FIXABLE">fixableValue.txt
only:
refs:
- dev
- some-test-branch
artifacts:
paths:
- fixableValue.txt
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
- apk add 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 "$FIXABLE">fixableValue.txt
- 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
- echo $FINAL_FIXABLE
- FINAL_FIXABLE="60"
- echo $FINAL_FIXABLE
- echo "$FINAL_FIXABLE">fixableValue.txt
only:
refs:
- master
- /^(([0-9]+)\.)?([0-9]+)\.x/
- rc
artifacts:
paths:
- fixableValue.txt
procession results (dev branch, case one):
stage: Scan results processing
dependencies:
- get results (dev branch)
image: alpine
script:
- FINAL_FIXABLE=$(cat fixableValue.txt)
- 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:
- FINAL_FIXABLE=$(cat fixableValue.txt)
- 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:
- FINAL_FIXABLE=$(cat fixableValue.txt)
- 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:
- FINAL_FIXABLE=$(cat fixableValue.txt)
- 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
【问题讨论】:
【参考方案1】:您无法使用这些方法来控制作业是否使用rules:
运行,因为规则在创建管道时评估,并且一旦创建管道就无法更改。
像这样动态控制管道配置的最佳选择可能是dynamic child pipelines。
附带说明,要为后续作业设置环境变量,您可以use artifacts:reports:dotenv
。当这个特殊的工件被传递到后续阶段/作业时,dotenv 文件中的变量将在作业中可用,就像在environment:
中设置的一样
stages:
- one
- two
first:
stage: one
script: # create dotenv file with variables to pass
- echo "VAR_NAME=foo" >> "myvariables.env"
artifacts:
reports: # create report to pass variables to subsequent jobs
dotenv: "myvariables.env"
second:
stage: two
script: # variables from dotenv artifact will be in environment automatically
- echo "$VAR_NAME" # foo
您对 .txt
工件所做的事情基本相同,它的工作方式相同,但脚本步骤更少。一个关键的区别是,这可以允许更多的动态控制,并且它适用于使用环境变量的其他一些作业配置键。比如你可以set environment:url
dynamically这种方式。
【讨论】:
感谢您提供的说明。我尝试了几天在 GitLab 父子功能的帮助下解决我的用例,但我做不到,因为目前存在从父管道传输工件到子管道的已知问题,并且没有解决此问题的解决方法目前可以帮助我。非常感谢您的帮助,通过研究这个主题我学到了很多东西。以上是关于如何能够将变量传递给 gitlab ci 管道中的规则?的主要内容,如果未能解决你的问题,请参考以下文章
我需要通过 gitlab-ci 中的 ssh 将 env 变量传递给 docker
如何将 gitlab ci/cd 变量传递给 kubernetes(AKS) deployment.yaml
如何将 exe 输出分配给 gitlab ci 脚本中的变量?