【问题标题】:Jenkins - Git Submodule Credentials Different from Parent RepoJenkins - Git 子模块凭证不同于父回购
【发布时间】:2017-11-13 23:41:58
【问题描述】:

背景

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

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

问题

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

系统信息

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

在 CentOS 上运行 Jenkins(生产)

Jenkins 版本:2.60.2(两者)

Git 插件版本:3.6.4(两者)

【问题讨论】:

  • 这里有同样的问题

标签: git github jenkins jenkins-plugins jenkins-job-builder


【解决方案1】:

是的,这很容易做到。您可以创建 pub/private 密钥对并将其设置为 github deploy key(如果您使用的是 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 并为它们使用特定的分支。

【讨论】:

  • 这个答案不清楚。添加第二个凭据很容易,但是如何将其“映射”到指定的存储库?好像您发布了一些原始配置文件?那是什么以及如何使用它?
  • 这没有回答一个被问到的问题。您回答了如何在 Jenkins 管道中设置单个部署密钥。问题是关于如何为子模块设置不同的凭据。
【解决方案2】:
  1. 否 - git 插件 supports only a single key(在撰写本文时)
  2. 根据git plugin docs,默认行为是根本不为子模块使用凭据。布尔标志告诉插件改为使用父凭据。它在下面使用的 git 插件不支持使用任何其他凭据的想法。
  3. 这很难找到,但我的 Github 项目也遇到了同样的问题 - 它使用了模块和 Github does not allow the same deploy key to be used across projects

为了解决这个问题,我首先set up a github app,安装它,并分配项目及其子模块。这个应用程序能够生成可用于克隆的访问密钥 - 所以我使用这些凭据进行克隆。我在 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 命令不会引用任何环境变量。但是,它看起来像这些access tokens are ephemeral,因此有所缓解。

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

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

【讨论】:

猜你喜欢
  • 2010-11-07
  • 1970-01-01
  • 2020-08-16
  • 1970-01-01
  • 2017-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-07
相关资源
最近更新 更多