Merging the feature branch updates in the master branch and automatic deployment in Production Server using DevOps.

Juzer Patanwala
5 min readMay 26, 2021

In this world of automation,we need rapid,fast and agile deployment.As soon as the developer comes up with new updates,it should be instantly tested and then deployed in the production environment.We will be solving this use-case in this article.

Use-Case

There is a project on which multiple developers are working.The multiple versions of the code are maintained using the VCS “Git”.A developer comes up with an updated code and pushes it to the feature branch.We need to instantly test this updated code in the Testing Environment and then deploy it in the Production Environment.We are going to fulfill this requirement using GitHub,Jenkins and Docker.

In our GitHub repository,there will be 2 branches :

  • Master Branch : This will deploy the code in the final production server.
  • Feature Branch dev1 : This code will be deployed in the testing environment.

Pre-Requisites

  1. Jenkins is required for creating the Pipeline.
  2. The plugin named Pipeline should be installed in Jenkins
  3. Docker is required for launching the testing and production containers.
  4. GitHub Repository with a master branch and feature branch.

Solution

We will automate the entire infrastructure using a single Jenkins Pipeline consisting of 3 stages.

Create a new job with Pipeline as the type of item.

After creating the job,in the Advanced Project Options section we will write the Pipeline script.

pipeline{
agent any
stages {
#We will write the code for different Stages next }
}

Start — This flow starts when a developer pushes the code in dev1 branch.The commit to dev1 branch will trigger the 1st stage of the pipeline

Stage 1

1.1 Fetch the code from the dev1 branch.

stage('Test'){
steps{
git branch: 'dev1', url: 'https://github.com/juzer-patan/jenkinspipelineautomation.git'

#We will add the next steps of the stage here
}

1.2 Add the Poll SCM property to monitor the dev1 branch on GitHub.You can also use any other functionality like "Trigger builds remotely" with webhooks.

     #Add this as the next step after git 
script{
properties([pipelineTriggers([pollSCM('* * * * *')])])
}

1.3 Deploy the feature branch code inside Testing Environment Docker container.

#Entire code for the 1st stage
stage('Test'){
steps{
git branch: 'dev1', url: 'https://github.com/juzer-patan/jenkinspipelineautomation.git'
script{
properties([pipelineTriggers([pollSCM('* * * * *')])])
}

sh '''sudo cp -rf * /testing
if docker ps -a | grep demo-test
then
echo \'Already Running\'
else
sudo docker run -dit -v /testing:/usr/local/apache2/htdocs/ -p 8082:80 --name demo-test httpd
fi
'''


}
}

Stage 2

In this stage we will require the GitHub credentials.Go to the Manage Credentials portal.

Then,click on Add Credentials to store your GitHub Credentials inside Jenkins Store.

2.1 Here,we will test the Testing Environment container deployed earlier using curl and if it is working properly then we will merge the dev1 branch with the master branch using the git merge command.This will just merge the local dev1 and master branches,so we will have to push the local master branch to the remote master branch using the git push command.

The git push command requires our GitHub credentials.We can pass our credentials in the Jenkins Pipeline using the withCredentials( ) function as follows :

withCredentials([ usernamePassword( credentialsId: 'YOUR_CREDENTIAL_ID', passwordVariable: 'GIT_PASSWORD', usernameVariable: 'GIT_USERNAME')]) {

#Here we will use the git push command
}

The code for Stage 2 is as follows :

stage('Merge'){
steps{
script{

withCredentials([ usernamePassword(credentialsId: 'YOUR_CREDENTIAL_ID', passwordVariable: 'GIT_PASSWORD', usernameVariable: 'GIT_USERNAME')]) {

sh('''
if curl 192.168.1.3:8082
then
git checkout master
git branch --set-upstream-to=origin/master
git merge dev1
git push https://${GIT_USERNAME}:${GIT_PASSWORD}@github.com/juzer-patan/jenkinspipelineautomation.git master
fi
''')
}
}
}

}

Stage 3

The Stage 3 will run only if the stage 1 and 2 gets executed successfully

3.1 Fetch the code from the master branch and add the Poll SCM property like we did for the first stage

stage('Prod'){
steps{
git 'https://github.com/juzer-patan/jenkinspipelineautomation.git'
script{
properties([pipelineTriggers([pollSCM('* * * * *')])])
}

3.2 Here,we will copy the code from the master branch and then deploy it inside the Production Environment container.

                sh '''sudo cp -rf  * /prod
if docker ps -a | grep production
then
echo \'Already Running\'
else
sudo docker run -dit -v /prod:/usr/local/apache2/htdocs/ -p 8084:80 --name production httpd
fi
'''

The entire pipeline code for your reference

pipeline{
agent any
stages{
stage('Test'){
steps{
git branch: 'dev1', url: 'https://github.com/juzer-patan/jenkinspipelineautomation.git'
script{
properties([pipelineTriggers([pollSCM('* * * * *')])])
}
sh '''sudo cp -rf * /demo
if docker ps -a | grep demo-test
then
echo \'Already Running\'
else
sudo docker run -dit -v /demo:/usr/local/apache2/htdocs/ -p 8082:80 --name demo-test httpd
fi
'''

}
}

stage('Merge'){
steps{
script{


withCredentials([usernamePassword(credentialsId: 'YOUR_CREDENTOAL_ID', passwordVariable: 'GIT_PASSWORD', usernameVariable: 'GIT_USERNAME')]) {
sh('''if curl 192.168.1.3:8082
then
git checkout master
git branch --set-upstream-to=origin/master
git merge dev1
git push https://${GIT_USERNAME}:${GIT_PASSWORD}@github.com/juzer-patan/jenkinspipelineautomation.git master
fi
''')
}
}
}

}
stage('Prod'){
steps{
git 'https://github.com/juzer-patan/jenkinspipelineautomation.git'
script{
properties([pipelineTriggers([pollSCM('* * * * *')])])
}
sh '''sudo cp -rf * /prod
if curl 192.168.1.3:8082
then
echo \'Working Fine\'
if docker ps -a | grep production
then
echo \'Already Running\'
else
sudo docker run -dit -v /prod:/usr/local/apache2/htdocs/ -p 8084:80 --name production httpd
fi
fi
'''
}
}

}
}

FINAL EXECUTION

Let’s check how our automation works

This is the content of the production server before execution

Now I will commit and push the code to the dev1 branch.

The Jenkins Job is automatically triggered

The dev1 branch is merged with the master branch

The production server is updated with the latest code

Finally,we have successfully automated the process of deploying the code from feature branch to the testing environment and finally the production environment.

Thank You!!

--

--

Juzer Patanwala

Cloud Engineer @ Searce Inc || Technical Content Writer || Technology and Automation Enthusiast