tl;dr
我如何传递数据,例如这$BUILD_VERSION
变量,Gitlab CI 中不同管道中的作业之间?
所以(就我而言):
Pipeline 1 on push ect. Pipeline 2 after merge
`building` job ... `deploying` job
│ ▲
└─────── $BUILD_VERSION ─────────┘
背景
考虑以下示例(完整yml
below):
building:
stage: staging
# only on merge requests
rules:
# execute when a merge request is open
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
when: always
- when: never
script:
- echo "BUILD_VERSION=1.2.3" > build.env
artifacts:
reports:
dotenv: build.env
deploying:
stage: deploy
# after merge request is merged
rules:
# execute when a branch was merged to staging
- if: $CI_COMMIT_BRANCH == $STAGING_BRANCH
when: always
- when: never
dependencies:
- building
script:
- echo $BUILD_VERSION
我有两个阶段,staging and deploy. The building
job in staging构建应用程序并创建一个“审核应用程序”(为了简单起见,没有单独的构建阶段)。这deploying
job in deploy然后上传新的应用程序。
管道包含building
每当打开合并请求时作业就会运行。这样,应用程序就构建完成了,开发人员可以单击合并请求中的“审核应用程序”图标。这deploying
作业在合并请求合并后立即运行。这个想法如下:
*staging* stage (pipeline 1) *deploy* stage (pipeline 2)
<open merge request> -> `building` job (and show) ... <merge> -> `deploying` job
│ ▲
└───────────── $BUILD_VERSION ───────────────┘
对我来说问题是staging/building
创建一些数据,例如A$BUILD_VERSION
。我想要这个$BUILD_VERSION
in the deploy/deploying
,例如用于通过 Gitlab API 创建新版本。
所以我的问题是:我如何通过$BUILD_VERSION
(和其他数据)来自staging/building
to deploy/deploying
?
到目前为止我尝试过的
artifacts.reports.dotenv
所描述的情况在 gitlab 文档中处理得更少将环境变量传递给另一个作业 https://docs.gitlab.com/ee/ci/variables/#pass-an-environment-variable-to-another-job。还有yml
下面显示的文件深受此示例的启发。尽管如此,它仍然不起作用。
The build.env
工件创建于building
,但每当deploying
作业执行后,build.env
文件被删除,如下第 15 行所示:“删除 build.env”。我尝试添加build.env
to the .gitignore
但它仍然被删除。
经过几个小时的搜索我发现这个gitlab问题评论 https://gitlab.com/gitlab-org/gitlab/-/issues/246777#note_417210007 and 这个 stackoverflow 帖子 https://stackoverflow.com/a/65878853/5934316认为artifacts.reports.dotenv
不适用于dependencies
or the needs
关键词。
去除dependencies
不起作用。使用needs
只是也不起作用。不允许同时使用两者。
有谁知道如何让它发挥作用?我觉得这就是它应该发挥的作用。
将工件作为文件获取
stackoverflow 帖子的这个答案Gitlab ci cd 删除合并请求的工件 https://stackoverflow.com/a/65878853/5934316建议使用build.env
作为普通文件。我也尝试过这个。 (相关)yml
如下:
building:
# ...
artifacts:
paths:
- build.env
deploying:
# ...
before_script:
- source build.env
结果与上面相同。这build.env
被删除。然后source build.env
命令失败,因为build.env
不存在。 (没关系,如果build.env
在里面.gitignore
或没有,都测试过)
从 API 获取工件
我还找到了 stackoverflow 帖子的答案在 GitLab CI 中使用合并请求作业中的工件 https://stackoverflow.com/a/66344557/5934316建议将该 API 与$CI_JOB_TOKEN
。但由于我需要非合并请求管道中的工件,因此我无法使用建议的CI_MERGE_REQUEST_REF_PATH
.
我尝试使用$CI_COMMIT_REF_NAME
。 (重要部分)yml
那么就是:
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'
# ...
但 API 请求被拒绝并显示“404 Not Found”。自从不支持提交 SHA https://docs.gitlab.com/ee/api/job_artifacts.html#download-a-single-artifact-file-from-specific-tag-or-branch, $CI_COMMIT_BEFORE_SHA
or $CI_COMMIT_SHA
也不工作。
Using needs
Update: 我找到这个版块了同一项目中管道之间的工件下载 https://docs.gitlab.com/ee/ci/yaml/#artifact-downloads-between-pipelines-in-the-same-project在 gitlab 文档中,这正是我想要的。但是:我无法让它工作。
The 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
Now the deploying
作业立即失败,我收到以下错误横幅:
我尝试设置artifacts.expire_in = never
(如图所示)但我仍然遇到同样的错误。也在Settings > CI/CD > 文物选择“保留最近成功作业的工件”。所以神器应该存在。我在这里错过了什么?根据文档,这应该有效!
我希望有人能帮助我获得$BUILD_VERSION
to the deploying
工作。如果除了我尝试过的方法之外还有其他方法,我很高兴听到它们。提前致谢。
这个例子.gitlab-ci.yml
:
stages:
- staging
- deploy
building:
tags:
- docker
image: bash
stage: staging
rules:
- if: ($CI_PIPELINE_SOURCE == "merge_request_event") && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "staging"
when: always
- when: never
script:
- echo "BUILD_VERSION=1.2.3" > build.env
artifacts:
reports:
dotenv: build.env
environment:
name: Example
url: https://example.com
deploying:
tags:
- docker
image: bash
stage: deploy
rules:
- if: $CI_COMMIT_BRANCH == "staging"
when: always
- when: never
dependencies:
- building
script:
echo $BUILD_VERSION