In this example, we are going to let GitHub trigger Jenkins pipeline build only when we merge code to a develop branch in GitHub repository. This action often occurs when a "feature/hotfix/release" branch is merged into "develop". That's all!


Prerequisites


Apply steps defined under "Jenkins server GitHub SSH integration" and "Allow Jenkins user to execute docker commands" sections in Integrating Jenkins with GitHub to run dockerised application pipeline page.


Ngrok setup


Download ngrok to your host OS's desktop and run $ ./ngrok http -host-header=rewrite 192.168.99.40:8080 in terminal. The http://192.168.99.40:8080 is your Jenkins GUI address. This will give you an URL that can be accessible from the Internet. We will use this to integrate with GitHub later on. Assume that it gave us http://fdb1ce55.ngrok.io as URL.


GitHub Integration Plugin


Find and install "GitHub Integration Plugin" plugin in Jenkins "Manage Plugins" page.


GitHub webhook URL


Do the following in Jenkins GUI.


  1. Go to "Configure System" page.

  2. Click "Advanced" button under "GitHub" section.

  3. Tick "Specify another hook url for GitHub configuration" tickbox, note URL http://192.168.99.40:8080/github-webhook/ somewhere and untick it again.

  4. Exit from page without saving.

Prepare Github repository


Go to GitHub repository on https://github.com/inanzzz/game and do the following.


  1. Go to "Settings" and then "Webhooks" page.

  2. Paste http://fdb1ce55.ngrok.io/github-webhook/ to "Payload URL" box. As you can see we are not using the local IP address.

  3. Under "Which events would you like to trigger this webhook?" section select "Let me select individual events." then tick "Pull requests" option.

  4. Click "Add webhook" button.

If you echo Jenkins logs at /var/log/jenkins/jenkins.log file, you should see line below at the bottom.


Feb 16, 2019 5:59:32 PM org.jenkinsci.plugins.github.webhook.subscriber.PingGHEventSubscriber onEvent
INFO: PING webhook received from repo !

Also, if you check the details of the webhook in GitHub page, you will see the communication information between GitHub and Jenkins. It can be found under "Recent Deliveries" section of the added webhook.


Create Jenkins project


Go to Jenkins and do the following to add a new project.


  1. Name the project as "game-pr-merger", select "Pipeline" and save it.

  2. Under "General" tab, tick "GitHub project" option and paste https://github.com/inanzzz/game into the box.

  3. Under "Build Triggers" tab, tick "GitHub hook trigger for GITScm polling" option.

  4. Select "Pipeline script from SCM" option under "Pipeline" section.

  5. Select "Git" as SCM.

  6. Use https://github.com/inanzzz/game for "Repository URL".

  7. Select GitHub-inanzzz from "Credentials".

  8. Change */master to develop because we only want "develop" branch to build for git merge actions.

  9. Add ci/pipeline/branch/develop/Jenkinsfile to "Script path".

  10. Save and exit.

Test with git merge event


Create a PR in GutHub repository and merge it by clicking "Merge pull request" button.



Your Jenkins log should print lines below.


Feb 16, 2019 9:22:47 PM org.jenkinsci.plugins.github.webhook.subscriber.DefaultPushGHEventSubscriber onEvent
INFO: Received PushEvent for https://github.com/inanzzz/game from 192.30.252.37 ⇒ http://192.168.99.40:8080/github-webhook/
Feb 16, 2019 9:22:47 PM org.jenkinsci.plugins.github.webhook.subscriber.DefaultPushGHEventSubscriber$1 run
INFO: Poked game-pr-merger
Feb 16, 2019 9:22:49 PM com.cloudbees.jenkins.GitHubPushTrigger$1 run
INFO: SCM changes detected in game-pr-merger. Triggering #2
Feb 16, 2019 9:23:12 PM org.jenkinsci.plugins.workflow.job.WorkflowRun finish
INFO: game-pr-merger #15 completed: SUCCESS

Files


ci/pipeline/branch/develop/Jenkinsfile


pipeline {
agent any

options {
skipDefaultCheckout(true)
}

stages {
stage('Checkout SCM') {
steps {
echo '> Checking out the source control ...'
checkout scm
}
}
stage('Docker Up') {
steps {
echo '> Building the docker containers ...'
sh 'make -sC docker/ci/ build'
}
}
stage('Composer Install') {
steps {
echo '> Building the application within the container ...'
sh 'make -sC docker/ci/ composer'
}
}
stage('Test') {
steps {
echo '> Running the application tests ...'
sh 'make -sC docker/ci/ test'
}
}
stage('Cleanup') {
steps {
echo '> Cleaning the docker artifacts ...'
sh 'make -sC docker/ci/ clean'
}
}
stage('Docker Image Build') {
steps {
echo '> Building the docker image ...'
}
}
stage('Docker Image Push') {
steps {
echo '> Pushing the docker image ...'
}
}
stage('Deploy') {
steps {
echo '> Deploying the application to staging ...'
}
}
}
}

docker/ci/Makefile


PHP_SERVICE := game_php

build:
@docker-compose up -d

composer:
@docker-compose exec -T $(PHP_SERVICE) composer install

test:
@docker-compose exec -T $(PHP_SERVICE) vendor/bin/php-cs-fixer fix src --rules=@PSR2 --using-cache=no --dry-run --verbose --diff
@docker-compose exec -T $(PHP_SERVICE) vendor/bin/phpunit tests
@docker-compose exec -T $(PHP_SERVICE) vendor/bin/phpstan analyse src tests --no-progress --level=max

clean:
@docker-compose down --volumes
@docker system prune --volumes --force