我正在使用jenkins管道来构建我的github项目。当我在GitHub上提出拉取请求(PR)时,它会创建工作“ pr-head”
始终失败,并显示以下错误
如果您对此有任何建议,请告诉我
答案 0 :(得分:4)
使用适合git服务器PR处理的refspec。例如。对于Bitbucket可能是:
+refs/pull-requests/*/merge:refs/remotes/@{remote}/PR-*
有关于此的公开票: https://issues.jenkins-ci.org/browse/JENKINS-52668?filter=18657
我能够使用Jenkins多分支管道,github插件和手动调用checkout
步骤来重现此问题。
对于Bitbucket,我发现了几种构建PR的选项。我现在甚至找到了一种跳过此处条件的方法。见下文。
只要有可能,我建议您使用checkout scm
,它很容易用于PR。
如果您需要手动使用checkout
步骤,则可以尝试调整Jenkinsfile,以便像我检查位桶存储库那样手动执行操作。
最简单的方法应该是至少进行一次checkout scm
,以查看应如何进行并在手动结帐步骤中相应地使用该值。对于未建立PR的情况,您将需要一些前提条件。
我终于使用以下代码从github上获得了小样本项目PR。为了进行快速测试,我从某个分支机构进行了PR。如果您使用叉子作为PR的来源,则可能需要进一步调整。
如https://stackoverflow.com/a/36359706/4279361中所述,您可以省略“构建分支”选项,以免出现此错误。但是,根据您的PR合并策略,您仍然需要相应地配置合并:
def isPr() {
env.CHANGE_ID != null
}
// github-specific refspec
def refspec = "+refs/pull/${env.CHANGE_ID}/head:refs/remotes/origin/PR-${env.CHANGE_ID} +refs/heads/master:refs/remotes/origin/master"
def url = 'https://github.com/orgi/workflow-durable-task-step-plugin.git'
def extensions = []
if (isPr()) {
extensions = [[$class: 'PreBuildMerge', options: [mergeRemote: "refs/remotes/origin", mergeTarget: "PR-${env.CHANGE_ID}"]]]
}
checkout([
$class: 'GitSCM',
doGenerateSubmoduleConfigurations: false,
extensions: extensions,
submoduleCfg: [],
userRemoteConfigs: [[
refspec: refspec,
credentialsId: '<your credentials>',
url: url
]]
])
对于位桶,您必须执行几乎相同的操作。但是,您可以选择直接在bitbucket中完成合并提交,在这种情况下,您无需在Jenkins中进行合并,而需要切换到PR分支。 您可以使用条件refspec或有条件地选择分支。这使得四个选项如下所示。到目前为止,我还没有找到不涉及条件的选项。 :(
按照我的解决方案似乎最有用。它们不涉及任何条件,并使用BRANCH_NAME
变量。但是我想到有时我会收到关于无效refspec的错误。在这种情况下,请使用以下替代方法之一。
使用由Bitbucket服务器准备的合并
def respec = '+refs/heads/*:refs/remotes/origin/* +refs/pull-requests/*/merge:refs/remotes/origin/PR-*'
checkout([$class: 'GitSCM',
branches: [[name: env.BRANCH_NAME]],
doGenerateSubmoduleConfigurations: false,
submoduleCfg: [],
userRemoteConfigs: [[
refspec: respec,
url: '<repo URL>'
]]
])
或者您决定让Jenkins进行合并。您可以使用条件refspec或有条件地合并到PR中。
def refspec = '+refs/heads/*:refs/remotes/origin/* +refs/pull-requests/*/merge:refs/remotes/origin/PR-*'
checkout([$class: 'GitSCM',
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'PreBuildMerge', options: [mergeRemote: "refs/remotes/origin", mergeTarget: env.BRANCH_NAME]]],
submoduleCfg: [],
userRemoteConfigs: [[
refspec: refspec,
url: '<repo URL>'
]]
])
要将PR分支与全局共享库一起使用,最直接的方法似乎是在为库配置源控件时使用Discover other refs
选项。但是,这对我不起作用:(
要从某些请求中加载共享库,您必须做两件事:
将以下refspec添加到共享库的Jenkins全局配置中:
+refs/pull-requests/*/merge:refs/remotes/@{remote}/PR-*
加载该库时,您不仅要使用env.BRANCH_NAME
,还必须使用"origin/${env.BRANCH_NAME}"
,例如:
libBranch = env.BRANCH_NAME
libId= "myLib@origin/${libBranch}"
lib = library(libId)
只是一个后备;我可以记住,包括PR在内的refspec有时对我不起作用。在这种情况下,您可以使用:
def isPr() {
env.CHANGE_ID != null
}
def respec = '+refs/heads/*:refs/remotes/origin/*'
if (isPr()) {
respec += ' +refs/pull-requests/*/merge:refs/remotes/origin/PR-*'
}
checkout([$class: 'GitSCM',
branches: [[name: env.BRANCH_NAME]],
doGenerateSubmoduleConfigurations: false,
submoduleCfg: [],
userRemoteConfigs: [[
refspec: respec,
url: '<repo URL>'
]]
])
def isPr() {
env.CHANGE_ID != null
}
def branch
if (isPr()) {
branch = "refs/remotes/origin/pull-requests/${env.CHANGE_ID}/merge"
} else {
branch = "*/master"
}
checkout([$class: 'GitSCM',
branches: [[name: branch]],
doGenerateSubmoduleConfigurations: false,
submoduleCfg: [],
userRemoteConfigs: [[
refspec: '+refs/heads/*:refs/remotes/origin/* +refs/pull-requests/*:refs/remotes/origin/pull-requests/*',
url: '<repo URL>'
]]
])
def isPr() {
env.CHANGE_ID != null
}
def refspec = '+refs/heads/*:refs/remotes/origin/*'
if (isPr()) {
refspec += ' +refs/pull-requests/*/merge:refs/remotes/origin/PR-*'
}
checkout([$class: 'GitSCM',
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'PreBuildMerge', options: [mergeRemote: "refs/remotes/origin", mergeTarget: env.BRANCH_NAME]]],
submoduleCfg: [],
userRemoteConfigs: [[
refspec: refspec,
url: '<repo URL>'
]]
])
def isPr() {
env.CHANGE_ID != null
}
def extensions = []
if (isPr()) {
extensions = [[$class: 'PreBuildMerge', options: [mergeRemote: "refs/remotes/origin/pull-requests", mergeTarget: "${env.CHANGE_ID}/from"]]]
}
checkout([$class: 'GitSCM',
doGenerateSubmoduleConfigurations: false,
extensions: extensions,
submoduleCfg: [],
userRemoteConfigs: [[
refspec: '+refs/heads/*:refs/remotes/origin/* +refs/pull-requests/*:refs/remotes/origin/pull-requests/*',
url: '<repo URL>'
]]
])