我在BitBucket上有两个分支:master
和develop
。我还在Jenkins服务器上配置了BitBucket Team Folder作业来构建该存储库。在develop
分支上有以下Jenkins文件:
node {
stage('Checkout') {
checkout scm
}
stage('Try different branch') {
sh "git branch -r"
sh "git checkout master"
}
}
当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] }
我原本期望git branch -r
命令可以打印origin/master
和origin/develop
,但出于某种原因,它只打印后者。
我已经阅读并尝试了解任何方法:例如,我尝试为Jenkins安装SSH代理插件并将Jenkins文件更改为:
node {
stage('Checkout') {
checkout scm
}
stage('Try different branch') {
sshagent(['Bitbucket']) {
sh "git branch -r"
sh "git checkout master"
}
}
}
但它似乎仍然没有找到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] }
我最终的计划是将某些内容提交到develop
,然后将其合并到master
,但到目前为止,我的运气很少。有没有人有可能的解决方案或解决方法?
PS:这似乎只是Jenkinsfile中的一个问题;我有一个类似于我想要的自由式工作,并且工作正常。
答案 0 :(得分:8)
经过几个小时的反复试验,我想出了一个可能的解决方案。它部分建立在马特的答案上,但我不得不改变它以使其发挥作用。
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"
}
}
}
答案 1 :(得分:5)
您可以使用为Git克隆和拉动创建的Jenkins管道中的内部函数。我还建议将分支克隆到单独的目录中。
checkout([$class: 'GitSCM',
branches: [[name: '*/branch_name']],
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'RelativeTargetDirectory',
relativeTargetDir: 'different_directory']],
submoduleCfg: [],
userRemoteConfigs: [[url: 'git@github.domain:org/repo.git']]])
答案 2 :(得分:2)
我无法得到上面的两个答案。我通过指定一个分支触发了一个Jenkins管道作业,并试图检查失败的作业中的另一个分支(开发):
error: pathspec 'develop' did not match any file(s) known to git.
我可以在失败的工作中看到这一点,这表明只提取了触发分支:
git fetch --no-tags --progress https://<github URL> +refs/heads/branch-name:refs/remotes/origin/branch-name
我通过更改远程获取配置并通过在触发的作业的Jenkinsfile中执行默认checkout scm
步骤后执行以下操作来获取所有分支来实现它:
sh """
git config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'
git fetch --all
"""
这要归功于这个答案https://stackoverflow.com/a/39986737/1988883
这也避免了必须为GitSCM script approvals配置Jenkins,我必须这样做才能尝试上面的两个解决方案
答案 3 :(得分:2)
您可以使用git命令,它是checkout
命令的高级版本
stage('Repo Checkout') {
steps {
deleteDir()
dir("repo-one-master") {
git url: "ssh://git@host.com/folder/project",
branch: 'master'
}
dir("repo-one-feature) {
git url: "ssh://git@host.com/folder/project",
branch: 'some-branch'
}
}
}
答案 4 :(得分:1)
问题在于Jenkins仅使用发现的分支来定义origin
。
@ swoop81答案有效,但是如果您只想签出一个分支,则只能获取该分支。
git config --add remote.origin.fetch +refs/heads/<branch-name>:refs/remotes/origin/<branch-name>
git fetch --no-tags https://<github-url> +refs/heads/<branch-name>:refs/remotes/origin/<branch-name>