In an enterprise application, development happens round the clock and developers commit their code to multiple repositories. Code gets built on some machines and tests are run on different servers and deployments happen else where. In such distributed environment building CI/CD pipeline is a challenging task.

To achieve continuous integration, we want to automatically build and test the code after each change to our code.

An efficient and configurable method of continuous integration between Git and Jenkins is Git Hooks. Git Hooks allow us to execute scripts based on specific Git actions. In our case, when a developer completes a successful push to the remote Git Server project repository, we want to call Jenkins to build, test, and deploy the modified project code.

When a PR is raised, a PR build job is triggered and runs all required tests and update the status checks to make it merge-able.
After merging the code another Jenkins job is triggered which is subscribed and build from the merged branch, run tests and upload the artifacts to a location from where the build is downloaded and deployed

On successful build from the merged branch, create an deployment event on Git for which there is webhook registered to trigger deployment job. You can create deployment event as below.

POST /repos/:owner/:repo/deployments
{
“ref”: “release-branch”,
“payload”: “{\”build_number\”:\”b123\”,\”room_id\”:123456}”,
“description”: “release build”
“environment”: “development”
}

There exists a Jenkins job which is registered as webhook and subscribes to deployment events picks the job and deploys the build on the environment mentioned in the deployment event.

After the deployment is successful, post a deployment status event on the above deployment event and trigger automation tests. There could be various test jobs you might be running based on your build sign off criteria to mark the build as stable. You can create a deployment event as below.

POST /repos/:owner/:repo/deployments/:id/statuses
{
“state”: “success”,
“target_url”: “https://example.com/deployment/1/output”,
“description”: “deployed successfully on development”
}

Every test job that is triggered will post a deployment status event to the statuses URL with the status of the tests run, which is supplied to the test job as a parameter.

A Jenkins job that is registered as webhook on Git to listen for deployment status events, will process all the deployment status events and if all the deployment status events are successful, then it triggers another job to promote the build to another environment where you want your build to be deployed like staging/production.

References

https://developer.github.com/v3/repos/deployments
https://help.github.com/enterprise/2.10/user/articles/defining-the-mergeability-of-pull-requests/