Introduction to CI/CD and GitHub Actions for JavaScript
Modern JavaScript application development on Node.js requires not only high-quality code but also a reliable process for delivering it to users. CI/CD (Continuous Integration / Continuous Deployment) is a set of practices that automate building, testing, and deploying code. One of the most popular tools for implementing CI/CD is GitHub Actions — a built-in workflow automation system on the GitHub platform.
In this article, we will thoroughly examine how to set up CI/CD for a JavaScript (Node.js) project using GitHub Actions. You will learn how to create pipelines, run tests, perform linting, build the project, and automatically deploy it to a server or cloud hosting. The material will be useful for both beginner developers and experienced engineers looking to optimize the development process.
GitHub Actions Basics: Structure and Syntax
GitHub Actions works based on YAML files stored in the .github/workflows directory of your repository. Each such file defines one or more workflows that are triggered by specific events: push, pull request, release creation, etc.
The basic structure of a workflow includes:
- name — the pipeline name;
- on — the event that triggers execution;
- jobs — a set of tasks that run sequentially or in parallel;
- steps — steps within each job (commands, actions).
Let's look at a minimal example for a Node.js project:
name: Node.js CI
on: push: branches: [ main ] pull_request: branches: [ main ]
jobs: build: runs-on: ubuntu-latest
steps: - uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20' - run: npm ci - run: npm testIn this example, we use built-in actions: actions/checkout for cloning the repository and actions/setup-node for installing the required Node.js version. The npm ci command installs dependencies strictly according to package-lock.json, and npm test runs the tests.
Setting Up Testing and Linting
A high-quality CI/CD pipeline for a JavaScript project should include code compliance checks and automated testing. Let's look at an extended example using popular tools: ESLint for linting, Jest for testing, and Prettier for formatting.
Add the necessary dependencies to the project:
npm install --save-dev eslint jest prettier eslint-config-prettierCreate a configuration file .eslintrc.json:
{ "env": { "node": true, "es2021": true, "jest": true }, "extends": ["eslint:recommended", "prettier"], "parserOptions": { "ecmaVersion": "latest", "sourceType": "module" }, "rules": { "no-console": "warn", "semi": ["error", "always"] }}Now update the workflow file:
name: Lint and Test
on: push: branches: [ main, develop ] pull_request: branches: [ main ]
jobs: quality: runs-on: ubuntu-latest
steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm'
- name: Install dependencies run: npm ci
- name: Run linter run: npx eslint .
- name: Check formatting run: npx prettier --check .
- name: Run tests run: npm test
- name: Upload test coverage