How To Add Pull Request Build Status Rule Before Merge In Github Multibranch Jenkins Project

jenkins
Reading Time: 4 minutes
Logo

Prerequisite

  • Knowledge About Pull Requests and Merge on SCM like Github
  • Jenkins and Jenkinsfile
  • Multibranch Strategies on a Git Project

Introduction

Whenever we build a project in a team or collaboration, Continous Integration of the work is an essential part of the project. The automation tools like Jenkins, Github Actions, Circle CI are quite useful tools for the DevOps group. The new changes require testing before integrating and that may be 100 or 1000 times in the development phase.We will be implementing one simple rule: to check the build status on main when a Pull Request is generated on the main branch before merging it using Jenkins.

Setup

I have created a setup for a multibranch pipeline on my Github repository. https://github.com/vaibhavkumar779/multibranchJenkinsPRbuildStatus and used Jenkins at my local system. while creating the mutibranch job in Jenkins use GitHub as the source and not Git. This provides us various pull request options for the build job.

Github Source option
Github source option
Options in Github source
Options in Github source

I have created a multibranch webhook for input from the Github repository. you can refer to the set-up at https://blog.knoldus.com/multibranch-pipelinewith-github-webhook/. While doing the webhook setup please select pushes and pull requests as inputs for this small project as shown below.

Pull Push Option
Pull Push Option

If you are using Jenkins on a local machine i.e on your laptop or desktop computer, you can use cross-platform applications like Ngrok that expose local servers on the Internet. You will be using terminal or Powershell if in windows. and get an output like:

Ngrok Terminal output
Ngrok Terminal output

The Project

We will be using a simple from main to development and from development to feature strategy/test. In this strategy, all the work of the application in the development phase is shifted to the development branch and while adding any new feature change or test we move to feature/test branches. The main branch handles deployment.

Scripting: Jenkinsfile

The whole pipeline of the project I maintained by Jenkinsfile which is common to all branches in our project. We will be using a simple Jenkinsfile as used on the repository

pipeline {
    agent any
    
    stages {
        stage('configuration') {
            steps {
                echo 'BRANCH NAME: ' + env.BRANCH_NAME
                echo sh(returnStdout: true, script: 'env')
            }
        }
        
        stage('Testing') {
            steps {
                script {
                    sh 'echo "Testing"'
                    sh "cat file.txt"
                }
            }
        }
        
        stage("build"){
            when {
                branch 'main'
            }
            
            steps{
                sh 'echo "Build Started"'
            }
        }

        stage("Deploy"){
            when {
                branch 'main'
            }
            
            steps{
                sh 'echo "Deploying App"'
            }
        }
    }
    
    post{
        success{
            setBuildStatus("Build succeeded", "SUCCESS");
        }

        failure {
            setBuildStatus("Build failed", "FAILURE");
        } 
    }
}

void setBuildStatus(String message, String state) {
    step([
        $class: "GitHubCommitStatusSetter",
        reposSource: [$class: "ManuallyEnteredRepositorySource", url: "https://github.com/vaibhavkumar779/multibranchJenkinsPRbuildStatus"],
        contextSource: [$class: "ManuallyEnteredCommitContextSource", context: "ci/jenkins/build-status"],
        errorHandlers: [[$class: "ChangingBuildStatusErrorHandler", result: "UNSTABLE"]],
        statusResultSource: [$class: "ConditionalStatusResultSource", results: [[$class: "AnyBuildResult", message: message, state: state]]]
    ]);
}

I have used a function setBuildStatus d in the post-build part of the job in Jenkins. We need to add a plugin in Jenkins named Github, you can explore it at https://plugins.jenkins.io/github/

It is written in groovy script, where it calls for a repository as given to it in the URL section. Using the class ManuallyEnteredRepositorySource so we need to provide the URL of our repository in reposSource. In contextSource, we define our context for the build for which we send the status. The errorHandlers, which reports UNSTABLE status in conditions like you have not changed the repository while copying the Jenkinsfile. Last is the actual output we want, in statusResultSource it saves the input given in the post-build job section. The state that we provide is of the fixed type in GitHub understands like success and failure. You can refer to it at https://docs.github.com/rest/reference/commits#commit-statuses

Settings: Github branch rule

Run the build two to three times so Github creates a cache of the status provided by Jenkins.

git status cache
git status cache

When you create a Pull request then you may get output like this below

PR build
PR build
PR build Status
PR build Status

When you click on the link of Details it will take you to the build page of Jenkins.

Build Details
Build Details

Now we move to the repository settings, not the profile settings. This you would have explored while creating the webhook.

Branch Rule
Branch Rule

Now we add a new rule and select the “Require status to pass before merging” option. Below is the search option type the name of the context as seen in the last pull request.

rule selection
rule selection

Now just add the rule and create a pull request. You will that now it is compulsory to have the build status before merging the pull request.

PR build required
PR build required

Conclusion

Now, you can create your own rules. Example pull requests as required to make changes to a branch as compulsory and many more. You can explore it on GitHub documentation itself.

References

Written by 

Explorer of new technologies: from DevOps to Web 3