【问题标题】:Gitlabs artifact of one project used in further projects另一个项目中使用的一个项目的 Gitlab 工件
【发布时间】:2017-01-20 14:28:20
【问题描述】:

问题

  • 在 CI 阶段使用 docker 容器时,在项目之间携带工件(jar、class、war)的最佳方式是什么。

让我详细解释一下我的问题,请不要停止阅读... =)

Gitlabs 项目1

  • 单元测试
  • 等等……

Gitlabs 项目2

  • 单元测试
  • 等等……
  • 构建(失败)
    • 这里我需要一个在 project1 中生成的工件(jar)

当前场景/cmets

  • 我正在使用 docker,所以在每个 .gitlab-ci.yml 中我都会有独立的容器
  • project1 一切正常
  • 如果我在 .gitlab-ci.yml 中使用“shell”而不是 docker,我可以将 project1 中的 jar 文件保存在磁盘中,并在 project2 启动构建时使用
  • 今天我在调用 project2 时触发 project1 完成工作良好
  • 我的工件不是 RPM,所以我不会添加到我的 repo 中

可能的解决方案

【问题讨论】:

  • 如果你写java,无论如何你应该使用maven...

标签: continuous-integration gitlab gitlab-ci gitlab-ci-runner


【解决方案1】:

在 GitLab 白银和高级版中,有 $CI_JOB_TOKEN 可用,它允许以下 .gitlab-ci.yaml sn-p:

build_submodule:
  image: debian
  stage: test
  script:
  - apt update && apt install -y unzip
  - curl --location --output artifacts.zip "https://gitlab.example.com/api/v4/projects/1/jobs/artifacts/master/download?job=test&job_token=$CI_JOB_TOKEN"
  - unzip artifacts.zip
  only:
  - tags

但是,如果您没有银牌或更高级别的 gitlab 订阅,而是依赖免费套餐,也可以使用 API 和管道触发器。

假设我们有 项目 A 正在构建 项目 B 需要的 app.jar

首先,您需要一个 API 令牌。 转到Profile settings/Access Tokens 页面创建一个,然后将其作为变量存储在项目B中。在我的例子中是GITLAB_API_TOKEN

项目 B 的 CI/CD 设置中添加一个新触发器,例如“项目 A 已构建”。这将为您提供一个可以复制的令牌。 打开 项目 A 的 .gitlab-ci.yaml 并从 项目 B 的 CI / CD 设置触发器部分复制 trigger_build: 部分。

项目 A

trigger_build:
  stage: deploy
  script:
    - "curl -X POST -F token=TOKEN -F ref=REF_NAME https://gitlab.example.com/api/v4/projects/${PROJECT_B_ID}/trigger/pipeline"

将 TOKEN 替换为该令牌(最好将其作为变量存储在 project A 中 - 然后您需要将其设为 token=${TRIGGER_TOKEN_PROJECT_B} 或其他内容),并将 REF_NAME 替换为您的分支(例如master)。

然后,在项目 B 中,我们可以编写一个仅基于触发器构建并检索工件的部分。

项目 B

download:
  stage: deploy
  only:
    - triggers
  script:
    - "curl -O --header 'PRIVATE-TOKEN: ${GITLAB_API_TOKEN}' https://gitlab.example.com/api/v4/projects/${PROJECT_A_ID}/jobs/${REMOTE_JOB_ID}/artifacts/${REMOTE_FILENAME}"

如果您知道工件路径,则可以将${REMOTE_FILENAME} 替换为它,例如build/app.jar。项目 ID 可以在 CI/CD 设置中找到。

我扩展了 project A 中的脚本以传递触发器设置部分中记录的剩余信息:

variables[VARIABLE]=VALUE 添加到 API 请求中。变量值可用于区分触发管道和正常管道。

所以触发器传递了 REMOTE_JOB_ID 和 REMOTE_FILENAME,当然你可以根据需要修改它:

curl -X POST \
     -F token=TOKEN \
     -F ref=REF_NAME \
     -F "variables[REMOTE_FILENAME]=build/app.jar" \
     -F "variables[REMOTE_JOB_ID]=${CI_JOB_ID}" \
     https://gitlab.example.com/api/v4/projects/${PROJECT_B_ID}/trigger/pipeline

【讨论】:

【解决方案2】:

你好,你必须看看一个名为 get-last-successful-build-artifact.sh 并由 morph027 开发的脚本。

https://gitlab.com/morph027/gitlab-ci-helpers

此脚本允许下载工件并将其解压缩到项目根目录中。它使用 Gitlab API 来检索最新的成功构建并下载相应的工件。只需稍微更新一下脚本,您就可以组合多个工件并解压缩到任意位置。

我目前也在启动 PHP library 来处理构建工件,但它处于非常早期的阶段,目前与 laravel 绑定。

目前还没有简单的方法来处理项目之间的工件使用,您必须使用这些工具构建自己的。

我认为使用 shell executor 不是正确的解决方案,它非常危险,因为您无法验证构建期间使用的服务器上的文件!

希望有帮助:)

【讨论】:

  • 我将您的答案标记为官方答案,因为您的脚本完全符合我们的需要。谢谢!
  • 是否可以使用 get-last-successful-build-artifact.sh 没有 private-token(在世界可读的存储库中)?例如共享一个不暴露你的令牌的工件下载命令
  • 目前无法在没有身份验证的情况下检索工件...要下载文件,您需要访问私有的 Gitlab API...
【解决方案3】:

在项目之间排列工件(jar、class、war)

这应该是包注册表的用途。

GitLab 13.3(2020 年 8 月)现在免费提供!

现在在 Core 中提供包注册表

一年半前,我们将 Maven 支持直接构建到 GitLab 中,从而扩大了对 Java 项目和开发人员的支持。我们的目标是提供一种标准化的方式来共享包并在项目之间进行版本控制。

从那时起,我们已投资进一步组建 Package 团队,同时与我们的客户和社区合作,以更好地了解您的用例。我们还添加了对 Node、C#/.NET、C/C++、Python、PHP 和 Go 开发人员的支持。

您对这些功能的更多采用、使用和贡献使我们能够将我们的愿景扩展到更全面的解决方案,该解决方案集成到我们的单个应用程序中,该应用程序支持所有常用语言和二进制格式的包管理。
如果没有 GitLab 社区的明确支持,这个目标是不可能实现的。

作为 GitLab 管理承诺的一部分,我们很高兴地宣布,每种包管理器格式的基本功能现已在 GitLab 核心版中提供。
这意味着如果您使用 npm、Maven、NuGet、Conan、PyPI、Composer 或 Go 模块,您将能够:

  • 将 GitLab 用作私有(或公共)包注册表
  • 使用您的 GitLab 凭据、个人访问权限或工作令牌进行身份验证
  • 将包发布到 GitLab
  • 从 GitLab 安装包
  • 搜索托管在 GitLab 上的软件包
  • 访问易于使用的 UI,该 UI 显示包详细信息和元数据,并允许您下载任何相关文件
  • 确保您的贡献可供所有 GitLab 用户使用

我们期待听到您的反馈,并继续与所有用户一起改进这些功能。

请参阅 DocumentationIssue

this video

【讨论】:

  • 虽然我目前正在尝试此解决方案,但其中一个问题是包注册表需要 xyz 格式的版本号(请参阅docs.gitlab.com/ee/user/packages/generic_packages/…)并且感觉更像是(永久)发布包,而不是为下游依赖构建共享快照/工件。例如,如果我有一个 UI 和一个后端,并将它们都构建在单独的存储库中,但将它们合并到第三个存储库中的一个包中,则 UI 和后端存储库可能会更好地使用工件
  • 事实上,使用相同版本两次会列出同一页面内的软件包,因为它们被认为是相等的,因此我需要为每个构建/提交提供正确的版本号(甚至不可能使用 -rc1 或 -beta/-snapshot/-dev 后缀。因此,为“跨项目管道”传递工件可能仍然是一个可行的解决方案。
  • @SebastianHöffner 好点。重新阅读gitlab.com/groups/gitlab-org/-/epics/4209(从中指定了该功能),该软件包注册表可能不适合您当前的工作流程。
【解决方案4】:

酷,发现这里引用了我的 sn-p ;)

是否可以在没有私有令牌的情况下使用 get-last-successful-build-artifact.sh(在世界可读的存储库中)?例如共享一个不暴露你的令牌的工件下载命令

是的,只需在项目设置 -> 管道 -> 秘密变量中将其添加为 secret variable

【讨论】:

    【解决方案5】:

    在撰写本文时,工件只能在管道内跨项目共享。见https://docs.gitlab.com/ee/ci/yaml/README.html#artifacts

    但是,有一个尚未实现的开放功能可以启用此功能。 https://gitlab.com/gitlab-org/gitlab-ce/issues/14728

    【讨论】:

      猜你喜欢
      • 2018-03-19
      • 2021-05-28
      • 2020-03-14
      • 2015-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多