在Jenkinsfile中检查不同的分支是不可能的吗?

Tho*_*ene 12 git bitbucket jenkins jenkins-pipeline

我在BitBucket上有两个分支:masterdevelop.我还在Jenkins服务器上配置了BitBucket Team Folder作业来构建该存储库.在develop分支上有以下Jenkinsfile:

node {
    stage('Checkout') {
        checkout scm
    }

    stage('Try different branch') {
        sh "git branch -r"
        sh "git checkout master"
    }
}
Run Code Online (Sandbox Code Playgroud)

当Jenkins运行它时,构建在尝试签出时失败master:

[Pipeline] stage
[Pipeline] { (Try different branch)
[Pipeline] sh
[e_jenkinsfile-tests_develop-4R65E2H6B73J3LB52BLACQOZLBJGN2QG22IPONX3CV46B764LAXA] Running shell script
+ git branch -r
  origin/develop
[Pipeline] sh
[e_jenkinsfile-tests_develop-4R65E2H6B73J3LB52BLACQOZLBJGN2QG22IPONX3CV46B764LAXA] Running shell script
+ git checkout master
error: pathspec 'master' did not match any file(s) known to git.
[Pipeline] }
Run Code Online (Sandbox Code Playgroud)

我所预料的git branch -r命令打印出两个origin/masterorigin/develop,但由于某些原因,只打印了后者.

我已经阅读并试图想出任何方法来做到这一点:例如,我尝试为Jenkins安装SSH代理插件并将Jenkins文件更改为:

node {
    stage('Checkout') {
        checkout scm
    }

    stage('Try different branch') {
        sshagent(['Bitbucket']) {
            sh "git branch -r"
            sh "git checkout master"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但它似乎仍未找到origin/master.更糟糕的是,SSH代理似乎在尝试签出之前被杀死了master:

[Pipeline] { (Try different branch)
[Pipeline] sshagent
[ssh-agent] Using credentials ThomasKasene (Used to communicate with Bitbucket)
[ssh-agent] Looking for ssh-agent implementation...
[ssh-agent]   Exec ssh-agent (binary ssh-agent on a remote machine)
$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-M6pIguCUpAV4/agent.11899
SSH_AGENT_PID=11902
$ ssh-add /var/jenkins_home/workspace/e_jenkinsfile-tests_develop-4R65E2H6B73J3LB52BLACQOZLBJGN2QG22IPONX3CV46B764LAXA@tmp/private_key_2394129657382526146.key
Identity added: /var/jenkins_home/workspace/e_jenkinsfile-tests_develop-4R65E2H6B73J3LB52BLACQOZLBJGN2QG22IPONX3CV46B764LAXA@tmp/private_key_2394129657382526146.key (/var/jenkins_home/workspace/e_jenkinsfile-tests_develop-4R65E2H6B73J3LB52BLACQOZLBJGN2QG22IPONX3CV46B764LAXA@tmp/private_key_2394129657382526146.key)
[ssh-agent] Started.
[Pipeline] {
[Pipeline] sh
[e_jenkinsfile-tests_develop-4R65E2H6B73J3LB52BLACQOZLBJGN2QG22IPONX3CV46B764LAXA] Running shell script
+ git branch -r
  origin/develop
[Pipeline] sh
$ ssh-agent -k
unset SSH_AUTH_SOCK;
unset SSH_AGENT_PID;
echo Agent pid 11902 killed;
[ssh-agent] Stopped.
[e_jenkinsfile-tests_develop-4R65E2H6B73J3LB52BLACQOZLBJGN2QG22IPONX3CV46B764LAXA] Running shell script
+ git checkout master
error: pathspec 'master' did not match any file(s) known to git.
[Pipeline] }
Run Code Online (Sandbox Code Playgroud)

我最终的计划是提交一些内容develop,然后将其合并master,但到目前为止,我的运气很少.有没有人有可能的解决方案或解决方法?

PS:这似乎只是Jenkinsfile中的一个问题; 我有一个类似于我想要的自由式工作,它工作正常.

Tho*_*ene 16

经过几个小时的反复试验,我想出了一个可能的解决方案.它部分建立在马特的答案上,但我不得不改变它以使其发挥作用.

Matt在要点中是正确的:checkout scm根本不够灵活,不能让我做我需要的东西,所以我不得不用GitSCM它来定制它.主要兴趣点是:

  • 添加扩展名LocalBranch以确保我签出实际分支,而不仅仅是分离HEAD.
  • 添加了扩展WipeWorkspace以删除工作区中的所有内容并强制完全克隆.我不认为这是我的问题解决方案的一部分,但它仍然很方便.
  • credentialsId由于存储库是私有的,因此使用该属性指定SSH凭据.

无论出于何种原因,当checkout执行该步骤时,它仅检出分支,但不将其设置为跟踪远程分支.在找到更优雅的解决方案之前,我必须手动执行此操作.

完成所有这些之后,我可以使用常规sh "git checkout master"和偶数sh "git push",只要我将它们包含在一个sshagent步骤中.

我在下面添加了一个结果Jenkins文件的工作示例,但请记住,它不应该用于任何接近生产的东西,因为它仍处于起步阶段; 例如,硬编码的版本号并且不检查您所在的分支.

node {
    mvnHome = tool 'Maven'
    mvn = "${mvnHome}/bin/mvn"

    stage('Checkout') {
        checkout([
            $class: 'GitSCM',
            branches: scm.branches,
            extensions: scm.extensions + [[$class: 'LocalBranch'], [$class: 'WipeWorkspace']],
            userRemoteConfigs: [[credentialsId: 'Bitbucket', url: 'git@bitbucket.org:NAVFREG/jenkinsfile-tests.git']],
            doGenerateSubmoduleConfigurations: false
        ])
    }

    stage('Release') {
        // Preparing Git
        sh "git branch -u origin/develop develop"
        sh "git config user.email \"jenkins@thomaskasene.com\""
        sh "git config user.name \"Jenkins\""

        // Making and committing new verison
        sh "${mvn} versions:set -DnewVersion=2.0.0 -DgenerateBackupPoms=false"
        sh "git commit -am \"Released version 2.0.0\""

        // Merging new version into master
        sh "git checkout master"
        sh "git merge develop"
        sh "git checkout develop"

        // Making and committing new snapshot version
        sh "${mvn} versions:set -DnewVersion=3.0.0-SNAPSHOT -DgenerateBackupPoms=false"
        sh "git commit -am \"Made new snapshot version 3.0.0-SNAPSHOT\""

        // Pushing everything to remote repository
        sshagent(['Bitbucket']) {
            sh "git push"
            sh "git checkout master"
            sh "git push"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


swo*_*p81 8

我无法得到上面的两个答案。我通过指定一个分支来触发 Jenkins 管道作业,并试图检查作业中的另一个分支(开发),该分支失败了:

error: pathspec 'develop' did not match any file(s) known to git.
Run Code Online (Sandbox Code Playgroud)

我可以在失败的工作中看到这一点,这表明只有触发分支被获取:

git fetch --no-tags --progress https://<github URL> +refs/heads/branch-name:refs/remotes/origin/branch-name
Run Code Online (Sandbox Code Playgroud)

我通过更改远程获取配置并通过checkout scm在触发作业的 Jenkinsfile 中执行默认步骤后执行以下操作来获取所有分支来使其工作:

sh """
    git config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'
    git fetch --all
"""
Run Code Online (Sandbox Code Playgroud)

这要归功于这个答案/sf/answers/2799071621/

这也避免了我必须为GitSCM 脚本批准配置 Jenkins来尝试上述两种解决方案


Mat*_*ard 5

您可以使用Jenkins Pipeline中为Git克隆和拉取而创建的内部函数。我还建议将分支克隆到单独的目录中。

checkout([$class: 'GitSCM',
  branches: [[name: '*/branch_name']],
  doGenerateSubmoduleConfigurations: false,
  extensions: [[$class: 'RelativeTargetDirectory',
    relativeTargetDir: 'different_directory']],
  submoduleCfg: [],
  userRemoteConfigs: [[url: 'git@github.domain:org/repo.git']]])
Run Code Online (Sandbox Code Playgroud)