Ever since taking control of Github in its hands, Microsoft has been making regularly making it more attractive. Github Actions is one of the noteworthy features rolled out after Microsoft’s acquisition of GitHub. In this article, we are going to understand what a Github Action is and then try to make a pipeline for Continuous Deployment using Github Actions. Thanks to my colleague and a well deserving GSOCER Prem Saraswat, for introducing me to Github actions.
Let us try to understand what a Github Action is. Github action is a way to automate things. Now since it is a technical blog and we are talking about
Github , by
things we mean any tasks or set of tasks that revolves around your code. Suppose you have written some test cases for your code. Now, what happens when you add some new features to your codebase?? You have to write new test cases to maintain the sanity of your Project. This is one thing that can be automated with Github Actions. Suppose you have to build a docker image containing the build of your code and push it AWS ECS. This again is something that can be automated using Github Actions.
Building a project, CI/CD, tests, reviews are a few of the things that can be achieved using Github Actions. Github provides you with a staging machine (a VM) where your actions are executed and the results are given back to you. As stated already, in this article we will try to build a pipeline for Continuous Deployment using Github Actions.
First, let us try to understand what Continuous Deployment is.
Suppose you are building a react project. Every time push a commit to the master branch (the main release branch) you have to take a pull on your server (or your docker), pull in the dependency changes (npm/yarn), build it and then run the project, and only then you are able to see your changes live.
Continuous Deployment is nothing but a fancy name of automating all this stuff. Continuous Deployment. It makes it very easy for a team to push their changes to the production server, and the automation also does not allow any human errors. The dev just pushes a commit on the master branch or merges a pull request on it, and the action takes over from there, building the code, extracting the executables and deploying it.
Deployment can be made both ways, using a docker container and pushing that to ECS, or by simply cloning the code in the required directory of the server and then restarting the server. In this post, we will be directly cloning the project into a predefined directory in the server.
Building the Action
To build the action, first of all, you need to have a repository on Github. As we are working with a nodeJS project in this article, it is assumed that you have a nodeJS repo in your Github account.
Now let us see step by step, how will we want the pipeline to look like.
- Get the ssh key.
- SSH into the server.
- Browse to the desired location.
- Pull or rsync the repository.
- Install the dependencies (npm install).
- Restart the apache/nginx/pm2 server.
The very first requirement is the SSH key. Since we are connecting to a remote machine, we do need to have a way of authorization on that server. SSH key serves that purpose. You can use your own private key, (the key that you use to ssh into the server) or create a new pair of public/private key using ssh-keygen.
Go to your repository -> settings -> secrets and create a new secret . Give your secret a name, this name shall be used to reference the secret later, so make sure you name it something you can remember. In the value, tab paste your private key in the PEM format. (with the —-BEGIN RSA—— header)
Next, click on the Actions tab, and now you will see a variety of actions that Github suggests you. You can anytime choose one of them, however keeping this post under consideration, we click on set up a flow yourself.
What we now see is a blank YAML file. YAML is nothing but yet another human-friendly data serialization standard. The purpose it serves here is that we define the flow of our pipeline here. It is in this file that we write what tasks have to be executed and in what order they are to be executed. Let us look at the attributes it has :
- Name: Name of the pipeline
- ON: Trigger for the action to begin
- JOBS: The series of steps to be taken
- RUNS ON: The virtual machine on which your action should run.
- STEPS: The steps that each action has to take.
There are many many other fields and place holders which you can read here.
Now, let us see populate our YAML file.
We trigger our action on a new commit on master. We build our action latest ubuntu distro. Let us come to the steps.
Step 1. Checkout
Our code is pulled on a virtual machine (not the server, but a temporary virtual machine) with Ubuntu distro (we chose that in the runs-on field).
Step 2. Configuring the Key
We saved our key in Github Secrets, in this step, we copy that key in a file named
ECD on the temporary virtual machine, and give it the necessary permissions.
Step 3. Push the code from temporary VM to the server via SSH
In this step, we run the rsync command (a command used to bring two remote directories in sync) to bring the directory on VM where code was checked out in sync with the desired directory on the server. The connection is established using SSH. In short, this step pushed the new code on to the desired directory of the server.
Step 4. SSH into the remote server (from the temporary VM) and deploy the code.
In this step, we ssh into the remote server, cd into the desired repository, npm install the dependencies and restart the server.