Jenkins无法从GitHub建立PR

时间:2018-08-18 06:43:13

标签: jenkins github jenkins-pipeline jenkins-github-plugin

我正在使用jenkins管道来构建我的github项目。当我在GitHub上提出拉取请求(PR)时,它会创建工作“ pr-head”

job screenshot

始终失败,并显示以下错误

Error screenshot

如果您对此有任何建议,请告诉我

Git PullRequest job failed. Couldn't find any revision to build. Verify the repository and branch configuration for this job中的答案都不能解决我的问题

1 个答案:

答案 0 :(得分:4)

更新2019/03/22:

快速分析助手

使用适合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

我终于使用以下代码从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

对于位桶,您必须执行几乎相同的操作。但是,您可以选择直接在bitbucket中完成合并提交,在这种情况下,您无需在Jenkins中进行合并,而需要切换到PR分支。 您可以使用条件refspec或有条件地选择分支。这使得四个选项如下所示。到目前为止,我还没有找到不涉及条件的选项。 :(

推荐的解决方案

按照我的解决方案似乎最有用。它们不涉及任何条件,并使用BRANCH_NAME变量。但是我想到有时我会收到关于无效refspec的错误。在这种情况下,请使用以下替代方法之一。

使用Bitbucket合并

使用由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合并

或者您决定让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选项。但是,这对我不起作用:(

enter image description here

要从某些请求中加载共享库,您必须做两件事:

  1. 将以下refspec添加到共享库的Jenkins全局配置中:

    +refs/pull-requests/*/merge:refs/remotes/@{remote}/PR-*
    
  2. 加载该库时,您不仅要使用env.BRANCH_NAME,还必须使用"origin/${env.BRANCH_NAME}",例如:

    libBranch = env.BRANCH_NAME
    libId= "myLib@origin/${libBranch}"
    lib = library(libId)
    

使用Bitbucket合并的替代解决方案

条件参考规格

只是一个后备;我可以记住,包括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>'
    ]]
])

在詹金斯使用Merge的替代解决方案

条件参考规范

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>'
    ]]
])