Jenkins - Git子模块凭据与父存储库不同

20

背景

Jenkins用于从Git repo构建工件,该Git repo具有一个Git子模块。这些子模块不在同一个repo中,甚至不在同一个终端点上,因此父项目检出良好,因为凭据(ssh密钥A)与主/父repo关联,但可预见的是,在Jenkins的视角下,针对子模块失败,因为凭据(ssh密钥B)与repo无关。

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

问题

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

输入图像描述

系统信息

在Docker Machine(本地)上运行Jenkins

在CentOS(生产)上运行Jenkins

Jenkins版本:2.60.2(两者皆是)

Git插件版本:3.6.4(两者皆是)


3
同样的问题在这里。 - Yefei
2个回答

4
  1. 不行 - git插件(截至目前)仅支持单个密钥
  2. 根据git插件文档,子模块的默认行为是根本不使用凭据。布尔标志告诉插件改为使用父凭据。它使用的底层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子模块时,请替我打他们。

我已经向git插件添加了一个功能请求,以支持GitHub App本地化,这至少解决了GitHub的问题:https://issues.jenkins.io/browse/JENKINS-67600 - Dan Alvizu
这对我很有帮助,谢谢!不过,使用我的git版本时,需要执行以下命令:git submodule update --init,还原则需执行 git checkout .gitmodules - Pete

1

是的,这很容易实现。您可以创建公钥/私钥对,并将其设置为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']]]

当这个流水线代码运行时,它会将存储库检出到工作目录的分支、提交等位置。您也可以指定目录。
因此,您可以使用它来检出一堆存储库并为它们使用特定的分支。

2
这个回答不是很清楚。添加第二个凭据很容易,但是如何将其“映射”到指定的仓库?看起来你贴出了一些原始配置文件?那是什么,我该怎么使用它? - Daniele Testa
1
这并没有回答任何一个问题。你回答了如何在Jenkins管道中设置单个部署密钥的问题。问题是关于如何为子模块设置不同的凭据。 - Dan Alvizu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接