Gitlab CI:如何将一个阶段的环境变量用作另一个阶段的 needs:project ref

Gitlab CI: How do I use the environment variable from one stage as needs:project ref in another

我在同一个项目中有两个工作:job Ajob B

job A 创建环境变量 EXTERNAL_PROJ_REF=some_tag 并通过 .env 文件导出它。

job B 需要从 external_project 下载工件并将它们与当前项目中的其他工件打包。我希望能够动态地选择从中下载这些外部工件的提交引用。我正在尝试将环境变量 EXTERNAL_PROJ_REF 用作 job B 所需的 external_projectref

job A:
  stage: build
  script:
    - echo "EXTERNAL_PROJ_REF=`./generate_variable.sh`" > build.env  # evaluates to EXTERNAL_PROJ_REF=some_tag
  artifacts:
    reports:
      dotenv: build.env

job B:
  stage: package
  script:
    - ./do_packaging_job.sh
  needs:
    - job: job A
      artifacts: true
    - project: external_project
      ref: $EXTERNAL_PROJ_REF
      job: external_job
      artifacts: true

当我 运行 这个管道时,job B 立即失败并出现以下错误:

This job depends on other jobs with expired/erased artifacts:

如果我将 ref 硬编码为 some_tag,作业不会失败,并且我可以确认 EXTERNAL_PROJ_REF 已成功传递给 job B

job B:
  stage: package
  script:
    - echo "Ref = $EXTERNAL_PROJ_REF"  # Correctly prints "Ref = some_tag"
    - ./do_packaging_job.sh
  needs:
    - job: job A
      artifacts: true
    - project: external_project
      ref: some_tag   # hardcoded so the job doesn't fail
      job: external_job
      artifacts: true

但是,当我有 ref:$EXTERNAL_PROJ_REF 时,管道失败。有人可以告诉我是否遗漏了什么吗?

我用于在两个 GitLab CI 作业之间共享变量的简单解决方案:

stages:
 - build
 - package
 
job A:
  stage: build
  script:
    - echo "EXTERNAL_PROJ_REF=`./generate_variable.sh`" > build.env
  artifacts:
    paths:
      - build.env

job B:
  stage: package
  before_script:
    - export $(cat build.env | xargs)
  script:
    - ./do_packaging_job.sh

我终于意识到Gitlab不支持我想做的事情,至少不支持这种方式。根据 this link,从不同作业传递的变量只能在作业的 before_scriptscriptafter_script 部分使用;它不能用于配置作业。我无法在 job Bneeds 部分使用它。

幸运的是,我找到了一个使用 Gitlab API 的简单解决方法。我有 API 访问 external_project,所以我只使用 wget 从动态选择的提交引用中下载我需要的工件。之后我直接把神器传给job B.

job A:
  stage: build
  script:
    # Dynamically create commit reference
    - EXTERNAL_PROJ_REF=`./generate_commit_ref.sh`
    # Download artifact with Gitlab API
    - wget --header "PRIVATE-TOKEN:${EXTERNAL_PROJ_TOKEN}" --output-document outputFileName.file "${CI_API_V4_URL}/projects/${EXTERNAL_PROJ_ID}/jobs/artifacts/${EXTERNAL_PROJ_REF}/raw/${EXTERNAL_ARTIFACT_PATH}?job=${EXTERNAL_JOB_NAME}"
    # btw CI_API_V4_URL is a gitlab defined variable
  artifacts:
    paths:
      - outputFileName.file

job B:
  stage: package
  script:
    - ./do_packaging_job.sh
  needs:
    # Now this packaging job only needs job A. It doesn't need the external job anymore
    - job: job A
      artifacts: true