Setting Up GitHub Actions for Node.js Projects
Today, the process of application development is heavily automation-oriented by default. Activities such as testing, code deployment, and even enforcing some quality standards of the code entail a number of tedious activities that are time-consuming and carry a high risk of errors. This article will guide you through the process of GitHub Actions setup and configuration for Node.js projects.
Discover how at OpenReplay.com.
GitHub Actions are open-source automation tools built into GitHub. They enable developers to perform their project activities by designing workflows. These workflows may be employed to perform functions such as testing code, building applications, or deploying software. With the help of YAML encoded files, one can outline several steps executed whenever certain declared actions occur in your repository, such as pushing or requesting code changes. The important elements, detailed processes, and recommendations to apply good Continuous Integration and Continuous Deployment CI/CD structures will all be discussed below. Let’s start with the diagram below, which explains the operations of GitHub Actions.
Image source: YouTube
The image above gives a holistic representation of the functioning of GitHub Actions. Events happen, which then start the workflows of one or more jobs. This job is divided into several steps, each performing certain actions. The whole process is described in a YAML file. Hence, it becomes quite convenient to set up any automation processes within your GitHub repository without much hustle.
Setting up GitHub Actions for Node.js
To start with GitHub Actions, you’ll need an added workflow file stored in the repository. This file employs the yaml
format and is usually located in the .github/workflows folder. The basic format includes:
name: Node.js CI
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '14' # Specify the Node.js version you want to use
# Add more steps here...
In this snippet, a workflow Node.js CI
is constructed, which is initiated on push and pull request events to the main branch. This constituent contains a single job called build
, which is executed on the latest available version of Ubuntu. The job consists of two steps; the first uses the actions/checkout
action to check out the repository’s code, while the second, which uses the actions/setup-node
action, installs node js v14
. This workflow is the groundwork for the upcoming tasks, such as executing tests or compiling the application.
Nodejs-Specific Configurations
In the workflow file, you can include steps that usually relate to Node.js projects. This generally covers performing tests, code linting, and building the application for release. For instance:
- name: Install dependencies
run: npm install
- name: Run tests
run: npm test
These steps guarantee that the application is constructed properly and that all the tests have been passed before any modifications are integrated.
In the workflow file, you will define which version of Node.js to use. This is done in the setup-node
stage, where you may use any Long Term Support LTS or a particular version.
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '14' # Use the desired Node.js version
This ensures that the required version is in place for running the application and performing the tasks in the next steps. You can also use version ranges or specify multiple versions if needed.
After you have completed the setup of the Node.js environment, the next thing you would do is install the project dependencies which in most cases you do using the below command:
- name: Install dependencies
run: npm install
This stage makes certain that every necessary package is accessible for the smooth functioning of your application.
Environment Variables
One option for setting environment variables is the GitHub Secrets feature, which allows the user to efficiently hide sensitive information like API keys or database connection information.
Assigning an environment variable by appending a written step in the process, which places the required variable into the $GITHUB_ENV
file is possible. For example:
- name: Set up environment variables
run: echo "MY_VARIABLE=${{ secrets.MY_VARIABLE }}" >> $GITHUB_ENV
Here, MY_VARIABLE
is assigned the secret MY_VARIABLE
and can thus be used in the following steps of the workflow. This way, sensitive information is not written to the logs, and your application can get the right configuration during runtime.
Automating Tasks
To facilitate testing within your Node.js project, you can include the stage in your GitHub Actions workflow, where you can run tests using Jest. Here’s how you can achieve the above:
- name: Run tests
run: npm test
If you would like to execute Jest with some selected options, you may consider including:
- name: Run Jest tests
run: npm run test -- --coverage
This guarantees that your tests run any time alterations are made or a pull request is initiated, thus helping to identify problems with the system in the early stages.
As soon as you decide to make your application available to the public, you can start implementing automation in the building and deploying processes. After you run your tests, you can append the steps to construct your application. For example:
- name: Build application
run: npm run build
The code above will run the command npm run build
, which in turn processes the application and gets it ready for production deployment by executing the build definition within the package.json
file of the project.
You can run the command corresponding to your deployment approach for deployment. For example, if you are using a service like Heroku or AWS, the command may resemble the following:
- name: Deploy to Production
run: npm run deploy # Adjust this command as necessary for your setup
This command runs npm run deploy
, which executes the deploy script from package.json
for the application’s production deployment.
Ensure that the deployment command you are using is tailored to accommodate the particulars of your environment.
Now, to uphold the quality of the code, it is possible to automate the process of checking for linting and also for formatting as part of the work process. In case ESLint and Prettier are being used, include the steps given below:
- name: Lint code
run: npx eslint .
- name: Format code
run: npx prettier --check .
These procedures will verify the presence of any linting issues and ensure that the code formatting is uniform throughout your project. Feel free to modify the commands according to your project’s settings.
Common GitHub Actions for Node.js
One of the most important aspects of Continuous Integration (CI) is the automation testing and validation of code changes. The following are some of the common CI actions for Node.js projects:
- Testing and Validation: To keep up the quality of the code, automating the testing process is very important. You can create a workflow where every time code is pushed, or a pull request is made, tests are run. Here is an instance of how to do this in your workflow:
- name: Run tests
run: npm test
This step executes the entire test suite to check that every test passes. In case any test fails, the workflow will be considered a failure to prevent any broken code from being merged.
- Code Coverage Analysis: To assess the proportion of your code that has been tested, you may incorporate code coverage solutions such as Istanbul or Coveralls. Once your tests have been executed, it is possible to apply a coverage command and display the outcomes:
- name: Run coverage report
run: npm run coverage
The code above executes the coverage script specified in the project’s package.json file. This script creates a code coverage report that shows the extent to which the existing test cases have exercised the code.
Continuous Deployment (CD)
Continuous Deployment (CD) automates every step that takes your application to production. Here are a few of the popular approaches to deploying a Node.js Application:
- Deploying to Cloud Platforms (with AWS): If you are deploying on the AWS cloud, some of the services you can choose from would include Elastic Beanstalk or Lambda. Below is a straightforward representation of how to deploy on Elastic Beanstalk using GitHub Actions:
- name: Deploy to AWS Elastic Beanstalk
uses: einaregilsson/beanstalk-deploy@v1
with:
application_name: your-app-name
environment_name: your-env-name
version_label: ${{ github.sha }}
region: your-region
bucket_name: your-bucket-name
bucket_key: your-bucket-key
access_key: ${{ secrets.AWS_ACCESS_KEY }}
secret_key: ${{ secrets.AWS_SECRET_KEY }}
Here, the code uses the einaregilsson/beanstalk-deploy
action to deploy an application on AWS Elastic Beanstalk. It indicates the application name, environment name, and version label (which is always set as the current Git commit SHA), along with the applicable AWS region, S3 bucket name, and the key of the bucket to use for the deployment artifacts. The keys for access and secret are pulled from the GitHub secrets tab, hence facilitating the safe incorporation of the credentials for the deployment process.
For safety concerns, please ensure that you add your AWS credentials to the repository secrets.
- Deploying to Serverless Environments: For deployments without backend servers, you may want to consider services such as AWS Lambda or Vercel. This is an example of deploying to AWS Lambda:
- name: Deploy to AWS Lambda
run: |
npm install -g serverless
serverless deploy
Here, the Serverless Framework is installed globally with the command npm install -g serverless
. Afterward, the command serverless deploy
is called, and it deploys the application to AWS Lambda as per the specifications of the Serverless Framework installed in the system, thus allowing comfortable handling of serverless functions and resources.
Be sure there is a serverless.yml
configuration file in your project to specify your Lambda functions and their properties.
Advanced GitHub Actions Features
Aside from the primary functions of GitHub Actions, other advanced features can add value to your workflows. Such features help to improve the efficiency, flexibility, and security of your CI/CD processes. Below are two essential advanced features:
Caching Dependencies
Dependency caching can help reduce the time spent waiting for the builds to complete by saving the dependencies of the project between the builds. This is especially the case for Node.js projects where npm install
is quite costly in time. With dependency caching, there is no need to re-install the dependencies for each and every run.
Here’s how to set up caching in your workflow:
- name: Cache Node.js modules
uses: actions/cache@v2
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
This setup caches the node_modules
directory using the dependency information of the package-lock.json
file. When the latter has not been altered, subsequent executions will reinstate the cached dependencies, leading to a remarkable decrease in the time taken to install the dependencies.
Parallelizing Tasks
Task parallelization helps in executing a command in more than one job at a single time which can significantly reduce the total execution time for your processes. This comes in handy especially when the project is bigger because you might want to run some tests and some linting and builds at the same time.
You can specify multiple jobs in your workflow that function concurrently as follows:
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Run tests
run: npm test
lint:
runs-on: ubuntu-latest
steps:
- name: Lint code
run: npx eslint .
Here, the jobs test
and lint
are executed at the same time, so problems can be found and resolved much faster.
Conclusion
No doubt, using GitHub Actions for your Node.js projects improves your development workflow remarkably. It is possible to conduct thorough testing, deployment, and code quality checks on applications without compromising their reliability or fixability. Pushing this agenda further saves time and encourages teamwork in organizations. As you thread your way through GitHub Actions, it becomes apparent that these instruments contribute to cleaner code and better project management.