What is CI/CD?
Nowadays, the concept of the CI/CD is everywhere. CI stands for continuous integration and the CD stands for Continuous Deployment. CI/CD is the backbone of the DevOps environment. It helps organisations to speed up the release of small features in new software, and implement the feedback and changes quickly.
Gogs is a free and open source Git service written in Go language. painless self hosted Git service. You can install and configure Gogs on your own servers. It supports all platforms including Linux, Mac and Windows. For more about Gogs, check their official document https://gogs.io/docs
Jenkins is a self-contained open source automation platform which can be used to automate all kinds of software development, testing, and distribution, or deployment tasks.
In this tutorial, I will show you how to create a simple CI/CD Pipeline using Jenkins and Gogs In this scenario, we have hosted a django application on the linux server. As of now we are doing the following process if any changes needed for the application. Developer pulls the live code from the Gogs repository and pushes back to the repo after modifying the code. Then the SystemAdministrator will pull the latest code from the Gogs repo to the application server.
We can automate the above processes with the help of CI/CD.
1. Developer push/merge code into a branch in the repo.
2. Admin get a notification message in slack about the push
3. Gogs trigger the Jenkins job for the new build and initiate the build if the conditions satisfy that specified in the Jenkins.
4. Admin get a notification message after the build.
5. Once the build is completed, the jenkins will trigger the code deployment into the application server.
6. Finally the application server will pull the latest code from the Gogs repo and send a notificatification message to slack.
Requirements:
SSH access to Jenkins server.
Gogs admin access.
SSH access to the application server.
1. Install plugins on Jenkins.
Required plugins:
Git
Gogs
Login to your Jenkins web interface.
Go to Plugins Manage
Search required plugins from there and click on “ Download now and install after restart”
2. Configure webhook
We need a hook to trigger from Gogs to Jenkins job. I’m using a post-receive hook in the repository to poke Jenkins jobs when a new push occurs. In Gogs repo there is a Git Hook option to configure post-receive hook. This hook will help you to minimize the delay between a push and a build. CI/CD Pipeline using Jenkins and Gogs will do this, go to your Gogs repo >> Settings >> Git Hooks >> Post Receive Then add the following line in your hooks. curl http://yourjenkinsserver/git/notifyCommit?url=<URL of the Gogs repo>
3. Configure access to Gogs from Jenkins.
SSH
Login to your jenkins server through ssh and generate a ssh key.
The ssh private and public key will be generated in /var/jenkins_home/.ssh/ Copy that public key from there.
Login to your Gogs and go to your Repository Settings > Deploy keys Add previously copied public key here
Add this private key in Jenkins credentials.
Login to your jenkins server and go to:
Jenkins >> Credentials >> System >> Global credentials
Then select “SSH username with private key” from the Drop down menu. Enter Gogs ssh username and paste previously created private key there.
Username and password
You can also configure this with your Gogs username and password.
Go to Jenkins >> Credentials >> System >> Global credentials
Enter your Gogs user username and password there.
4. Configure SSH access to application server from jenkins.
In this example I have a user called jenkins in the application server.
Login to your Jenkins server through SSH.
Copy previously created key to the application server
Now configure this ssh details in jenkins.
Install “Publish over SSH” plugin
Go to Jenkins > Manage Jenkins > Configure System > Publish Over SSH
If you get any error as shown in the below screenshot, create ssh key with following options in the 3rd step.
5. Configure Jenkins job
Login to your Jenkins dashboard.
Go to Jenkins > New Item.
Enter your project name and select “Free style project”
In this job, we are executing a bash script to deploy the code into the application server. So we need string parameters to pass into the bash script as a argument.
So select the option “This project is parameterised” under Gogs webhook
Then add the parameter “ GIT_FOLDER”
Specify the directory name in the application server to which git pull happens for code deployment.
In my case the directory is /home/jenkins/cicd-dev
Add next parameter is “GIT_CHECKOUT_DIR”
Specify the directory name in the application server to which will deploy the code.
Next parameter is “SERVER_ENV”
Next parameter is “VENV”
Specify your python virtual environment path in the application server.
Then add the parameter “DEPLOY_SCRIPT”
This variable stores the path of the deploy script.
hsgfhsg
I will show you the content of the script at the end of the tutorial.
Now add the Gogs repo URL and credentials in the “Source Code Management” You can select previously added credentials from there.
Finally go to the “Post-build Action” in the Jenkins job.
Select “Send build Artifacts over SSH” and paste the following command in the “Exec command box”
If the conditions satisfy, jenkins will pull files from the gogs repo and execute the deploy script with the above mentioned arguments.
Here is the deploy script written in the bash script.
###Beginning##
#!/bin/bash
#Deployment script used by Jenkins
#Author: Hans Emmanuel
GIT_FOLDER=$1
GIT_BRANCH=$2
GIT_CHECKOUT_DIR=$3
GIT_URL=$4
SERVER_ENV=$5
VENV=$6
PIP_INS=false
DEPLOYED=false
SLACK_URL= <specify your slak url if you are using slack>
cd $GIT_FOLDER
git fetch
if (git cat-file -e $GIT_BRANCH:DEPLOY)
then
echo “deploying the code”
BRANCH=$(echo ${GIT_BRANCH} | cut -d’/’ -f2)
if ! (git diff –exit-code –name-only $GIT_BRANCH — requirements.txt)
then
PIP_INS=true
fi
git pull && GIT_WORK_TREE=$GIT_CHECKOUT_DIR git checkout $BRANCH -f && DEPLOYED=true && echo “CODE Deployed”
cd $GIT_CHECKOUT_DIR
if $PIP_INS
then
cd $GIT_CHECKOUT_DIR
echo “Installing requirements”
source $VENV/bin/activate
pip install -r requirements.txt
fi
touch $GIT_CHECKOUT_DIR/uwsgi.ini
url=$GIT_URL
REPO=$(basename $url)
if $DEPLOYED
then
curl -X POST –data “payload={\”text\”: \”:slack: Jenkins Repo $REPO branch ${GIT_BRANCH} Deployment is SUCCESS on ${SERVER_ENV} server\”}” $SLACK_URL
else
curl -X POST –data “payload={\”text\”: \”:slack: Jenkins Repo *$REPO* branch *${GIT_BRANCH}* Deployment is *FAILED* on *${SERVER_ENV}* server\”}” $SLACK_URL
fi
else echo “NOT Deploying Code”
fi
###End of the Script###