在 Jenkins 中,如何将项目签出到特定目录中(使用 GIT)

Posted

技术标签:

【中文标题】在 Jenkins 中,如何将项目签出到特定目录中(使用 GIT)【英文标题】:In Jenkins, how to checkout a project into a specific directory (using GIT) 【发布时间】:2012-04-03 19:19:55 【问题描述】:

对于“svn”风格感到抱歉 - 我们正在从 SVN 迁移到 GIT(包括我们的 CI Jenkins 环境)。

我们需要的是能够让 Jenkins 将 GIT 项目(存储库?)签出(或者我应该说克隆?)到特定目录中。我们已经尝试了一些 refspecs 魔法,但它并不是很容易理解和成功使用。

此外,如果在同一个 Jenkins 项目中,我们需要将多个私有 GitHub 存储库检出到项目根目录下的多个单独目录中,请问我们该怎么做?

我们已经安装了 GitHub 插件。希望我们的措辞正确。

【问题讨论】:

【参考方案1】:

只需在 git 操作中添加“dir wrapper”即可:

dir('subDir') 
    checkout scm

【讨论】:

【参考方案2】:

从url中找到repoName,然后checkout到指定目录。

String url = 'https://github.com/foo/bar.git';
String[] res = url.split('/');
String repoName = res[res.length-1];
if (repoName.endsWith('.git')) repoName=repoName.substring(0, repoName.length()-4);

checkout([
  $class: 'GitSCM', 
  branches: [[name: 'refs/heads/'+env.BRANCH_NAME]],
  doGenerateSubmoduleConfigurations: false,
  extensions: [
    [$class: 'RelativeTargetDirectory', relativeTargetDir: repoName],
    [$class: 'GitLFSPull'],
    [$class: 'CheckoutOption', timeout: 20],
    [$class: 'CloneOption',
        depth: 3,
        noTags: false,
        reference: '/other/optional/local/reference/clone',
        shallow: true,
        timeout: 120],
    [$class: 'SubmoduleOption', depth: 5, disableSubmodules: false, parentCredentials: true, recursiveSubmodules: true, reference: '', shallow: true, trackingSubmodules: true]
  ],
  submoduleCfg: [],
  userRemoteConfigs: [
    [credentialsId: 'foobar',
    url: url]
  ]
])

【讨论】:

【参考方案3】:

我没有使用github插件,但是从介绍页面看,它或多或少有点像gerrit-trigger插件。

您可以安装 git 插件,它可以帮助您检查您的项目,如果您想在一个 jenkins 作业中包含多个项目,只需将 Repository 添加到您的作业中。

【讨论】:

【参考方案4】:

在新的 Pipeline 流程中,下图可能会有所帮助..

【讨论】:

这会在尝试使用git 可执行文件时抛出错误,说没有.git 文件【参考方案5】:

在新的 Jenkins 2.0 管道(以前称为工作流插件)中,这样做的方式不同:

主存储库 其他附加存储库

这里我特指Multibranch Pipeline 2.9版。

主存储库

这是包含您的 Jenkinsfile 的存储库。

在您的管道项目的配置屏幕中,输入您的存储库名称等。

不要使用其他行为> 签出到子目录。这会将您的 Jenkinsfile 放在子目录 where Jenkins cannot find it 中。

Jenkinsfile 中,使用dir() 签出子目录中的主存储库:

dir('subDir') 
    checkout scm

其他存储库

如果您想查看更多存储库,请使用 Pipeline Syntax 生成器自动生成 Groovy 代码 sn-p。

在您的管道项目的配置屏幕中:

    选择管道语法。在样本中 步骤下拉菜单,选择checkout: General SCM。 选择您的 SCM 系统,例如 Git。填写常用信息 关于您的存储库或软件仓库。 请注意,在多分支管道中,环境变量 env.BRANCH_NAME 包含主存储库的分支名称。 在其他行为下拉菜单中,选择 签出到子目录 单击生成 Groovy。 Jenkins 将显示 Groovy 代码 sn-p 对应于您指定的 SCM 结帐。 将此代码复制到您的管道脚本或Jenkinsfile

【讨论】:

这里的代码 sn-p:checkout([$class: 'GitSCM', branches: [[name: '*/branchname']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'MyDirectory']], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'myId', url: 'https://github.com/jenkinsci/jenkins.git']]]) 其实我认为@davey_dev 的答案是正确的。如果您首先使用dir('subDir') 步骤进入子目录,那么 repo 将被克隆到 subDir 的另一个子目录中,您将获得subDir/[repo name]/[contents]。我正在寻找一种获取dubDir\[contents] 的方法,因此使用relativeTargetDir 是正确的方法。 除此之外,如果您使用主存储库执行此操作,您可能还需要使用本文中所示的skipDefaultCheckout 选项以避免签出两次devops.stackexchange.com/a/1074【参考方案6】:

值得研究 Pipeline 插件。使用该插件,您可以将多个 VCS 项目签出到相对目录路径中。事先为每个 VCS 签出创建一个目录。然后向新签出的 VCS 工作区发出命令。就我而言,我使用的是 git。但你应该明白了。

node
    def exists = fileExists 'foo'
    if (!exists)
        new File('foo').mkdir()
    
    dir ('foo') 
        git branch: "<ref spec>", changelog: false, poll: false, url: '<clone url>'
        ......
    
    def exists = fileExists 'bar'
    if (!exists)
        new File('bar').mkdir()
    
    dir ('bar') 
        git branch: "<ref spec>", changelog: false, poll: false, url: '<clone url>'
        ......
    
    def exists = fileExists 'baz'
    if (!exists)
        new File('baz').mkdir()
    
    dir ('baz') 
        git branch: "<ref spec>", changelog: false, poll: false, url: '<clone url>'
        ......
    

【讨论】:

这给出了错误,Scripts not permitted to use new java.io.File java.lang.String,这是真的。有关使用管道代码 sn-p 生成器创建管道脚本或 Jenkinsfile 所需的代码的方法,请参阅我的答案。 您可以使用sh "mkdir -p directory 作为Scripts not permitted... 的解决方法 dir ('foo') 将创建文件夹,如果它不存在【参考方案7】:

我同意@Łukasz Rżanek 的观点,我们可以使用git plugin

但是,我使用选项:结帐到子方向,启用如下: 在源代码管理中,勾选 Git 点击添加按钮,选择结帐到子目录

【讨论】:

但是不能为不同的repos设置不同的文件夹。 就我而言,我的 Jenkins 工作只从一个存储库中克隆代码。你说的这种情况我没试过。 如果我们不希望它成为子目录怎么办?你可以使用“../other_dir” - 回答我自己的问题,你可以使用相对结帐,并在构建外壳中使用“cd ../other_dir”更改到该目录【参考方案8】:

此外,如果在同一个 Jenkins 项目中,我们需要将多个私有 GitHub 存储库检出到项目根目录下的多个单独目录中。请问我们该怎么做?

Jenkin's Multiple SCMs Plugin 很好地为我解决了几个存储库问题。我刚刚开始了一个项目构建,它在一个公共文件夹下检查了四个不同的 git 存储库。 (我有点不愿意将 git 超级项目用作 Łukasz Rżanek 的 suggested previously,因为 git 在没有子模块的情况下已经足够复杂了。)

【讨论】:

多个 SCM 不显示每个版本的更改,有一个错误,他们已经 1.5 年没有修复它:(【参考方案9】:

Jenkins 的默认git plugin 可以很好地完成这项工作。

添加新的 git 存储库(项目配置 > 源代码管理 > 检查 GIT 选项)到项目后导航到插件设置的底部,就在 存储库浏览器上方em> 地区。应该有一个高级按钮。单击它后,应该会出现一个新表单,其值描述为 本地子目录 for repo(可选)。将此设置为folder 将使插件将存储库检出到与您的工作区相关的文件夹中。通过这种方式,您可以在项目中拥有任意数量的存储库,全部位于不同的位置。

或者,如果您使用的项目允许这样做,您可以使用 GIT 子模块,它类似于 SVN 中的外部路径。在GIT Book 中有一个关于该主题的部分。如果这不违反某些政策,子模块的使用相当简单,为您提供了强大的方法来控制将要导入的位置、版本/标签/分支,并且它将在您的本地存储库中可用,并为您提供更好的可移植性。

显然,GIT 插件支持签出子模块,因此 Jenkins 可以非常有效地使用它们。

【讨论】:

只有一个 Local subdirectory for repo 设置适用于所有存储库,因此这并不适合管理多个存储库。见issues.jenkins-ci.org/browse/JENKINS-13086。 我什至没有看到使用 Git 插件 2.4.2 的这个选项。这个答案已有 4 年历史,所以该选项可能已被删除? (但是,我确实看到了@biolinh 在另一个答案中提到的“签出到子目录”,但这是针对所有存储库的。 “签出到子目录”位于 git 插件的“其他行为”部分。但是,这仍然将您限制为每个作业只有一个 git 存储库。如果每个作业需要多个 git 存储库,请使用 Jenkins 管道。

以上是关于在 Jenkins 中,如何将项目签出到特定目录中(使用 GIT)的主要内容,如果未能解决你的问题,请参考以下文章

使用 Jenkins 管道将多个 git 存储库签出到同一个作业中

将所有项目签出到某个分支

使用 GIT 如何将不同提交中的文件签出到新分支中? [复制]

如何将 Bitbucket 的 pull request 签出到本地 review

从一个分支签出到另一个分支时,Pycharm“保持更改”? [复制]

在 Bash 的文件路径参数中获取最后一个目录名/文件名