CI/CD
This template includes three GitHub Actions workflows for continuous integration and delivery.
Workflows Overview
| Workflow | File | Purpose | Trigger |
|---|---|---|---|
| CI | ci.yml | Quality checks | PRs, pushes to main |
| Docs | docs.yml | Deploy documentation | Pushes to main (docs paths) |
| Release | release.yml | Version and publish | Pushes to main (changeset paths) |
CI Workflow
File: .github/workflows/ci.yml
Triggers
on:
pull_request:
push:
branches: [main]Runs on:
- All pull requests
- Direct pushes to
main
Steps
- Checkout — Clone the repository
- Setup Node — Install Node.js 20
- Enable Corepack — Activate pnpm from
packageManagerfield - Install dependencies —
pnpm install --frozen-lockfile - Lint —
pnpm run lint - Typecheck —
pnpm run typecheck - Test —
pnpm run test - Build —
pnpm run build - Package lint —
pnpm run lint:package - Unused deps check —
pnpm run lint:deps - Markdown lint —
pnpm run lint:md - Docs build —
pnpm run docs:build
Why This Order?
The steps are ordered by:
- Fast failures first — Lint and typecheck catch issues quickly
- Dependencies — Build must succeed before publint
- Completeness — Docs build verifies everything integrates
Docs Workflow
File: .github/workflows/docs.yml
Triggers
on:
push:
branches: [main]
paths:
- "docs/**"
- "package.json"
- "pnpm-lock.yaml"
- "typedoc.json"
- "src/**"
workflow_dispatch:Runs on:
- Pushes to
mainthat modify documentation-related files - Manual dispatch (allows triggering from GitHub UI)
Path Filtering
The workflow only runs when relevant files change:
| Path | Reason |
|---|---|
docs/** | Documentation content changed |
package.json | Version or config may affect docs |
pnpm-lock.yaml | Dependencies may affect docs build |
typedoc.json | API docs configuration changed |
src/** | API docs depend on source code |
This saves CI minutes by not rebuilding docs for unrelated changes.
Jobs
Build Job:
- Checkout repository
- Setup Node with Corepack
- Install dependencies
- Build docs (
pnpm run docs:build) - Upload artifact to GitHub Pages
Deploy Job:
- Deploy artifact to GitHub Pages
Permissions
permissions:
contents: read
pages: write
id-token: writepages: write— Required to deploy to GitHub Pagesid-token: write— Required for GitHub's OIDC authentication
Release Workflow
File: .github/workflows/release.yml
Triggers
on:
push:
branches: [main]
paths:
- ".changeset/**"
- "package.json"
- "pnpm-lock.yaml"Runs on pushes to main that modify:
- Changeset files (new or consumed)
- Package configuration
How It Works
The workflow uses changesets/action:
Check for changesets — Are there pending changesets in
.changeset/?If changesets exist:
- Creates or updates a "Version Packages" PR
- PR contains version bumps and CHANGELOG updates
If no changesets (and Version PR was merged):
- Publishes to npm
- Creates GitHub release
Quality Gates
Before releasing, the workflow runs:
- name: Quality gates
run: |
pnpm run lint
pnpm run typecheck
pnpm run test
pnpm run build
pnpm run lint:packageThis ensures only working code is published.
Required Secrets
| Secret | Purpose | How to Set |
|---|---|---|
GITHUB_TOKEN | Create PRs, releases | Automatic (provided by GitHub) |
NPM_TOKEN | Publish to npm | Add manually in repo settings |
See Releases for npm token setup.
Permissions
permissions:
contents: write
pull-requests: writecontents: write— Create releases, push version commitspull-requests: write— Create and update Version PR
Common Issues
pnpm Not Found
Symptom: CI fails with "pnpm: command not found"
Cause: Corepack not enabled
Fix: Ensure the workflow includes:
- name: Enable Corepack
run: corepack enableFrozen Lockfile Fails
Symptom: pnpm install --frozen-lockfile fails
Cause: pnpm-lock.yaml is out of sync with package.json
Fix locally:
pnpm install
git add pnpm-lock.yaml
git commit -m "chore: update lockfile"
git pushDocs Deploy Fails
Symptom: Docs workflow succeeds but site shows 404
Cause: GitHub Pages not configured correctly
Fix: See GitHub Pages Setup
Release Not Publishing
Symptom: Version PR merged but no npm publish
Causes:
NPM_TOKENsecret not set- Token doesn't have publish permissions
- Package name already taken on npm
Fix: Check Actions logs for the specific error.
Concurrency
All workflows use concurrency controls:
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: trueThis means:
- Only one run per branch at a time
- New pushes cancel in-progress runs
- Saves CI minutes on rapid iteration
The release workflow uses cancel-in-progress: false to prevent interrupted publishes.
Running Locally
You can run the same checks locally:
# Full CI equivalent
pnpm run lint
pnpm run typecheck
pnpm run test
pnpm run build
pnpm run lint:package
pnpm run lint:deps
pnpm run lint:md
pnpm run docs:buildThis helps catch issues before pushing.