18

背景

Jenkins 被用于从具有 Git 子模块的 Git 存储库构建工件。子模块与父项目不在同一个仓库中,甚至不在同一个端点。问题是父存储库检查正常,因为凭证 ssh 密钥 A 与主/父存储库相关联,但毫不奇怪,子模块失败,因为凭证 ssh 密钥 B 与来自 Jenkins 的存储库无关' 观点看法。

令人惊讶的是,Jenkins 对 Git 子模块没有更好的开箱即用支持。是时候做出贡献了。

问题

  1. 有没有办法为单个 Git 存储库存储多个凭据?
  2. 如果答案是否定的,为什么 Jenkins 在高级子模块行为下提供了使用父存储库默认远程凭据的选项,如下所示?
  3. 还有什么其他方法可以处理具有不同凭据的 Jenkins 和 Git 子模块?

在此处输入图像描述

系统信息

在 Docker 机器上运行 Jenkins(本地)

在 CentOS 上运行 Jenkins(生产)

詹金斯版本:2.60.2(两者)

Git 插件版本:3.6.4(两者)

4

2 回答 2

1

是的,这很容易做到。您可以创建 pub/private 密钥对并将其设置为github 部署密钥(如果您不使用 git hub,则作为您使用的任何密钥集)。您可以将其添加为 Jenkins 凭据(前提是您安装了凭据插件)。

Username: git@github.com
Private Key:  the private key for that key set
Passphrase:  whatever passphrase you used
ID: aws-jenkins-github-deploykey (just an example name)
Description: some useful text

ID 映射到下面的credentialsId

checkout changelog: true, poll: false, scm: [$class: 'GitSCM',
     branches: [[name: "branch name, commit sha, or tag/tagname" ]],
     userRemoteConfigs: [[
     credentialsId: 'aws-jenkins-github-deploykey',
     url: 'git@github.com:myorg/myrepo.git']]]

当这个 Pipeline 代码运行时,它会检查分支处的 repo,提交等到工作目录。您还可以指定目录。

因此,您可以使用它来检查一堆 repos 并为它们使用特定的分支。

于 2018-11-09T20:51:10.840 回答
0
  1. 否 - git 插件仅支持一个键(在撰写本文时)
  2. 根据git plugin docs,默认行为是根本不为子模块使用凭据。布尔标志告诉插件使用父凭据。它在下面使用的 git 插件不支持使用任何其他凭据的想法。
  3. 这很难找到,但我的 Github 项目遇到了同样的问题 - 它使用了模块,而Github 不允许跨项目使用相同的部署密钥

为了解决这个问题,我首先设置了一个 github 应用程序,安装它,并分配项目及其子模块。这个应用程序能够生成可用于克隆的访问密钥 - 所以我使用这些凭据进行克隆。我在 git 插件行为中禁用了子模块,并使用本机git命令更新子模块 URL 以在运行之前使用用户名和密码submodule initsubmodule update克隆子模块。

steps {
    withCredentials([usernamePassword(credentialsId: 'github-app-credentials',
                                usernameVariable: 'GITHUB_APP',
                                passwordVariable: 'GITHUB_ACCESS_TOKEN')]) {
        checkout ([
            $class: 'GitSCM',
            userRemoteConfigs: [[
                credentialsId: '',
            url: "https://x-access-token:$GITHUB_ACCESS_TOKEN@github.com/<ORG>/<PROJECT>.git"
            ]],
            branches: [[ name: '*/main' ]],
            extensions: [[
                $class: 'SubmoduleOption', 
                disableSubmodules: true
            ]]
        ])
        sh '''
            git config --file=.gitmodules submodule.SUBMODULE_A.url https://x-access-token:$GITHUB_ACCESS_TOKEN@github.com/<ORG>/<SUBMODULE_A>.git
            git config --file=.gitmodules submodule.SUBMODULE_B.url https://x-access-token:$GITHUB_ACCESS_TOKEN@github.com/<ORG>/<SUBMODULE_B>.git
            git submodule init update
            git restore .gitmodules

            # rest of build
        '''
    }
}

这标志着 Jenkins 中的安全问题,因为 GITHUB_ACCESS_TOKEN 被插入到字符串中,以便将其传递给 git URL。我不相信这是可以修复的,因为该checkout命令不会引用任何环境变量。但是,看起来这些访问令牌是短暂的,因此有所缓解。

我相信你也可以通过使用GIT_SSH_COMMAND环境变量来使用部署密钥,尽管这留给读者作为练习。

下次有人建议使用 git 子模块时,请帮我打他们。

于 2022-01-14T21:47:54.263 回答