mii*_*le7 30 pass-data gitlab gitlab-ci devops
如何$BUILD_VERSION
在 Gitlab CI 中不同管道的作业之间传递数据(例如变量)?
所以(就我而言):
\nPipeline 1 on push ect. Pipeline 2 after merge\n\n `building` job ... `deploying` job\n \xe2\x94\x82 \xe2\x96\xb2\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 $BUILD_VERSION \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n考虑以下示例(完整内容yml
如下):
Pipeline 1 on push ect. Pipeline 2 after merge\n\n `building` job ... `deploying` job\n \xe2\x94\x82 \xe2\x96\xb2\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 $BUILD_VERSION \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n我有两个阶段,登台和部署。暂存阶段building
的工作构建应用程序并创建一个“审查应用程序”(为了简单起见,没有单独的构建阶段)。然后,部署中的作业会上传新应用程序。deploying
building
每当打开合并请求时,包含作业的管道就会运行。这样,应用程序就构建完成了,开发人员可以单击合并请求中的“审核应用程序”图标。该deploying
作业在合并请求合并后立即运行。这个想法如下:
*staging* stage (pipeline 1) *deploy* stage (pipeline 2)\n\n<open merge request> -> `building` job (and show) ... <merge> -> `deploying` job\n \xe2\x94\x82 \xe2\x96\xb2\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 $BUILD_VERSION \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n对我来说问题是,登台/创建building
一些数据,例如$BUILD_VERSION
. 我想将其放在deploy /$BUILD_VERSION
中,例如通过Gitlab API 创建新版本。deploying
所以我的问题是:如何将$BUILD_VERSION
(和其他数据)从staging /传递building
到deploy / deploying
?
artifacts.reports.dotenv
所描述的情况在 gitlab 文档中将环境变量传递给另一个作业中处理得更少。另外,yml
下面显示的文件深受此示例的启发。尽管如此,它仍然不起作用。
该build.env
工件是在 中创建的building
,但每当deploying
执行作业时,该build.env
文件就会被删除,如下面第 15 行所示:“删除 build.env”。我尝试添加build.env
到.gitignore
但它仍然被删除。
经过几个小时的搜索,我在这个 gitlab 问题评论和这个 stackoverflow 帖子中发现不适artifacts.reports.dotenv
用于dependencies
或needs
关键字。
删除dependencies
不起作用。仅使用needs
也不起作用。不允许同时使用两者。
有谁知道如何让它发挥作用?我觉得这就是它应该发挥的作用。
\nstackoverflow 帖子Gitlab ci cd removes artifact for merge requests的答案建议将其用作build.env
普通文件。我也尝试过这个。(相关)yml
如下:
building:\n stage: staging\n # only on merge requests\n rules:\n # execute when a merge request is open\n - if: $CI_PIPELINE_SOURCE == "merge_request_event"\n when: always\n - when: never\n script:\n - echo "BUILD_VERSION=1.2.3" > build.env\n artifacts:\n reports:\n dotenv: build.env\n\ndeploying:\n stage: deploy\n # after merge request is merged\n rules:\n # execute when a branch was merged to staging\n - if: $CI_COMMIT_BRANCH == $STAGING_BRANCH\n when: always\n - when: never\n dependencies: \n - building\n script:\n - echo $BUILD_VERSION\n
Run Code Online (Sandbox Code Playgroud)\n结果与上面相同。被build.env
删除。然后source build.env
命令失败,因为build.env
不存在。(无论是否build.env
在其中.gitignore
,都进行了测试)
我还找到了 stackoverflow 帖子Use artifacts from merge request job in GitLab CI的答案,它建议将 API 与$CI_JOB_TOKEN
. 但由于我需要非合并请求管道中的工件,因此我无法使用建议的CI_MERGE_REQUEST_REF_PATH
.
我尝试使用$CI_COMMIT_REF_NAME
. 那么(的重要部分)yml
是:
*staging* stage (pipeline 1) *deploy* stage (pipeline 2)\n\n<open merge request> -> `building` job (and show) ... <merge> -> `deploying` job\n \xe2\x94\x82 \xe2\x96\xb2\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 $BUILD_VERSION \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n但 API 请求被拒绝并显示“404 Not Found”。由于提交 SHA 不受支持,$CI_COMMIT_BEFORE_SHA
或者$CI_COMMIT_SHA
也不起作用。
needs
更新:我在 gitlab 文档中找到了同一项目中管道之间的 Artifact downloads部分,这正是我想要的。但是:我无法让它工作。
\nyml
从文档中进行更少的复制后,看起来如下所示:
building:\n # ...\n artifacts:\n paths:\n - build.env\n\ndeploying:\n # ...\n before_script:\n - source build.env\n
Run Code Online (Sandbox Code Playgroud)\n现在deploying
作业立即失败,我收到以下错误横幅:
我尝试设置artifacts.expire_in = never
(如图所示)但仍然遇到相同的错误。另外,在“设置” > “CI/CD” > “工件”中,选择“保留最近成功作业中的工件”。所以神器应该存在。我在这里错过了什么?根据文档这应该有效!
我希望有人能帮助我找到这份$BUILD_VERSION
工作deploying
。如果除了我尝试过的方法之外还有其他方法,我很高兴听到它们。提前致谢。
这个例子.gitlab-ci.yml
:
deploying:\n # ...\n script:\n - url=$CI_API_V4_URL/projects/jobs/artifacts/$CI_COMMIT_REF_NAME/download?job=building\n - echo "Downloading $url"\n - \'curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --output $url\'\n # ...\n
Run Code Online (Sandbox Code Playgroud)\n
根据 Gitlab 文档,应该可以通过 URL 下载任何作业的工件(如果它尚未过期)。
此外,您还可以使用 Gitlab API 从其他项目下载(未过期的)工件;您可以使用 Gitlab API 来标记作业的工件以保留无论过期策略,或删除工件。
但我自己还没有尝试过。
对于您的情况,假设“构建”和“部署”作业都在分支上运行main
,您有望像这样传递工件。
如果您有其他方法可以在作业中找出deploying
作业在哪个分支名称 Xbuilding
上运行,那么您可以从分支 X 下载工件,而不是main
像我下面那样总是从分支 X 下载工件。
# Assuming
# domain: example.com
# namespace: mygroup
# project: myproject
building:
# on latest commit on `main`, because we need a predictable
# branch name to save/retrieve the artifact.
stage: staging
script:
- echo "BUILD_VERSION=1.2.3" > build.env
artifacts:
# 'paths', not 'reports'
paths:
- build.env
deploying:
# after merge request is merged
stage: deploy
dependencies:
- building
script:
# could use ${CI_PROJECT_URL} to get https://example.com/mygroup/myproj
- curl https://${CI_SERVER_HOST}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}/-/jobs/artifacts/main/raw/build.env?job=building > build.env
- source build.env
- echo $BUILD_VERSION # should print '1.2.3'.
Run Code Online (Sandbox Code Playgroud)
文档的相关部分,包含链接和摘录:
要浏览或下载分支的最新工件,请使用这两个 URL 之一。[我认为该/file/
变体用于 Gitlab Pages 工件,但我不确定。——埃斯蒂斯]
https://example.com/<namespace>/<project>/-/jobs/artifacts/<ref>/browse?job=<job_name>
https://example.com/<namespace>/<project>/-/jobs/artifacts/<ref>/download?job=<job_name>
https://example.com/<namespace>/<project>/-/jobs/artifacts/<ref>/raw/<path/to/file>?job=<job_name>
https://example.com/<namespace>/<project>/-/jobs/artifacts/<ref>/file/<path>?job=<job_name>
例如,要下载包含domain gitlab.com
、namespace gitlab-org
、project gitlab
、分支上的最新提交main
、job coverage
、文件路径的工件review/index.html
:
https://gitlab.com/gitlab-org/gitlab/-/jobs/artifacts/main/raw/review/ index.html?job=覆盖率
expire_in
环境的控制。.gitlab-ci.yml
使用 Gitlab API 的优点是,如果您可以获得正确的令牌,您还可以从其他项目下载工件。如果您的脚本在 Gitlab CI 中运行,您将需要数字项目 ID,即 $CI_PROJECT_ID。
要下载工件存档:
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/${CI_PROJECT_ID}/jobs/artifacts/main/download?job=test"
要下载单个工件文件:
curl --location --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/${CI_PROJECT_ID}/jobs/artifacts/main/raw/some/release/file.pdf?job=pdf"
您不能使用 CI/CD 在完全不相关的管道之间传递工件。事实上,“构建”是在定义合并请求的分支上运行,“部署”是在合并结果上运行,并不意味着“部署”只是下一个阶段。如果中间合并了另一个 MR 会怎样?如果出现合并冲突怎么办?
换句话说,你不能仅仅因为构建了开发分支就跳过了主分支上的“构建”。让“构建”始终发生,并将“部署”限制在主分支。在此设置中,您可以轻松地将工件从“构建”传递到“部署”。
或者,如果您希望合并事件实际更新主分支的版本状态,只需使用源代码控制的 VERSION 文件即可。这就是 git 的用途。当您合并时,main 将采用分支中的版本。如果不同的分支首先进入,您就必须解决冲突,正如您应该做的那样。
归档时间: |
|
查看次数: |
47445 次 |
最近记录: |