是否不可能在 Jenkinsfile 中签出不同的分支? [英] Is it impossible to checkout a different branch in Jenkinsfile?
问题描述
我在 BitBucket 上有两个分支:master
和 develop
.我还在我的 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/master
和 origin/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 detachedHEAD
. - 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屋!