CI/CD
This guide covers the GitHub Actions workflows included in the template.
Workflows
CI Workflow
File: .github/workflows/ci.yml
Runs on every push and pull request:
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- run: bun install
- run: bun run build
- run: bun run lint
- run: bun run typecheck
- run: bun run test:coverageChecks Performed
| Check | Command | Purpose |
|---|---|---|
| Build | bun run build | Package builds |
| Lint | bun run lint | Code quality |
| Typecheck | bun run typecheck | Type safety |
| Test | bun run test:coverage | Tests pass, coverage |
Release Workflow
File: .github/workflows/release.yml
Handles versioning and publishing using the official changesets/action:
name: Release
on:
push:
branches: [main]
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: oven-sh/setup-bun@v2
- run: bun install
- run: bun run build
- name: Create Release PR or Publish
id: changesets
uses: changesets/action@v1
with:
version: bun run changeset:version
publish: bun run release
title: "chore(release): version packages"
commit: "chore(release): version packages"
createGithubReleases: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Generate Release Notes
if: steps.changesets.outputs.published == 'true'
run: bunx changelogithub
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}Note: The
changesets/actionhandles changeset detection, PR creation, and publishing. Release notes are generated bychangelogithub.
What It Does
- Detects changeset files
- Creates "Version Packages" PR if changesets exist
- When PR is merged, publishes to npm
- Generates GitHub release notes with
changelogithub
Required Permissions
For organizations, you must enable GitHub Actions to create pull requests:
- Go to repository Settings → Actions → General
- Scroll to Workflow permissions
- Enable "Allow GitHub Actions to create and approve pull requests"
Without this setting, the release workflow will fail when trying to create the version PR.
Docs Workflow
File: .github/workflows/docs.yml
Builds and deploys the VitePress documentation site:
name: Docs
on:
push:
branches: [main]
paths:
- "docs/**"
- ".github/workflows/docs.yml"
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- run: bun install
- run: bun run docs:build
- uses: actions/configure-pages@v5
- uses: actions/upload-pages-artifact@v4
with:
path: docs/.vitepress/dist
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
steps:
- uses: actions/deploy-pages@v4Setup Required
- Go to repo Settings → Pages
- Set Source to "GitHub Actions"
What It Does
- Triggers when
docs/**files change - Builds VitePress site with
bun run docs:build - Deploys to GitHub Pages
Repository Settings
Merge Settings
The template recommends squash merging for clean history:
| Setting | Value | Purpose |
|---|---|---|
| Allow squash merging | ✅ Enabled | Clean, linear history |
| Allow merge commits | ❌ Disabled | Avoid merge commit clutter |
| Allow rebase merging | ❌ Disabled | Consistent merge strategy |
| Delete branch on merge | ✅ Enabled | Auto-cleanup merged branches |
| Squash commit title | PR Title | Use PR title as commit message |
| Squash commit message | PR Body | Include PR description |
Setup with GitHub CLI
gh api repos/OWNER/REPO -X PATCH \
-f delete_branch_on_merge=true \
-f allow_squash_merge=true \
-f allow_merge_commit=false \
-f allow_rebase_merge=false \
-f squash_merge_commit_title=PR_TITLE \
-f squash_merge_commit_message=PR_BODYBranch Protection
Protect the main branch from direct pushes:
| Setting | Value | Purpose |
|---|---|---|
| Required status checks | ci | CI must pass before merge |
| Strict status checks | ✅ Enabled | Branch must be up to date |
| Dismiss stale reviews | ✅ Enabled | Re-review after new commits |
| Required approvals | 0 | Self-merge allowed (template) |
| Force pushes | ❌ Blocked | Protect commit history |
| Deletions | ❌ Blocked | Prevent accidental deletion |
Setup with GitHub CLI
gh api repos/OWNER/REPO/branches/main/protection -X PUT \
--input - << 'EOF'
{
"required_status_checks": {
"strict": true,
"contexts": ["ci"]
},
"enforce_admins": false,
"required_pull_request_reviews": {
"required_approving_review_count": 0,
"dismiss_stale_reviews": true
},
"restrictions": null,
"allow_force_pushes": false,
"allow_deletions": false
}
EOFGitHub Pages
Enable documentation site deployment:
| Setting | Value | Purpose |
|---|---|---|
| Source | GitHub Actions | Deploy via workflow |
| URL | OWNER.github.io/REPO | Documentation site |
Setup with GitHub CLI
gh api repos/OWNER/REPO/pages -X PUT -f build_type=workflowFeatures
| Feature | Status | Purpose |
|---|---|---|
| Issues | ✅ Enabled | Bug reports and features |
| Discussions | ✅ Enabled | Community Q&A |
| Wiki | ❌ Disabled | Use VitePress docs instead |
Enable Discussions
gh repo edit OWNER/REPO --enable-discussionsSecrets
Required secrets in repository settings:
| Secret | Purpose | How to Get |
|---|---|---|
GITHUB_TOKEN | Auto-provided | Automatic |
NPM_TOKEN | npm publishing | npmjs.com → Access Tokens |
CODECOV_TOKEN | Coverage uploads | codecov.io → Settings |
Adding NPM_TOKEN
- Go to npmjs.com → Access Tokens
- Generate New Token → Automation
- In GitHub: Settings → Secrets → Actions → New secret
- Name:
NPM_TOKEN, Value: your token
Customization
Adding Node.js Matrix
Test on multiple Node versions:
jobs:
build:
strategy:
matrix:
node: [20, 22]
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}Adding Coverage Upload
Upload to Codecov:
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}Adding SonarCloud
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}Debugging
View Workflow Logs
- Go to Actions tab
- Click on workflow run
- Click on job to see logs
Re-run Failed Workflow
- Go to failed workflow run
- Click "Re-run jobs" → "Re-run failed jobs"
Skip CI
Add [skip ci] to commit message:
git commit -m "docs: update readme [skip ci]"