@deposition.cloud/node-pipeline v1.6.1
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 npm ci/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 23 images for dev / test / prod with 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/node-pipeline-template"
file: "/.gitlab-ci-template.yml"
That’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:
- npm run lint
Here’s a suggested 🧪 Development section you can add to the README to guide internal contributors working on this template:
🧪 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-ci-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 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/node-pipeline-template' ref: 'your-feature-branch' file: '/.gitlab-ci-template.yml'
Push and observe the CI pipeline behavior.
Publishing Changes
- All changes must follow Conventional Commits.
Pushing to
main
triggerssemantic-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-dev
This will execute:
dumb-init npm run start
Which, 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 npm node-pipeline-test run test
4. 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/.npm \
-t node-pipeline-dev .
🛠 Pipeline Overview
Job | Trigger (branch/tag) | What happens |
---|---|---|
build | every push | Installs deps with npm ci , caches layers, runs npm 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_script
writes.npmrc
using templated$CI_API_V4_URL
,$CI_JOB_TOKEN
, namespace, and project ID.Dockerfile
installs Node 23 either via official binaries or source build (fallback for unusual arches), then definesdev
,test
,release
stages.release.config.ts
wiressemantic-release
plugins:- GitLab release + Changelog + Git commit
@eclass/semantic-release-docker
twice: once for‑dev
images, once for prod.
Versioning follows Conventional Commits; change the commit message → pipeline decides the next version.
🤝 Contributing
- Fork & clone this repo.
npm ci
- 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
.npmrc
handling, release workflow, or Dockerfile
🪪 License
Released under the Hippocratic 2.1 License — ethical open source. See LICENSE
for details.