在 Jenkinsfile 中签出不同的分支是不可能的吗? [英] Is it impossible to checkout a different branch in Jenkinsfile?

查看:17
本文介绍了在 Jenkinsfile 中签出不同的分支是不可能的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have two branches on BitBucket: master and develop. I've also got a BitBucket Team Folder job configured on my Jenkins server to build that repository. On the develop branch there's the following Jenkinsfile:

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

    stage('Try different branch') {
        sh "git branch -r"
        sh "git checkout master"
    }
}

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

When Jenkins runs it, the build fails when it attempts to checkout 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] }

我原以为 git branch -r 命令会同时打印出 origin/masterorigin/develop,但出于某种原因只打印后者.

I had expected the git branch -r command to print out both origin/master and origin/develop, but for some reason it only prints the latter.

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

I've read around and tried to come up with any ways to do this: For example, I tried installing the SSH Agent Plugin for Jenkins and changed the Jenkinsfile to:

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

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

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

But it still doesn't appear to find origin/master. What's worse, the SSH agent seems to be killed before it attempts to checkout 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] }

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

My eventual plan is to commit something to develop and then merge it into master, but so far I have had very little luck. Has anybody got a possible solution or workaround?

PS:这似乎只是 Jenkinsfile 中的问题;我有一份自由式工作,做的事情与我想要的类似,而且效果很好.

PS: This only seems to be a problem in Jenkinsfile; I have a freestyle job that does something similar to what I want, and it works fine.

推荐答案

经过几个小时的反复试验,我想出了一个可能的解决方案.它部分基于马特的回答,但我必须对其进行修改才能使其正常工作.

After some hours of trial and error, I came up with a possible solution. It builds partly on Matt's answer, but I had to alter it to make it work.

Matt 在本质上是正确的:checkout scm 根本不够灵活,无法让我做我需要的事情,所以我不得不使用 GitSCM 来自定义它.主要兴趣点是:

Matt was correct in the essentials: checkout scm simply wasn't flexible enough to allow me to do what I needed, so I had to use GitSCM to customize it. The major points of interest are:

  • 添加了扩展 LocalBranch 以确保我签出到一个实际的分支,而不仅仅是一个分离的 HEAD.
  • 添加了扩展 WipeWorkspace 以删除工作区中的所有内容并强制进行完整克隆.我不认为这是我问题解决方案的一部分,但它仍然很方便.
  • 使用 credentialsId 属性指定 SSH 凭据,因为存储库是私有的.
  • Added extension LocalBranch to make sure I check out to an actual branch, and not just a detached HEAD.
  • Added extension WipeWorkspace to delete everything in the workspace and force a complete clone. I don't think this was a part of the solution to my question, but it was still handy to have.
  • Specified the SSH credentials using the credentialsId property since the repository is private.

无论出于什么原因,当执行 checkout 步骤时,它只签出分支,但没有设置它来跟踪远程分支.在找到更优雅的解决方案之前,我必须手动完成.

For whatever reason, when the checkout step is executed, it only checks out the branch, but does not set it to track the remote branch. Until I find a more elegant solution, I had to do this manually.

完成所有这些之后,我可以使用常规的 sh "git checkout master" 甚至 sh "git push",只要我将它们包含在 sshagent 步骤.

After all that was done, I could use regular sh "git checkout master" and even sh "git push", as long as I enclosed them in an sshagent step.

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

I added a working example of the resulting Jenkinsfile below, but please keep in mind that it shouldn't be used for anything close to production as it's still very much in its infancy; hardcoded version numbers and no checks for which branch you're in, for example.

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"
        }
    }
}

这篇关于在 Jenkinsfile 中签出不同的分支是不可能的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆