(This Blog post is part of a collaborative work between Me and Mustapha El Idrissi, Consult his devTo page for more information: https://dev.to/appsbymuss)
What is CI/CD
CI/CD, or Continuous Integration and Continuous Delivery/Deployment, is a set of practices and tools that automates the process of software development, testing, and release. It helps developers deliver code changes more frequently, safely, and reliably.
Continuous Integration: This is a development practice where developers frequently integrate their code changes into a shared repository.
Continuous Delivery: This goes one step further by automating the entire release process. Once code passes all testing stages, it is automatically deployed to the production environment.
There are lot of tools that are used to perform CI and CD such as and not limited to:
- Jenkins
- GitHub Actions
- GitLab CI/CD
- Travis CI
However these tools are usually followed by resource use restrictions or require monetary contributions to be used efficiently and at the same time beginners struggle to use such tools at the start of their Software Development career.
- There is however an easier-to-bootstrap and harder-to-efficiently-setup way to achieve CI/CD which is "GitHub Webhooks"
How to setup GitHub Webhook ?
Step 0: Create a repo
- Ofcourse when we have a new project we have to create a new repository for it to store our code changes (aka commits), but in this case it will also be useful to achieve our CI/CD goal.
Step 1: Create a route for the POST-webhook
- Assuming that you already have a server with your desired runtime environment/Framework up and running on a specific port.
- You're gonna have to also make a webhook in order to let Github have a way to reach your server in the case of new change to the main/production branch on your github repo like so:
require('dotenv').config();
const express = require('express');
const crypto = require('crypto');
const bodyParser = require('body-parser');
const { exec } = require('child_process');
const app = express();
const updatedAt = new Date();
function verifySignature(req, res, buf, encoding) {
const signature = req.headers['x-hub-signature-256']; // GitHub sends the signature here
if (!signature) {
console.log('No signature found on request');
return false;
}
const hmac = crypto.createHmac('sha256', process.env.REPO_WEBHOOK_SECRET);
const digest = 'sha256=' + hmac.update(buf).digest('hex');
if (signature !== digest) {
console.log('Signature does not match');
return false;
}
console.log('Signature is valid');
return true;
}
app.use(bodyParser.json());
app.post('/cicd/github-cicd', (req, res) => {
const buf = JSON.stringify(req.body); // The raw body of the request
// const isValid = verifySignature(req, res, buf);
/* if (!isValid) {
return res.status(401).send('Invalid signature');
}*/
const { ref } = req.body;
if (ref === 'refs/heads/main') {
// PM2 is my instance manager
exec('git pull origin main && pm2 restart cicd_app');
}
res.sendStatus(200);
});
app.get('/cicd/time', (req, res) => {
res.send(`<h1>${updatedAt}</h1>`);
});
app.listen(80, () => {
console.log("Listening on Port 80...");
});
Step 2: Configure the repo's settings
Then we get to the webhook creation panel
[warn] Depending on the SSL state of your website (if it's activated or not), choose the "SSL Verification" option accordingly.
[warn] Incase you want Github to include a "secret" token to authenticate itself to your server to ensure it's Github and not a threat actor, then put a secret word, otherwise leave empty.
Step 3: Ready !
- After Setting up your webhook on your webserver and github webhook of your repo, then you're basically good to go.
Macro
- First a developer will push their commit (code changes) to GitHub.
- Secondly GitHub will send a POST Request to our server, and specifically to our webhook route with the body in JSON with information related to that github push that we've done just a moment ago.
- Thirdly The server will then ofcourse treat said request as a way to know that there are changes on the production branch that must be applied as soon as possible, therefor a git pull will be attempted and then tests and new builds and whatnot are going to be executed.
- Finally The server will consequently restart with the updated source code.
Top comments (1)
This is a very good post.