Node.js test & build pipeline — every CI platform
Node.js test & build pipeline — every CI platform
Almost every Node.js project has the same baseline pipeline: install dependencies, lint, run unit tests across two or three Node versions, and surface JUnit-format test reports back into the CI UI. Here is that pipeline implemented identically (semantically) on each of the four major CI platforms.
Four things change between the implementations: the YAML keys themselves, where caching is declared, how the version matrix is expressed, and how test reports surface in the UI.
Conversion notes
- •GitHub Actions and CircleCI declare the matrix at the top of the job; GitLab uses parallel:matrix; Bitbucket has no native matrix and the same pipeline is repeated as parallel steps.
- •Caching is a step on GitHub Actions, a job-level block on GitLab, an explicit pair of restore_cache/save_cache on CircleCI, and a step-level caches: list on Bitbucket.
- •Test reports surface natively only on GitLab (artifacts.reports.junit) and Bitbucket (test-reports/ folder). On GitHub and CircleCI you upload the file as an artifact and consume it via dashboards.
Side-by-side implementation
name: Test
on:
push:
pull_request:
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node: [18, 20, 22]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: npm
- run: npm ci
- run: npm run lint
- run: npm test -- --reporter=junit --reporter-options output=report.xml
- uses: actions/upload-artifact@v4
if: always()
with:
name: junit-${{ matrix.node }}
path: report.xml
stages:
- test
variables:
npm_config_cache: $CI_PROJECT_DIR/.npm
cache:
key: $CI_COMMIT_REF_SLUG
paths: [.npm/]
test:
stage: test
image: node:${NODE}
parallel:
matrix:
- NODE: ["18", "20", "22"]
script:
- npm ci --cache .npm
- npm run lint
- npm test -- --reporter=junit --reporter-options output=report.xml
artifacts:
when: always
reports:
junit: report.xml
paths: [report.xml]
version: 2.1
jobs:
test:
parameters:
node:
type: string
docker:
- image: cimg/node:<< parameters.node >>
steps:
- checkout
- restore_cache:
keys:
- npm-{{ checksum "package-lock.json" }}-<< parameters.node >>
- run: npm ci
- save_cache:
key: npm-{{ checksum "package-lock.json" }}-<< parameters.node >>
paths: [node_modules]
- run: npm run lint
- run: npm test -- --reporter=junit --reporter-options output=report.xml
- store_test_results:
path: report.xml
- store_artifacts:
path: report.xml
workflows:
main:
jobs:
- test:
matrix:
parameters:
node: ["18", "20", "22"]
image: node:20
definitions:
caches:
npm: ~/.npm
pipelines:
default:
- parallel:
- step:
name: test (Node 20)
caches: [npm]
script:
- npm ci
- npm run lint
- npm test -- --reporter=junit --reporter-options output=test-reports/report.xml
artifacts:
- test-reports/**
- step:
name: test (Node 22)
image: node:22
caches: [npm]
script:
- npm ci
- npm test
artifacts:
- test-reports/**
Related Tools
YAML Formatter
Format and validate YAML. Convert YAML to JSON or JSON to YAML. Supports 2 and 4 space indentation.
Cron Builder
Visual builder for cron-job schedules.
Gitignore Generator
Generate .gitignore files for any language, framework, or IDE — 100+ templates, 100% client-side.
JSON Schema Generator
Generate a JSON Schema from one or more sample JSONs — drafts 2020-12, 2019-09, 7, 6, 4. Detects formats (date-time, email, uuid, ipv4, uri), extracts $defs, validates with AJV, and exports to YAML, TypeScript, and Zod. 100% in your browser.
AI Coding Rules
Curated rules-file library and generator for Cursor, Claude Code, GitHub Copilot, Windsurf, Cline, Aider, Continue, and Cody. Browse 20 hand-crafted .cursorrules / CLAUDE.md / copilot-instructions.md files for popular stacks, build a custom one with the wizard, or convert any rules file between AI-tool formats.