【问题标题】:how to access multiple repositories in CI build?如何在 CI 构建中访问多个存储库?
【发布时间】:2016-01-04 21:10:56
【问题描述】:

我们有一个由多个(非公共)存储库组成的项目。

要构建整个项目,构建系统需要拥有所有存储库(master 分支)的文件。

有没有一种方法可以配置 GitLab CI 以提供我需要的存储库?

我想我可以在 CI 构建期间执行git fetch 或类似的操作,但是如何处理身份验证呢?

【问题讨论】:

    标签: gitlab gitlab-ci


    【解决方案1】:

    如果您运行 gitlab 8.12 或更高版本,则权限模型为reworked。除了这个新的权限模型,还有 CI 环境变量 CI_JOB_TOKEN。 GitLab 的高级版本使用此环境变量作为触发器,但您可以使用它来克隆存储库。

    dummy_stage:
      script:
        - git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.instance/group/project.git
    

    【讨论】:

    • 请注意,正如上面示例中正确记录的那样,在 GitLab url 中,实例和组之间的分隔符必须是斜杠 (...gitlab.instance/group/project.git) 和 not 冒号 (...gitlab.instance:group/project.git) 以使克隆成功。 repo 的 SSH url 采用后一种形式,导致错误使用该格式。
    • SSH 密钥/令牌如果您需要从其他 GL 实例中获取它们,则不会被破解。另一方面,您可以在这些存储库的本地实例中创建导入的分支,并(使用另一个带有同步脚本的存储库)不时同步它们。
    • 部署密钥不是黑客,同意。我的答案是使用最少的权限来完成任务(也不必更改任何配置)。部署密钥的好处是它开辟了广泛的可能性(写访问、gitlab 实例之外的存储库等)。
    • @GrantHumphries,感谢您的提示。我刚刚犯了那个错误,正在拔头发试图找出问题所在
    【解决方案2】:

    一些对我有用的解决方法(我讨厌这个词!):

    1. 使用git submodule,见https://docs.gitlab.com/ce/ci/git_submodules.html

    2. 重用由 Gitlab 定义的 $CI_REPOSITORY_URL,甚至在子 Docker 容器中也可用。此环境变量已经包含用户名和密码,可用于同一服务器上的另一个 repo。参见 .gitlab-ci.yml 中的 sn-p:

    - BASE_URL=`回显 $CI_REPOSITORY_URL | sed "s;\/*$CI_PROJECT_PATH.*;;"` - REPO_URL="$BASE_URL/thirdparty/gtest.git" - REPO_DIR=第三方/gtest -rm -fr $REPO_DIR - 混帐克隆 $REPO_URL $REPO_DIR
    1. 甚至将该 URL 与用户名\密码存储在 ~/.git-credentials 文件中并配置 git 以通过 credential.helper 使用它。所有进一步的“git clone”命令都将使用它。
    - echo 存储 git 凭据以供“git clone”命令使用,无需用户名和密码... - GIT_CREDENTIALS_FILE=~/.git-credentials - BASE_URL=`回显 $CI_REPOSITORY_URL | sed "s;\/*$CI_PROJECT_PATH.*;;"` - 回显 $BASE_URL > $GIT_CREDENTIALS_FILE - git config --global credential.helper store --file=$GIT_CREDENTIALS_FILE

    但是!

    在 CI\CD 领域工作了好几年,我认为需要将存储库链接为 sources 的设计不是很好。

    是的,在 Jenkins 或 TeamCity 等经典 CI 工具中,您可以创建一个在不同子目录中获取多个 Git 存储库的作业。

    但我喜欢 GitLab CI 的 Pipeline As Code 方式,其中 .gitlab-ci.yml 控制着这个 repo 的构建,您甚至不必考虑获取源代码的整个预构建步骤。 然后这样的构建将发布 binary 工件和下游项目\repos 可以使用这些而不是 sources 的依赖项。它也更快。

    关注点分离。

    我的 .gitlab-ci.yml 中没有正式的方式来使用另一个项目的工件。但是还有其他方法,例如钩子、Gitlab API,尽管此类定制解决方案需要维护。

    有更好的方法 - 发布\获取工件到\来自外部广泛采用的包管理器。 根据您的语言,它可能是 Maven、NuGet、npm、jFrog Artifactory、Nexus 等。 这种方法的另一个优点是开发人员可以在他们的本地构建中遵循相同的过程,如果在 .gitlab-ci.yml 中定义了依赖项,这并不容易

    这对于原生代码(Cxx)来说是一个更大的问题,主要是由于二进制接口的兼容性,但像 Conan.io 之类的东西正在慢慢迎头赶上。

    【讨论】:

    • 赞成解决方案 2。我的变体看起来像 git clone $(echo $CI_REPOSITORY_URL | sed -e s"|$CI_PROJECT_PATH|$SECOND_PROJECT_PATH|")
    【解决方案3】:

    您可以为所有项目添加部署密钥。然后在运行器上配置部署密钥的私钥。在构建过程中使用普通的 git 命令来克隆运行器上的存储库。这可能需要对跑步者进行一些配置,但它应该可以工作。

    您可以生成一个 SSH 密钥对并在所有运行器上使用它,也可以为每个运行器生成一个密钥对。要生成 SSH 密钥对,请遵循 SSH key 文档。私钥应放在“gitlab-runner”用户的.ssh 目录中,以便git 命令可以在克隆时显示它。公钥应作为部署密钥添加到 GitLab 项目中。在项目设置中添加部署密钥 -> '部署密钥'。

    【讨论】:

    • 能否请您更准确一点“然后在运行器上配置部署密钥的私钥。”
    • 编辑:我用更多细节更新了答案。如果您仍有疑问,请告诉我。
    • 也许自 2015 年以来情况发生了变化,但在 Gitlab.com 上,跑步者似乎以root 运行东西。就我而言,没有gitlab-runner 用户。
    • ssh/keys 的最大问题是它允许运行器的用户(gitlab 文件的编写者能够访问和复制该 ssh 密钥)。
    • 像我一样,如果您是第一次听说部署密钥/令牌,here 是文档的链接。它有例子,很容易理解。
    猜你喜欢
    • 1970-01-01
    • 2022-01-12
    • 2021-11-16
    • 1970-01-01
    • 1970-01-01
    • 2018-09-09
    • 2016-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多