我如何传递数据,例如$BUILD_VERSION
变量,在 Gitlab CI 中不同管道中的作业之间?
考虑以下示例(完整的 yml
下面):
building:
# only on merge requests
stage: staging
script:
- echo "BUILD_VERSION=1.2.3" > build.env
artifacts:
reports:
dotenv: build.env
deploying:
# after merge request is merged
stage: deploy
dependencies:
- building
script:
- echo $BUILD_VERSION
我有两个阶段,staging 和 deploy。 staging 中的 building
作业构建应用并创建“审核应用”(为简单起见,没有单独的构建阶段)。 deploy 中的 deploying
作业然后上传新应用。
每当打开合并请求时,包含 building
作业的管道就会运行。通过这种方式构建应用程序,开发人员可以单击合并请求中的“审查应用程序”图标。 deploying
作业在合并请求合并后立即运行。思路如下:
*staging* stage *deploy* stage
<open merge request> -> `building` job (and show) ... <merge> -> `deploying` job
│ ▲
└───────────── $BUILD_VERSION ───────────────┘
我的问题是,staging/building
创建了一些数据,例如$BUILD_VERSION
。我想在 deploy/$BUILD_VERSION
中使用这个 deploying
,例如用于通过 Gitlab API 创建新版本。
所以我的问题是:如何将 $BUILD_VERSION
(和其他数据)从 staging/building
传递到 deploy/{{ 1}}?
deploying
在 Pass an environment variable to another job 中的 gitlab 文档中,描述的案例较少处理。此外,下面显示的 artifacts.reports.dotenv
文件深受此示例的启发。还是不行。
yml
工件是在 build.env
中创建的,但是每当执行 building
作业时,deploying
文件都会被删除,如下面的第 15 行所示: .env”。我尝试将 build.env
添加到 build.env
,但它仍然被删除。
经过数小时的搜索,我在 this gitlab issue comment 和 this stackoverflow post 中发现 .gitignore
不适用于 artifacts.reports.dotenv
或 dependencies
关键字。>
删除 needs
不起作用。仅使用 dependencies
也不起作用。不允许同时使用。
有谁知道如何让它发挥作用?我觉得这就是它应该工作的方式。
stackoverflow 帖子 Gitlab ci cd removes artifact for merge requests 的这个答案建议将 needs
用作普通文件。我也试过这个。 (相关)build.env
如下:
yml
结果和上面一样。 building:
# ...
artifacts:
paths:
- build.env
deploying:
# ...
before_script:
- source build.env
被移除。然后 build.env
命令失败,因为 source build.env
不存在。 (build.env
是否在 build.env
中无关紧要,均已测试)
我还找到了 stackoverflow 帖子 Use artifacts from merge request job in GitLab CI 的答案,它建议将 API 与 .gitignore
一起使用。但由于我需要非合并请求管道中的工件,因此我无法使用建议的 $CI_JOB_TOKEN
。
我尝试使用 CI_MERGE_REQUEST_REF_PATH
。 (重要的部分)$CI_COMMIT_REF_NAME
然后是:
yml
但是这个 API 请求被“404 Not Found”拒绝了。由于 commit SHAs are not supported,deploying:
# ...
script:
- url=$CI_API_V4_URL/projects/jobs/artifacts/$CI_COMMIT_REF_NAME/download?job=building
- echo "Downloading $url"
- 'curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --output $url'
# ...
或 $CI_COMMIT_BEFORE_SHA
也不起作用。
$CI_COMMIT_SHA
更新:我在 gitlab 文档中找到了 Artifact downloads between pipelines in the same project 部分,这正是我想要的。但是:我无法让它工作。
从文档中复制更少的内容后,needs
如下所示:
yml
现在 building:
# ...
artifacts:
paths:
- version
expire_in: never
deploying
# ...
needs:
- project: $CI_PROJECT_PATH
job: building
ref: staging # building runs on staging branch, main doesn't work either
artifacts: true
作业立即失败,我收到以下错误横幅:
我尝试设置 deploying
(如图所示),但仍然出现相同的错误。同样在 Settings > CI/CD > Artifacts 中选择“保留最近成功作业的工件”。所以应该存在工件。我在这里错过了什么?这应该根据文档工作!
我希望有人能帮助我让 artifacts.expire_in = never
担任 $BUILD_VERSION
的工作。如果有其他方法而不是我尝试过的方法,我很高兴听到它们。提前致谢。
示例deploying
:
.gitlab-ci.yml
答案 0 :(得分:1)
这是你可以通过文件传递的东西。
在构建作业中创建新变量:
variables:
CONFIG: "anyname"
然后在脚本中执行导出/复制到文件,例如:
- echo $BUILD_VERSION > $CI_PROJECT_DIR/$CONFIG
在工件中添加路径:
artifacts:
paths:
- $CONFIG
然后在部署作业中
variables:
CONFIG: "anyname"
和来源
- source $CI_PROJECT_DIR/$CONFIG
要使其工作,只需尝试解决传递问题,保持依赖关系并保留工件,只需使用“需求”,避免清除作业中的工件
答案 1 :(得分:1)
您不能使用 CI/CD 在完全不相关的管道之间传递工件。 “构建”在定义合并请求的分支上运行,而“部署”在合并的结果上运行,这一事实并不意味着“部署”只是下一阶段。如果在两者之间合并另一个 MR 会怎样?如果存在合并冲突怎么办?
换句话说,你不能仅仅因为你构建了开发分支就跳过主分支上的“构建”。让“构建”一直发生,将“部署”限制在主分支。在此设置中,您可以轻松地将工件从“构建”传递到“部署”。
或者,如果您希望合并事件实际使用版本状态更新主分支,只需使用源代码控制的 VERSION 文件。这就是 git 的用途。当您合并时, main 将从分支采用 VERSION。如果不同的分支首先进入,您将必须解决冲突,这是您应该做的。