将多个git代码库检出到同一个Jenkins工作区

153

使用Jenkins 1.501和Jenkins Git插件1.1.26。

我有3个不同的git存储库,每个存储库中都有多个项目。

现在我需要将3个git存储库中的所有项目都检出到Jenkins从机上的同一工作区。 我已在:源代码管理:多个SCM 中定义了每个git存储库。但是每次检出存储库时,前一个存储库(及其关联的项目)都会被删除。

我已经阅读了这篇文章:

http://jenkins.361315.n4.nabble.com/multiple-git-repos-in-one-job-td4633300.html

但它并没有真正帮助我。 我尝试为所有存储库在本地存储库子目录(可选)下指定相同的文件夹,但结果相同。

如果在Jenkins中无法实现此目标,我猜可以使用一些预构建步骤/脚本来将项目移动到正确的位置。 修改项目的构建配置不是一个选择。

9个回答

87

通过多个SCMs插件:

  • 为每个需要检出的仓库(主项目或依赖项目)创建一个不同的仓库条目。

  • 对于每个项目,在“高级”菜单中(第二个“高级”菜单,每个仓库有两个标记为“高级”的按钮),找到“本地子目录存储库(可选)”文本框。在那里可以指定你想将项目复制到的“工作空间”目录中的子目录。你可以映射我的开发计算机的文件系统。

“第二个高级菜单”不再存在,取而代之的是使用“添加”按钮(在“附加行为”部分),并选择“检出到子目录”

  • 如果你正在使用Ant,由于现在build.xml文件与构建目标不在工作区根目录中,而是在子目录中,因此必须在“调用Ant”配置中反映该情况。为此,在“调用Ant”中,按“高级”并填写“Build file”输入文本,包括build.xml所在的子目录的名称。

3
这似乎已经过时了。在编写此文时,Multiple SCMs插件GIT代码片段中不包含可选子路径。 - AlexeiOst
14
每个代码库中都有一个名为“Add”的下拉列表。在其中,您可以找到选项“Checkout to a sub-directory”,它执行相同的操作。 - Gary Ye
1
我按照你的指南使用了多个SCM插件和Git,但我遇到了另一个有趣的问题。它似乎不想正确地为不同的代码库检出相同的分支(develop)。它尝试通过哈希来检出提交(这仅在第一个代码库中有效)。对此有什么解决办法吗? - Lefteris
1
已弃用:用户应迁移到https://wiki.jenkins-ci.org/display/JENKINS/Pipeline+Plugin。Pipeline提供了一种更好的检出多个SCM的方式,并得到Jenkins核心开发团队的支持。 - phunehehe
1
管道需要您学习一种新的DSL,这对于我们想要完成的非常简单的任务(从多个存储库中检查代码)来说有点过于繁琐。在Jenkins管道DSL周围出现一个体面的GUI之前,请坚持使用Multiple SCM插件。我可以报告它在Jenkins 2.17上运行良好。 - Burak Arslan
显示剩余3条评论

82

使用Jenkins + Git插件无法在单个工作区中同时检出多个存储库。

作为解决方法,您可以设置一个shell脚本步骤,在构建时将每个需要的存储库检出到作业工作区,也可以拥有多个上游作业,每个作业只检出一个存储库,然后复制到最终项目工作区(在各种方面都存在问题)。

以前,多个SCM插件可以帮助解决这个问题,但现在已被弃用。从多个SCM插件页面:“用户应迁移到https://wiki.jenkins-ci.org/display/JENKINS/Pipeline+Plugin。Pipeline提供了检出多个SCM的更好方法,并得到Jenkins核心开发团队的支持。”


为什么第一种方法有问题?拆分工作似乎是一个好的实践。 - CurtainDog
1
这通常是一个好的实践,但当您需要在同一物理位置进行多个检出时,维护就成为了一个巨大的问题。例如,如果您想创建一个分支构建,您将不得不克隆4个作业,然后逐个更改每个作业的路径。当然有插件可以帮助解决这个问题,但最好的方法是从单个作业中检出到相对路径。然后,您可以克隆任意数量的作业而无需更改设置。 - CIGuy
1
你需要将它从正确答案中更改,因为它已不再相关。 - Dvir669
3
管道需要你学习一种新的DSL,这对于我们想要完成的非常简单的任务(从多个存储库检查代码)来说有点过于复杂。在Jenkins管道DSL周围出现一个像样的GUI之前,请继续使用Multiple SCM插件。我可以报告它在Jenkins 2.17上运行良好。 - Burak Arslan
2
我最近遇到了多个仓库同样的问题。尽管我和@BurakArslan一样对新的DSL持怀疑态度,但现在我正在使用Pipeline插件。它实际上并不像我想象的那么糟糕,并且还附带一个相当不错的片段生成器。仅使用了2个小时后,我现在更喜欢这种方法,因为我最终可以将管道构建脚本与其他代码一起提交到Git中。 - Ben
显示剩余2条评论

60

由于多版本控制插件已被弃用。

使用Jenkins Pipeline,可以检出多个git仓库并在使用gradle构建后进行编译。

node {   
def gradleHome

stage('Prepare/Checkout') { // for display purposes
    git branch: 'develop', url: 'https://github.com/WtfJoke/Any.git'

    dir('a-child-repo') {
       git branch: 'develop', url: 'https://github.com/WtfJoke/AnyChild.git'
    }

    env.JAVA_HOME="${tool 'JDK8'}"
    env.PATH="${env.JAVA_HOME}/bin:${env.PATH}" // set java home in jdk environment
    gradleHome = tool '3.4.1' 
}

stage('Build') {
  // Run the gradle build
  if (isUnix()) {
     sh "'${gradleHome}/bin/gradle' clean build"
  } else {
     bat(/"${gradleHome}\bin\gradle" clean build/)
  }
}
}

你可能希望考虑使用Git子模块代替自定义的流程。

3
谢谢!“dir”块是关键,我之前不知道为什么在我的工作区只看到最近克隆的代码库。 - bonh
在多个版本控制系统下,“更改”的概念是如何考虑的?它只是由组成作业的所有存储库中看到的更改总和吗?如果可能的话,最好可以从每个存储库中列出它们,例如“来自XXX存储库的23个更改,来自YYY存储库的3个更改”,或者类似这样更紧凑的东西。 - jxramos
我正在使用git子模块,但当任何一个多个仓库中创建了新的PR时,我需要更改分支。有什么办法可以实现吗? - Arnold Roa
1
@ArnoldRoa 不确定你的设置。假设你有Github,那么当PR被创建时,你会收到一个Webhook事件 - 在该事件中,该PR的分支将在事件中提供(或者至少是某种引用)。因此,您可以简单地获取该事件的分支名称。虽然我还没有尝试过。 - Joker

21

3
谢谢,太好了。我可以将两个Bitbucket路径放入存储库部分,现在我如何告诉Repo1检出“develop”分支,而对于Repo2检出“fixes”分支?我在Jenkins中看到了要构建的分支部分,我该如何设置存储库名称和Refsec在分支指定器中(空白为“任何”),以便每个存储库都可以检出我想要的相应分支?或者我做错了,我应该点击说“多个SCM”的布尔值? - pelos
@pelos,你找到解决方案了吗? - Govind
目前我们没有使用yml文件,而是使用常规任务完成了两个不同的工作流程。 - pelos

7

Jenkins: 多重版本控制(SCM)已被废弃。 GIT插件 - 无法用于多个代码库。

编写脚本/流水线是正确的方法。


5
根据仓库之间的关系,另一种方法是将另一个仓库(仓库)作为git子模块添加到其中一个仓库中。Git子模块创建对其他存储库的引用。这些子模块存储库只有在克隆“超级项目”(官方术语)时指定--recursive标志时才会被克隆。
以下是将子模块添加到当前项目的命令: git submodule add <repository URI path to clone> 我们使用Jenkins v1.645,而git SCM将默认进行超级项目的递归克隆。 然后您将在同一Jenkins作业工作区中获得超级项目文件和所有相关(子模块)存储库文件的各自目录。
不保证这是正确的方法,但这是一种方法。

1
如何将子模块更改为不同的分支?我想设置Jenkins在任何创建PR的分支上运行测试。 - Arnold Roa

2
我也曾遇到过这个问题。我使用了Trigger/call builds on other projects解决了它。对于每个代码库,我使用参数调用下游项目。
主项目:
This project is parameterized
String Parameters: PREFIX, MARKETNAME, BRANCH, TAG
Use Custom workspace: ${PREFIX}/${MARKETNAME}
Source code management: None

然后,对于每个代码库,我会像这样调用下游项目:

Trigger/call builds on other projects: 
Projects to build: Linux-Tag-Checkout
Current Build Parameters
Predefined Parameters: REPOSITORY=<name>

Downstream project: Linux-Tag-Checkout:

This project is parameterized
String Parameters: PREFIX, MARKETNAME, REPOSITORY, BRANCH, TAG
Use Custom workspace:${PREFIX}/${MARKETNAME}/${REPOSITORY}-${BRANCH}
Source code management: Git
git@<host>:${REPOSITORY}
refspec: +refs/tags/${TAG}:refs/remotes/origin/tags/${TAG}
Branch Specifier: */tags/${TAG} 

1
在单个工作区中同时检出多个存储库是可能的,使用Jenkins + Git插件(也许只有在较新的版本中才能实现)。
在“源代码管理”部分,不要选择“Git”,而是选择“多个SCMs”并添加多个git存储库。
确保在除一个之外的所有存储库中,将“检出到子目录”操作作为“附加行为”添加,并指定一个单独的子目录。

我相信你使用的是(已弃用的)多重SCM插件而不是原生Git插件。 - Robert

0

我们正在使用git-repo来管理我们的多个GIT存储库。还有一个Jenkins Repo插件,它允许将由git-repo管理的所有或部分存储库检出到同一Jenkins作业工作区。


你如何解决这个问题?我已经安装了你提到的插件,并阅读了关于repo和插件的资料,但我不知道如何设置Jenkins来克隆两个仓库并在一个项目中执行... - GreenAsJade
为了使用Repo,需要创建一个特殊的仓库,其中只包含清单文件。在这个文件中,您可以指定有关其他仓库的所有信息。清单文件的确切格式在git-repo项目的docs/manifest-format.txt文件中进行了描述(https://gerrit.googlesource.com/git-repo/+/master/docs/manifest-format.txt)。在配置Jenkins Repo作业的一部分时,您需要指定“清单”仓库的位置以及可选的“清单”文件名称(您可能有多个文件)。清单中指定的所有仓库都将被克隆。 - vladisld

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