Jenkins 在 GitHub 上的 PR 构建失败 [英] Jenkins build fail for PR from GitHub

查看:34
本文介绍了Jenkins 在 GitHub 上的 PR 构建失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

一直失败并出现以下错误

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

即使是

要从某个拉取请求加载共享库,您必须做两件事:

  1. 将以下引用规范添加到共享库的 Jenkins 全局配置中:

    +refs/pull-requests/*/merge:refs/remotes/@{remote}/PR-*

  2. 在加载该库时,您必须使用"origin/${env.BRANCH_NAME}" 而不是仅使用 env.BRANCH_NAME,例如:>

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

使用 Bitbucket Merge 的替代解决方案

条件参考规范

作为后备;我记得包括 PR 在内的 refspec 有时对我不起作用.在这种情况下,您可以使用:

def isPr() {env.CHANGE_ID != null}def respec = '+refs/heads/*:refs/remotes/origin/*'如果(isPr()){respec += ' +refs/pull-requests/*/merge:refs/remotes/origin/PR-*'}checkout([$class: 'GitSCM',分支:[[名称:env.BRANCH_NAME]],doGenerateSubmoduleConfigurations: false,submoduleCfg: [],用户远程配置:[[参考规格:重新规格,url: '<repo URL>']]])

条件分支名称

def isPr() {env.CHANGE_ID != null}定义分支如果(isPr()){branch = "refs/remotes/origin/pull-requests/${env.CHANGE_ID}/merge"} 别的 {分支 = "*/master"}checkout([$class: 'GitSCM',分支:[[名称:分支]],doGenerateSubmoduleConfigurations: false,submoduleCfg: [],用户远程配置:[[refspec: '+refs/heads/*:refs/remotes/origin/* +refs/pull-requests/*:refs/remotes/origin/pull-requests/*',url: '<repo URL>']]])

在 Jenkins 中使用 Merge 的替代解决方案

条件参考规范

def isPr() {env.CHANGE_ID != null}def refspec = '+refs/heads/*:refs/remotes/origin/*'如果(isPr()){refspec += ' +refs/pull-requests/*/merge:refs/remotes/origin/PR-*'}checkout([$class: 'GitSCM',doGenerateSubmoduleConfigurations: false,扩展:[[$class:'PreBuildMerge',选项:[mergeRemote:refs/remotes/origin",mergeTarget:env.BRANCH_NAME]],submoduleCfg: [],用户远程配置:[[参考规格:参考规格,url: '<repo URL>']]])

条件合并

def isPr() {env.CHANGE_ID != null}定义扩展 = []如果(isPr()){extensions = [[$class: 'PreBuildMerge', options: [mergeRemote: "refs/remotes/origin/pull-requests", mergeTarget: "${env.CHANGE_ID}/from"]]]}checkout([$class: 'GitSCM',doGenerateSubmoduleConfigurations: false,扩展:扩展,submoduleCfg: [],用户远程配置:[[refspec: '+refs/heads/*:refs/remotes/origin/* +refs/pull-requests/*:refs/remotes/origin/pull-requests/*',url: '<repo URL>']]])

I'm using jenkins pipeline to build my github project. When I raise a pull request (PR) on GitHub, its creating a job "pr-head"

which fails all the time with below error

Let me know if you have any suggestions for this

Even the answers in Git PullRequest job failed. Couldn't find any revision to build. Verify the repository and branch configuration for this job did not solve my problem

解决方案

Update 2019/03/22:

Quick anser

Use a refspec which fits your git server's PR handling. E.g. for Bitbucket that could be:

+refs/pull-requests/*/merge:refs/remotes/@{remote}/PR-*

Full Answer

There is an open ticket about this: https://issues.jenkins-ci.org/browse/JENKINS-52668?filter=18657

EDIT:

I was able to reproduce this issue using a Jenkins multibranch pipeline together with the github plugin and a manual call to the checkout step.

For Bitbucket I found several options how to build PRs. I now even found a way to skip the conditional there. See below.

Recommendation

Whenever possible I'd recommend using checkout scm which works for PRs easily.

If you need to use the checkout step manually you could try to adjust your Jenkinsfile in order to do things manually as I did for checking out a bitbucket repo.

Easiest way should be to do a checkout scm at least one time to see how it should be done and use that values accordingly in the manual checkout steps. You'll need some if condition for the case that you're not building a PR.


Github

I finally got my small sample project buildin PRs from github using the following code. For my quick test I did a PR from some branch. In case you're using a fork as source for the PR it may need some further adjustment.

As stated in https://stackoverflow.com/a/36359706/4279361 you can leave out 'branches to build' option to not get this error. However depending on your PR merge strategy you'd still need to configure the merge accordingly:

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

For bitbucket you have to do the almost the same. However you'll have the option to the merge commit done in bitbucket directly in which case you do not need to do the merge in Jenkins but need to switch to the PR branch instead. You may either work with a conditional refspec or choose the branch conditionally. That makes four options a shown below. So far I didn't find an option which does not involve a conditional. :(

Recommended solutions

Following solutions to me seems most usable. They do not involve any conditionals and make use of the BRANCH_NAME variable. However it occurred to me that sometimes I got an error about an invalid refspec. In those cases please use one of the alternative solutions as written below.

Using Bitbucket Merge

Use the merge which as prepared by the Bitbucket server

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

Using Jenkins Merge

Or you decide to let Jenkins do the merge. You may either use a conditional refspec or a conditional merge into the 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>'
    ]]
])

Shared library

To use PR branches alongside a global shared library it would seem like the most straight-forward way would be to use the Discover other refs option when configuring the source control for your library. However that didn't work for me :(

To load a shared library from some pull request you have to do two things:

  1. Add the following refspec to your shared library's Jenkins global configuration:

    +refs/pull-requests/*/merge:refs/remotes/@{remote}/PR-*
    

  2. Instead of just using env.BRANCH_NAME you have to use"origin/${env.BRANCH_NAME}" when loading that library, like:

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

Alternative Solution using Bitbucket Merge

Conditional Refspec

Just as a fallback; I can remember that the refspec including the PRs sometimes didn't work for me. In that case you could use:

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

Conditional Branch Name

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

Alternative Solution using Merge in Jenkins

Conditional refspec

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

Conditional merge

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

这篇关于Jenkins 在 GitHub 上的 PR 构建失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆