In this post we'll cover GitHub Actions. We'll show you how to use it to automate your deployment workflow and how to use environment variables to save secrets.
We will deploy a simple Nest app using GitHub Actions. We'll start with a simple NestJS app. You don't need to know NestJS to get started, and you can use your own app if you wish. The starting point of the project can be taken from here.
GitHub Actions Environment Variables
We're going to store Docker secrets later in the post using secret variables from GitHub Actions. They can be easily found in the Settings tab and will help you during the automation process.
The Tasks
Like in any production app, we'll create a feature branch from the main branch. After the changes are made, we'll create a pull request to the main branch.
Before merging, you need to ensure that this feature branch will not cause any breaking changes. For each pull request, you want to ensure that the build is successful and that all tests passed.
If you don’t use GitHub Actions, this will require a manual process. Suppose you’re happy with your pull request and want to merge it into the main branch. The next set of tasks is to build Docker image and push it into Docker hub. You can also automate these manual tasks with GitHub Actions.
The Setup
You need to extract the Nest-App from the link provided earlier in your local system and run npm install in it.
After that, create a new repository in GitHub and push your project.
Click on the Actions tab. There you will find a lot of snippets for different projects.
Search for Node and then click on the Configure button of a Node.js project.
Copy all the code from this page, but don't save it. You are going to create it from VS Code in the next step.
Back in your app, you need to create a .github folder and a workflows folder inside it. So inside it, create an integrate.yml file and paste the code from earlier. The .yml file basically says that on push or pull to the main branch, you need to run jobs. The first job name is build, and it runs-on an Ubuntu machine provided by GitHub. It also specifies the node version it will run.
In the steps below, you are using GitHub's Checkout Actions to check out into the build agent's directory. After that, you are setting up Node in that directory.
Lastly, the main command of npm i and npm run build are run.
You will also create the workflow for your tests. Below, you are creating another job called unit-tests and doing the same setup again.
The Failed Run
Now create and push a remote branch that you'll use for your changes.
Back in GitHub, you'll see a compare and pull request button that you need to click.
In the next screen, you just need to write a description and click the Create pull request button.
The next screen says that a new branch got created called new-actions. Click on the Actions tab.
On the Actions page, you can see that your action failed. You need to click on the same to know the exact issue.
The next page shows that there is an issue in unit-tests in the integrate.yml file.
The Successful Run
Upon inspection, it's clear that there is no space in the unit tests. So, we're adding the space and again pushing the changes to new-actions.
Back in GitHub, you can see that a new action has been running.
This time the build completed successfully.
Also notice that the build and unit-tests jobs were run on three versions of Node.js.
Now you can Merge this pull request and will get a confirmation.
The Docker Setup
You'll need to go to https://hub.docker.com/ and register if you don't have an account.
Once you're logged in, click on the Create Repository button.
On the next page, you need to give the app a name and a description. Then click the Create button.
On the next page, you should see the success message. Then click on the user profile in the top-right corner and then click the Account Settings link.
On the next screen, click on the Security tab and then the New Access Token button.
A pop-up will open, and you need to give a description and permissions. After that, click the Generate button.
On the next screen, you will get your username and the token. You'll need to copy those.
Environment Variables in GitHub
You cannot expose the Docker username and password, so you'll save them in GitHub environment variables.
In the GitHub repository, click Settings, Secrets, then Actions. You should see a button for New repository secret, and you'll need to click on it.
On the next page, you will give the new secret a name of DOCKER_PASSWORD. Add the access token from the earlier section. After that, click on the Add secret button.
You'll also create another variable of DOCKER_USERNAME and store the username here.
Now you should see two Repository secrets in the Actions tab.
The Release Flow
Next, you'll create the Docker release flow. Go to the main branch. Then get the updates and create a new branch of release-flow.
Next, create a file release.yml in the workflows folder. Place the code below in it. Here, you're running the job deploy only when merging to the main branch. You just need to check out to the branch. After that, you will be running the Docker build command.
Next, you'll use the username and password to log in to Docker using the secrets stored in GitHub in the previous section.
Lastly, you're running the push command to push to Docker.
The Docker Run
First, you'll add these changes and then commit them to your new release-flow branch. After that, you'll push it to GitHub.
Back in GitHub, you should see a new Compare & pull request on the home page of your app.
Click on it.
On the next page, you need to provide some descriptions and click the Create pull request button.
Since you've created a new branch, the integrate flow, the build, and the unit test jobs should run successfully.
Now you can merge your pull request in the main branch by clicking the Merge pull request button.
You will be asked to confirm this merge on the next page. Just click the Confirm merge button.
Your new actions of release-flow should run now, and you can see it in the Actions tab.
After clicking any of them, you should find that your Docker commands also ran.
After two or three minutes, your workflows should complete successfully.
You can also confirm that the new Docker image was added in Docker hub.
Conclusion
In this post, you pushed a simple Nest app to GitHub. Then you created two automated workflows on GitHub through GitHub Actions.
First, you created an integrate workflow that ran when a pull request was made to main branch from a feature branch. It ran the build and test jobs. Next, you created integrate workflow for your Docker workflow. It ran after a push was made to the main branch. The job created a Docker build and a Docker image in Docker hub.
Did you know you can easily spin up an environment on release directly from your docker-compose file? Give it a shot.
About Release
Release is the simplest way to spin up even the most complicated environments. We specialize in taking your complicated application and data and making reproducible environments on-demand.
Speed up time to production with Release
Get isolated, full-stack environments to test, stage, debug, and experiment with their code freely.