ci-cd
SKILL.md
CI/CD - Pipeline & Deployment Patterns
Production patterns for GitHub Actions, deployment strategies, and release automation
When to Use This Skill
Use this skill when:
- Setting up CI/CD pipelines
- Configuring GitHub Actions workflows
- Implementing deployment strategies
- Automating testing and linting
- Building release workflows
- Setting up preview deployments
Don't use this skill when:
- Using managed deployment platforms only (Vercel, Netlify auto-deploy)
- Infrastructure as code (see
dockerskill)
Critical Patterns
Pattern 1: Basic CI Pipeline
When: Automated testing on every PR
# ✅ GOOD: .github/workflows/ci.yml
name: CI
on:
pull_request:
branches: [main]
push:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run lint
typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run typecheck
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm test -- --coverage
- uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
build:
runs-on: ubuntu-latest
needs: [lint, typecheck, test]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run build
- uses: actions/upload-artifact@v4
with:
name: build
path: .next
# ❌ BAD: Single job doing everything sequentially
jobs:
build:
steps:
- run: npm run lint && npm run typecheck && npm test && npm run build
Pattern 2: Deployment Workflow
When: Automated staging and production deployments
# ✅ GOOD: .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
workflow_dispatch:
inputs:
environment:
description: 'Environment to deploy'
required: true
default: 'staging'
type: choice
options:
- staging
- production
jobs:
test:
uses: ./.github/workflows/ci.yml
deploy-staging:
needs: test
runs-on: ubuntu-latest
environment:
name: staging
url: https://staging.example.com
steps:
- uses: actions/checkout@v4
- name: Deploy to Vercel (Staging)
run: |
npx vercel deploy --token=${{ secrets.VERCEL_TOKEN }} \
--env NEXT_PUBLIC_API_URL=${{ vars.API_URL }}
deploy-production:
needs: deploy-staging
runs-on: ubuntu-latest
if: github.event.inputs.environment == 'production' || github.ref == 'refs/heads/main'
environment:
name: production
url: https://example.com
steps:
- uses: actions/checkout@v4
- name: Deploy to Vercel (Production)
run: |
npx vercel deploy --prod --token=${{ secrets.VERCEL_TOKEN }} \
--env NEXT_PUBLIC_API_URL=${{ vars.API_URL }}
- name: Notify Slack
uses: slackapi/slack-github-action@v1
with:
payload: |
{
"text": "🚀 Deployed to production: ${{ github.sha }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
Pattern 3: Release Workflow
When: Automating version bumps and changelog generation
# ✅ GOOD: .github/workflows/release.yml
name: Release
on:
push:
tags:
- 'v*'
permissions:
contents: write
packages: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate changelog
id: changelog
uses: orhun/git-cliff-action@v3
with:
config: cliff.toml
args: --latest --strip header
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
body: ${{ steps.changelog.outputs.content }}
draft: false
prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') }}
- name: Deploy to Production
run: |
npx vercel deploy --prod --token=${{ secrets.VERCEL_TOKEN }}
# Conventional commit workflow for automatic versioning
# .github/workflows/version.yml
name: Version
on:
push:
branches: [main]
jobs:
version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.PAT }}
- name: Bump version
uses: conventional-changelog/standard-version@v15
with:
release-as: patch # or minor, major
- name: Push changes
run: |
git push --follow-tags origin main
Pattern 4: Preview Deployments
When: Creating preview environments for PRs
# ✅ GOOD: .github/workflows/preview.yml
name: Preview
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
deploy-preview:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v4
- name: Deploy Preview
id: deploy
run: |
PREVIEW_URL=$(npx vercel deploy --token=${{ secrets.VERCEL_TOKEN }})
echo "url=$PREVIEW_URL" >> $GITHUB_OUTPUT
- name: Comment on PR
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `🔗 Preview deployed: ${{ steps.deploy.outputs.url }}`
})
cleanup-preview:
runs-on: ubuntu-latest
if: github.event.action == 'closed'
steps:
- name: Delete Preview
run: |
# Clean up preview deployment
echo "Cleaning up preview for PR #${{ github.event.number }}"
Pattern 5: Matrix Testing
When: Testing across multiple versions or platforms
# ✅ GOOD: Matrix strategy for comprehensive testing
name: Test Matrix
on: [push, pull_request]
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node: [18, 20, 22]
exclude:
- os: windows-latest
node: 18 # Skip old Node on Windows
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: 'npm'
- run: npm ci
- run: npm test
test-database:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: test
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis:7
ports:
- 6379:6379
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- name: Run migrations
run: npx prisma migrate deploy
env:
DATABASE_URL: postgres://postgres:postgres@localhost:5432/test
- name: Run tests
run: npm test
env:
DATABASE_URL: postgres://postgres:postgres@localhost:5432/test
REDIS_URL: redis://localhost:6379
Code Examples
For complete, production-ready examples, see references/examples.md:
- Reusable Workflow
- Database Migration Pipeline
- Monorepo CI
- Docker Build and Push
Anti-Patterns
Don't: Hardcode Secrets
# ❌ BAD: Secrets in workflow file
env:
API_KEY: sk-12345abcdef
# ✅ GOOD: Use GitHub Secrets
env:
API_KEY: ${{ secrets.API_KEY }}
Don't: Deploy Without Tests
# ❌ BAD: Deploy without testing
on:
push:
branches: [main]
jobs:
deploy:
steps:
- run: npm run deploy # What if tests fail?
# ✅ GOOD: Tests must pass first
jobs:
test:
# ... run tests
deploy:
needs: test # Only runs if test passes
Don't: Skip Caching
# ❌ BAD: Installing dependencies every time
- run: npm ci # Downloads everything every run
# ✅ GOOD: Cache dependencies
- uses: actions/setup-node@v4
with:
cache: 'npm'
- run: npm ci # Uses cache when possible
Quick Reference
| Task | Action/Approach | Example |
|---|---|---|
| Cache deps | actions/setup-node with cache |
cache: 'npm' |
| Parallel jobs | Matrix strategy | matrix: { node: [18, 20] } |
| Service deps | Services containers | services: postgres: |
| Preview deploy | PR comment with URL | actions/github-script |
| Auto-release | Tag-triggered workflow | on: push: tags: ['v*'] |
| Reuse workflows | workflow_call |
uses: ./.github/workflows/x.yml |
Resources
Official Documentation:
Related Skills:
- docker: Container builds in CI
- observability: Deployment monitoring
- security: Secure CI/CD practices
Keywords
ci-cd, github-actions, deployment, pipelines, automation, continuous-integration, continuous-deployment, release, preview
Weekly Installs
2
Repository
dsantiagomj/dsm…-toolkitFirst Seen
Feb 25, 2026
Security Audits
Installed on
trae-cn2
gemini-cli2
codebuddy2
github-copilot2
codex2
kiro-cli2