如何能够将变量传递给 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

如何将值传递给 Gitlab CI 作业

如何将 exe 输出分配给 gitlab ci 脚本中的变量?

Gitlab ci问题将工件传递到带有触发器和需要关键字的下游管道

如何在 Gitlab 中基于管道变量运行作业?