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

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

问题描述

我在 BitBucket 上有两个分支:masterdevelop.我还在我的 Jenkins 服务器上配置了一个 BitBucket 团队文件夹作业来构建该存储库.在 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.

推荐答案

经过几个小时的反复试验,我想出了一个可能的解决方案.它部分建立在 Matt 的回答之上,但我必须对其进行更改才能使其发挥作用.

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天全站免登陆