How to check out a Pull-Request with Jenkins Pipeline?

13,528

Solution 1

It turned out this can be made working by setting a refspec property on the checkout configuration object:

checkoutConfig.with {
    branches = [[ name: 'pr/4711' ]]
    userRemoteConfigs[0].refspec = '+refs/pull/*/head:refs/remotes/origin/pr/*'
}

See also: https://gist.github.com/piscisaureus/3342247

Solution 2

If you're working with bitbucket:

checkout([$class: 'GitSCM', branches: [[name: 'FETCH_HEAD']], 
doGenerateSubmoduleConfigurations: false, extensions: [
                    [$class: 'LocalBranch'],
                    [$class: 'CleanBeforeCheckout']], 
                    submoduleCfg: [], userRemoteConfigs:  [
                    [refspec: "refs/pull-requests/${prNumber}/from:pr/${prNumber}", 
       credentialsId: "${credentialId}",url: "${cloneurl}"]]])

Solution 3

Based on this doc about fetching a pull request.

Assuming you pass the PR number as a parameter:

checkout([$class: 'GitSCM', branches: [[name: "FETCH_HEAD"]],
  extensions: [[$class: 'LocalBranch']],
  userRemoteConfigs: [[refspec: "+refs/pull/${params.PR_NUMBER}/head:refs/remotes/origin/PR-${params.PR_NUMBER}", url: "https://${GITHUB_TOKEN}@github.com/${YOUR_REPO}"]]])

What's going on here:

  • First, you fetch refs for PullRequests
  • Then you checkout to the FETCH_HEAD
  • LocalBranch is required to avoid detached HEAD on the Jenkins agent

Cheers!

Solution 4

Inspired by previous responses and sources https://www.git-tower.com/learn/git/faq/detached-head-when-checkout-commit i wrote a simple shared library pipeline step:

checkoutPullRequest.groovy

Void call(String prNbr, String repo) {
    checkout([$class: 'GitSCM',
        branches: [[name: "FETCH_HEAD"]],
        doGenerateSubmoduleConfigurations: false,
        extensions: [[$class: 'LocalBranch'], [$class: 'RelativeTargetDirectory', relativeTargetDir: "${repo}"]],
        userRemoteConfigs: [[refspec: "+refs/pull/${prNbr}/head:refs/remotes/origin/PR-${prNbr} +refs/heads/master:refs/remotes/origin/master",
                            url: "https://${env.GITHUB_TOKEN}@github.com/githubusername/${repo}"]]
    ])
}

so in your pipeline Jenkinsfile you can just use

checkoutPullRequest('926', 'appgitrepo')
Share:
13,528
Thomas Hirsch
Author by

Thomas Hirsch

Updated on August 01, 2022

Comments

  • Thomas Hirsch
    Thomas Hirsch over 1 year

    I would like to build a Pipeline that integrates multiple repositories.

    The general idea:

    1. Provide a branch name as input.
    2. Use the GitHub-API to find Pull-Requests across several projects, that were created from a branch with that name.
    3. Make (shallow) clones from several repositories, checking out the specified Pull-Requests.

    Note that I am not trying to trigger the build itself from a Pull-Request. The triggering Job is just a plain Pipeline script. So checkout scm does not apply in my case. I would be nice to get this triggered from Pull-Requests. The many Multi-Branch plugins for Jenkins do not help me though, because they assume only a single repository to be part of the build.

    So far, I mostly avoided calling git from an sh step, because that would bring me close to throwing away any and all Jenkins-Git-integration.

    How, if at all, can I use the Pipeline checkout method to directly check out a Pull-Request?

    Is this even in scope of the checkout method? Probably, what I am looking for is interacting directly with the JGit client of Jenkins, at which point I might just as well use sh commands...

  • dlauzon
    dlauzon over 2 years
    To see more Jenkins checkout details/options, you can use Jenkins' Pipeline Syntax Snippet Generator, pick the Sample Step named 'checkout: Check out from version control', pick 'Git' as the SCM, and under 'Additional Behaviours', click 'Add' to see a list of possibilities. E.g. add the behaviour named 'Calculate changelog against a specific branch' and you'd be able to set the source and target branch of the PR, so the changeset (i.e. which files were changed, which can be used in conditions in pipeline steps) would be generated accordingly.