@deposition.cloud/node-pipeline
v2.0.0
Published
Node CI
Readme
Node Pipeline Template
A batteries‑included GitLab CI/CD template that gives every Node.js project the same, battle‑tested pipeline in one line of YAML. Use it to ship NPM packages, publish Docker images, and generate changelogs automatically—without copying any YAML between repos.
✨ Vision
"Define a secure, repeatable, zero‑maintenance release workflow for every Node project in the organisation."
Instead of bespoke .gitlab-ci.yml files, teams simply include this template and inherit a pipeline that already follows our best practices:
- Single source of truth – fixes & improvements land once, benefit everyone.
- Security by default – credentials are injected at runtime, never committed.
- Semantic, automated releases – human‑friendly versioning & changelogs.
- Multi‑registry publishing – GitLab ⇢ Docker Hub ⇢ GHCR in one shot.
🔑 Core Features
| Capability | What it does | Why it matters |
| --- | --- | --- |
| Dynamic .npmrc injection | Generates a project‑scoped .npmrc with $CI_JOB_TOKEN so pnpm install/publish can talk to GitLab’s private registry. | Keeps tokens out of the repo and works for every namespace/project. |
| Semantic‑release | Analyses commit messages, bumps package.json, updates docs/CHANGELOG.md, creates Git tags/releases, and triggers Docker/NPM publishing. | Zero manual versioning; consistent changelogs. |
| Multi‑stage Dockerfile | Builds Node.js 24 images for dev / test / prod with an Alpine base and optional source build fallback. | Fast layer caching and identical runtime across projects. |
| Dev & Prod image tags | Publishes :latest, :next, :beta, :alpha, plus a ‑dev image for branch builds. | Try features early without polluting production tags. |
| Reusable YAML anchors/jobs | build, unit, latest, tag, semantic jobs are ready to extend. | Clear separation of concerns; easy overrides. |
📚 Typical Use Cases
- Private NPM libraries that should be versioned & installable via GitLab’s registry.
- Microservices / CLIs that ship as Docker images to multiple registries.
- Frontend apps that just want a lint→test→semantic‑release flow without extra wiring.
🚀 Quick Start
Add a single include in your project‑level .gitlab-ci.yml:
include:
- project: "deposition.cloud/infra/devops/ci-cd-templates/node-pipeline"
file: ".gitlab/template.yml"
build:
extends: .build
unit:
extends: .unit
latest:
extends: .latest
tag:
extends: .tag
semantic:
extends: .semantic-nodeThat’s it. The default jobs will build, test and release on every push/tag.
Required CI/CD variables
| Variable | When needed | Description |
| --- | --- | --- |
| CI_JOB_TOKEN | always (provided by GitLab) | Used for private registry auth – no action required. |
| DOCKER_REGISTRY_USER / DOCKER_REGISTRY_PASSWORD | if publishing to Docker Hub | Credentials for docker.io. |
| GITHUB_USER / GITHUB_TOKEN | if publishing to GHCR | Personal access token with write:packages scope. |
You can override or extend any job with extends:—for example, to add linting:
lint:
extends: .unit # runs before semantic‑release
script:
- pnpm run lint🧪 Development
This repo is not a typical Node app — it’s a pipeline template. That means most development focuses on the following:
Key Areas to Modify
.gitlab/template.yml: add or improve reusable job blocks (e.g.,.build,.semantic)release.config.ts: update semantic-release logic (e.g., new Docker registries or tagging logic)Dockerfile: adjust Node.js installation or improve CI image stagesdocs/CHANGELOG.md: is auto-updated by semantic-releasepackage.json: only defines minimal scripts and dependencies required for CI
Local Testing
You don’t “run” this repo locally. But to validate changes:
Clone a test project that includes this template.
In that test project’s
.gitlab-ci.yml, point to a specific branch or ref:include: - project: 'deposition.cloud/infra/devops/ci-cd-templates/node-pipeline' ref: 'your-feature-branch' file: '.gitlab/template.yml'Push and observe the CI pipeline behavior.
Publishing Changes
All changes must follow Conventional Commits.
Pushing to
maintriggerssemantic-release, which:- bumps
package.json - updates
CHANGELOG.md - creates a GitLab release
- publishes Docker images and NPM package
- bumps
✅ Quick Local Build & Test
1. Build the image
You can build any stage explicitly using --target.
# To build the full release image (prod)
docker build -t node-pipeline-release .
# To build just the dev stage (includes node_modules, scripts)
docker build --target dev -t node-pipeline-dev .
# To build the test stage (runs lint & test scripts)
docker build --target test -t node-pipeline-test .Add --progress=plain if you want more verbose output.
2. Run it
docker run --rm -it node-pipeline-devThis will execute:
dumb-init pnpm run startWhich, in this template project, just logs Hello world!.
3. Override commands
To run custom scripts, override the default CMD:
# Open a shell
docker run --rm -it --entrypoint sh node-pipeline-dev
# Or run tests
docker run --rm -it --entrypoint pnpm node-pipeline-test run test4. Use BuildKit cache (optional but faster)
DOCKER_BUILDKIT=1 docker build -t node-pipeline-dev .You can also mount cache explicitly like CI does:
docker build \
--build-arg BUILD_WORKDIR=/app \
--mount type=cache,target=/app/.pnpm-store \
-t node-pipeline-dev .🛠 Pipeline Overview
| Job | Trigger (branch/tag) | What happens |
| --- | --- | --- |
| build | every push | Installs deps with pnpm install, caches layers, runs pnpm run build. |
| unit | every push | Placeholder for tests / linters (defaults to vitest). |
| latest | main branch | Builds & pushes dev Docker images (‑dev suffix). |
| tag | version tags | Builds & pushes prod images (no suffix). |
| semantic | main, prerelease branches, tags | Runs semantic‑release → bumps version, updates changelog, publishes NPM package + Docker images. |
🧩 How It Works
before_scriptwrites.npmrcusing templated$CI_API_V4_URL,$CI_JOB_TOKEN, namespace, and project ID.Dockerfileinstalls Node.js 24 either via official binaries or source build (fallback for unusual arches), then definesdev,test,releasestages.release.config.tswiressemantic-releaseplugins:- GitLab release + Changelog + Git commit
@eclass/semantic-release-dockertwice: once for‑devimages, once for prod.
Versioning follows Conventional Commits; change the commit message → pipeline decides the next version.
🤝 Contributing
- Fork & clone this repo.
pnpm install- Make your change, commit using Conventional Commits.
- Push → the pipeline will run locally; once merged, downstream projects get the new template via
include: ref:pinning.
Please open MRs for:
- New pipeline features or job types
- Docs & examples
- Bug fixes in
.npmrchandling, release workflow, or Dockerfile
🪪 License
Released under the Hippocratic 2.1 License — ethical open source. See LICENSE for details.
