CI/CD Deployment Skill
Purpose
CI/CD automates the path from code to production. Well-configured pipelines catch bugs before users, enforce quality gates, and make deploys boring. This skill covers pipeline creation, optimization, debugging, deployment strategies, and release management across platforms.
When to Activate
- Setting up CI/CD for a new or existing project
- Debugging failed builds or deployments
- Adding or modifying pipeline stages (lint, test, deploy)
- Configuring deployment targets (staging, preview, production)
- Optimizing build times and reducing CI costs
- Designing release workflows (semantic versioning, changelogs)
- Setting up preview/ephemeral environments per PR
- Implementing rollback procedures
Core Workflow
Step 1: Detect Existing CI/CD
Search the repository for existing configuration:
.github/workflows/*.yml # GitHub Actions
.circleci/config.yml # CircleCI
Jenkinsfile # Jenkins
.gitlab-ci.yml # GitLab CI
bitbucket-pipelines.yml # Bitbucket Pipelines
Dockerfile # Container builds
docker-compose.yml # Multi-container orchestration
vercel.json # Vercel
netlify.toml # Netlify
fly.toml # Fly.io
render.yaml # Render
railway.json # Railway
appspec.yml # AWS CodeDeploy
buildspec.yml # AWS CodeBuild
cloudbuild.yaml # Google Cloud Build
azure-pipelines.yml # Azure DevOps
Also check package.json scripts, Makefile, and Taskfile.yml for build/deploy commands the pipeline may reference.
Step 2: Understand the Stack
Before writing any pipeline config, identify:
- Language & runtime: Node.js, Python, Go, Rust, Java, etc.
- Package manager: npm, pnpm, yarn, pip, poetry, go modules, cargo
- Build tool: webpack, vite, esbuild, tsc, gradle, make
- Test runner: jest, vitest, pytest, go test, cargo test
- Linter/formatter: eslint, prettier, ruff, golangci-lint, clippy
- Deployment target: Vercel, AWS, GCP, Fly.io, Kubernetes, static hosting
- Monorepo tooling: turborepo, nx, lerna, pnpm workspaces
Step 3: Apply or Modify Pipeline Configuration
Generate or modify pipeline config following these principles:
- Match project conventions -- use the same scripts from package.json/Makefile
- Fail fast -- run cheapest checks first (lint before full test suite)
- Cache aggressively -- dependencies, build artifacts, Docker layers
- Minimize secrets -- use OIDC where possible, scope secrets to environments
- Pin versions -- actions, Docker images, runtime versions
- Set timeouts -- every job and long-running step needs an explicit timeout
Step 4: Validate
Before committing pipeline changes:
- Syntax check -- use
actionlint for GitHub Actions, circleci config validate, etc.
- Verify secret references -- confirm every
${{ secrets.X }} has a corresponding secret configured
- Confirm scripts exist -- every
npm run X or make Y must resolve to a real command
- Test locally -- use
act for GitHub Actions, circleci local execute for CircleCI
- Dry run -- push to a feature branch first, never modify the default branch pipeline blindly
Pipeline Architecture
A production-grade pipeline has five stages. Not every project needs all of them -- start simple and add stages as the project matures.
Stage 1: Build
- Install dependencies with lockfile (
npm ci, pip install -r requirements.txt)
- Enable dependency caching keyed on lockfile hash
- Compile/transpile source code
- Generate build artifacts and pass to downstream jobs
Stage 2: Quality Gate
- Lint source code (eslint, ruff, clippy)
- Type-check (tsc --noEmit, mypy, pyright)
- Run unit tests with coverage reporting
- Security scan dependencies (npm audit, trivy, snyk)
- Check for secrets in code (gitleaks, trufflehog)
Stage 3: Integration
- Run integration tests against real services (database, API)
- Execute database migrations in test environment
- Run E2E tests (Playwright, Cypress) against preview deployment
- Contract testing for microservices
Stage 4: Deploy
- Deploy to preview/staging environment on PR
- Run smoke tests against staging
- Deploy to production on merge to default branch
- Use deployment strategy appropriate to risk (see
references/deployment-strategies.md)
Stage 5: Post-Deploy
- Run smoke tests against production
- Health check endpoints
- Notify team (Slack, Discord, email)
- Tag release, generate changelog
- Monitor error rates for regression
Build Optimization
Dependency Caching
Cache dependencies to avoid re-downloading on every build:
- npm/pnpm/yarn: Cache based on lockfile hash
- pip: Cache
~/.cache/pip with requirements hash
- Go: Cache
~/go/pkg/mod with go.sum hash
- Docker: Layer caching, BuildKit cache mounts
- Turborepo/Nx: Remote caching for monorepo builds
See references/github-actions-patterns.md for platform-specific examples.
Parallel Execution
Run independent stages concurrently:
- Lint, type-check, and unit tests can run in parallel
- Different test suites (unit, integration, e2e) can run in parallel
- Multi-platform builds (linux/amd64, linux/arm64) can run in parallel
Conditional Execution
Skip unnecessary work:
- Path filters: Only run frontend tests when frontend code changes
- Skip patterns:
[skip ci] in commit message for docs-only changes
- Branch filters: Only deploy from default branch
- Changed file detection: Use tools like
dorny/paths-filter or tj-actions/changed-files
Artifact Management
- Upload build artifacts for downstream jobs instead of rebuilding
- Set retention policies to control storage costs
- Use artifact checksums to verify integrity across jobs
Platform-Specific Patterns
Detailed patterns and examples are in the reference documents:
references/github-actions-patterns.md -- Reusable workflows, caching, matrix builds, environment protection
references/deployment-strategies.md -- Rolling, blue-green, canary, feature flags, preview environments
references/rollback-procedures.md -- Platform-specific rollback, post-rollback checklist, when not to rollback
Pipeline Health Checks
Use scripts/check_pipeline_health.sh to audit an existing pipeline configuration for common issues. It checks for:
- Detected CI system and config files
- Referenced scripts that may not exist
- Hardcoded secrets or tokens in pipeline files
- Dockerfile best practices
- Missing lockfiles or .gitignore
Gotchas
Secrets
Never hardcode secrets in pipeline files. Use the platform's secret store (GitHub Secrets, CircleCI Contexts, etc.). Verify that every referenced secret actually exists in the target environment before merging. Use OIDC federation for cloud providers instead of long-lived credentials where possible.
Branch Protection
Pipeline changes on the default branch may require admin review. Always test pipeline changes in a feature branch first. Be aware that some CI platforms only read workflow files from the default branch for certain trigger types.
Build Matrix Explosion
A matrix of 3 OS versions x 3 runtime versions = 9 jobs. Constrain matrices to what you actually deploy. Use include/exclude to target specific combinations. Consider running the full matrix only on release branches.
Docker Cache Invalidation
Order Dockerfile instructions from least to most frequently changing. Copy package.json AND the lockfile before running npm install. Source code copies should come after dependency installation. Use .dockerignore to exclude node_modules, .git, and test fixtures.
Flaky Tests in CI
Investigate environment differences before adding retry logic. Common causes: timing-dependent assertions, shared test state, missing environment variables, DNS resolution differences, file system ordering. Fix the root cause -- retries mask bugs.
CI Cost Management
GitHub Actions minutes are finite on private repos. Use path filters to skip unnecessary runs. Cancel in-progress runs when a new commit is pushed to the same branch. Use self-hosted runners for heavy workloads. Monitor usage regularly.
Timeout Defaults
Set explicit timeouts on every job and long-running step. Platform defaults (6 hours on GitHub Actions) are far too generous. A hanging build that consumes 6 hours of compute is expensive and blocks the pipeline. Typical timeouts: build (15 min), unit tests (10 min), e2e tests (20 min), deploy (10 min).
Environment Parity
CI environments differ from local: different OS, different file system (case sensitivity), different network access, different available tools. Pin tool versions explicitly. Use Docker for reproducibility. Document required environment variables.
1---2name: cicd-deployment3description: Manage CI/CD pipelines, build processes, deployment configurations, and release workflows. Use when the user says 'set up CI', 'create a pipeline', 'deploy this', 'fix the build', 'GitHub Actions', 'deployment failed', 'create release workflow', 'add a build step', 'configure staging', or 'set up preview deployments'. Also triggers on 'CI/CD', 'continuous integration', 'continuous deployment', 'pipeline configuration', 'build process', 'release management', 'deploy to production', or 'workflow automation'.4---5
6# CI/CD Deployment Skill
7
8## Purpose
9
10CI/CD automates the path from code to production. Well-configured pipelines catch bugs before users, enforce quality gates, and make deploys boring. This skill covers pipeline creation, optimization, debugging, deployment strategies, and release management across platforms.
11
12## When to Activate
13
14- Setting up CI/CD for a new or existing project
15- Debugging failed builds or deployments
16- Adding or modifying pipeline stages (lint, test, deploy)
17- Configuring deployment targets (staging, preview, production)
18- Optimizing build times and reducing CI costs
19- Designing release workflows (semantic versioning, changelogs)
20- Setting up preview/ephemeral environments per PR
21- Implementing rollback procedures
22
23## Core Workflow
24
25### Step 1: Detect Existing CI/CD
26
27Search the repository for existing configuration:
28
29```
30.github/workflows/*.yml # GitHub Actions
31.circleci/config.yml # CircleCI
32Jenkinsfile # Jenkins
33.gitlab-ci.yml # GitLab CI
34bitbucket-pipelines.yml # Bitbucket Pipelines
35Dockerfile # Container builds
36docker-compose.yml # Multi-container orchestration
37vercel.json # Vercel
38netlify.toml # Netlify
39fly.toml # Fly.io
40render.yaml # Render
41railway.json # Railway
42appspec.yml # AWS CodeDeploy
43buildspec.yml # AWS CodeBuild
44cloudbuild.yaml # Google Cloud Build
45azure-pipelines.yml # Azure DevOps
46```
47
48Also check `package.json` scripts, `Makefile`, and `Taskfile.yml` for build/deploy commands the pipeline may reference.
49
50### Step 2: Understand the Stack
51
52Before writing any pipeline config, identify:
53
54- **Language & runtime**: Node.js, Python, Go, Rust, Java, etc.
55- **Package manager**: npm, pnpm, yarn, pip, poetry, go modules, cargo
56- **Build tool**: webpack, vite, esbuild, tsc, gradle, make
57- **Test runner**: jest, vitest, pytest, go test, cargo test
58- **Linter/formatter**: eslint, prettier, ruff, golangci-lint, clippy
59- **Deployment target**: Vercel, AWS, GCP, Fly.io, Kubernetes, static hosting
60- **Monorepo tooling**: turborepo, nx, lerna, pnpm workspaces
61
62### Step 3: Apply or Modify Pipeline Configuration
63
64Generate or modify pipeline config following these principles:
65
661. **Match project conventions** -- use the same scripts from package.json/Makefile
672. **Fail fast** -- run cheapest checks first (lint before full test suite)
683. **Cache aggressively** -- dependencies, build artifacts, Docker layers
694. **Minimize secrets** -- use OIDC where possible, scope secrets to environments
705. **Pin versions** -- actions, Docker images, runtime versions
716. **Set timeouts** -- every job and long-running step needs an explicit timeout
72
73### Step 4: Validate
74
75Before committing pipeline changes:
76
771. **Syntax check** -- use `actionlint` for GitHub Actions, `circleci config validate`, etc.
782. **Verify secret references** -- confirm every `${{ secrets.X }}` has a corresponding secret configured
793. **Confirm scripts exist** -- every `npm run X` or `make Y` must resolve to a real command
804. **Test locally** -- use `act` for GitHub Actions, `circleci local execute` for CircleCI
815. **Dry run** -- push to a feature branch first, never modify the default branch pipeline blindly
82
83## Pipeline Architecture
84
85A production-grade pipeline has five stages. Not every project needs all of them -- start simple and add stages as the project matures.
86
87### Stage 1: Build
88
89- Install dependencies with lockfile (`npm ci`, `pip install -r requirements.txt`)
90- Enable dependency caching keyed on lockfile hash
91- Compile/transpile source code
92- Generate build artifacts and pass to downstream jobs
93
94### Stage 2: Quality Gate
95
96- Lint source code (eslint, ruff, clippy)
97- Type-check (tsc --noEmit, mypy, pyright)
98- Run unit tests with coverage reporting
99- Security scan dependencies (npm audit, trivy, snyk)
100- Check for secrets in code (gitleaks, trufflehog)
101
102### Stage 3: Integration
103
104- Run integration tests against real services (database, API)
105- Execute database migrations in test environment
106- Run E2E tests (Playwright, Cypress) against preview deployment
107- Contract testing for microservices
108
109### Stage 4: Deploy
110
111- Deploy to preview/staging environment on PR
112- Run smoke tests against staging
113- Deploy to production on merge to default branch
114- Use deployment strategy appropriate to risk (see `references/deployment-strategies.md`)
115
116### Stage 5: Post-Deploy
117
118- Run smoke tests against production
119- Health check endpoints
120- Notify team (Slack, Discord, email)
121- Tag release, generate changelog
122- Monitor error rates for regression
123
124## Build Optimization
125
126### Dependency Caching
127
128Cache dependencies to avoid re-downloading on every build:
129
130- **npm/pnpm/yarn**: Cache based on lockfile hash
131- **pip**: Cache `~/.cache/pip` with requirements hash
132- **Go**: Cache `~/go/pkg/mod` with go.sum hash
133- **Docker**: Layer caching, BuildKit cache mounts
134- **Turborepo/Nx**: Remote caching for monorepo builds
135
136See `references/github-actions-patterns.md` for platform-specific examples.
137
138### Parallel Execution
139
140Run independent stages concurrently:
141
142- Lint, type-check, and unit tests can run in parallel
143- Different test suites (unit, integration, e2e) can run in parallel
144- Multi-platform builds (linux/amd64, linux/arm64) can run in parallel
145
146### Conditional Execution
147
148Skip unnecessary work:
149
150- **Path filters**: Only run frontend tests when frontend code changes
151- **Skip patterns**: `[skip ci]` in commit message for docs-only changes
152- **Branch filters**: Only deploy from default branch
153- **Changed file detection**: Use tools like `dorny/paths-filter` or `tj-actions/changed-files`
154
155### Artifact Management
156
157- Upload build artifacts for downstream jobs instead of rebuilding
158- Set retention policies to control storage costs
159- Use artifact checksums to verify integrity across jobs
160
161## Platform-Specific Patterns
162
163Detailed patterns and examples are in the reference documents:
164
165- `references/github-actions-patterns.md` -- Reusable workflows, caching, matrix builds, environment protection
166- `references/deployment-strategies.md` -- Rolling, blue-green, canary, feature flags, preview environments
167- `references/rollback-procedures.md` -- Platform-specific rollback, post-rollback checklist, when not to rollback
168
169## Pipeline Health Checks
170
171Use `scripts/check_pipeline_health.sh` to audit an existing pipeline configuration for common issues. It checks for:
172
173- Detected CI system and config files
174- Referenced scripts that may not exist
175- Hardcoded secrets or tokens in pipeline files
176- Dockerfile best practices
177- Missing lockfiles or .gitignore
178
179## Gotchas
180
181### Secrets
182
183Never hardcode secrets in pipeline files. Use the platform's secret store (GitHub Secrets, CircleCI Contexts, etc.). Verify that every referenced secret actually exists in the target environment before merging. Use OIDC federation for cloud providers instead of long-lived credentials where possible.
184
185### Branch Protection
186
187Pipeline changes on the default branch may require admin review. Always test pipeline changes in a feature branch first. Be aware that some CI platforms only read workflow files from the default branch for certain trigger types.
188
189### Build Matrix Explosion
190
191A matrix of 3 OS versions x 3 runtime versions = 9 jobs. Constrain matrices to what you actually deploy. Use `include`/`exclude` to target specific combinations. Consider running the full matrix only on release branches.
192
193### Docker Cache Invalidation
194
195Order Dockerfile instructions from least to most frequently changing. Copy `package.json` AND the lockfile before running `npm install`. Source code copies should come after dependency installation. Use `.dockerignore` to exclude `node_modules`, `.git`, and test fixtures.
196
197### Flaky Tests in CI
198
199Investigate environment differences before adding retry logic. Common causes: timing-dependent assertions, shared test state, missing environment variables, DNS resolution differences, file system ordering. Fix the root cause -- retries mask bugs.
200
201### CI Cost Management
202
203GitHub Actions minutes are finite on private repos. Use path filters to skip unnecessary runs. Cancel in-progress runs when a new commit is pushed to the same branch. Use self-hosted runners for heavy workloads. Monitor usage regularly.
204
205### Timeout Defaults
206
207Set explicit timeouts on every job and long-running step. Platform defaults (6 hours on GitHub Actions) are far too generous. A hanging build that consumes 6 hours of compute is expensive and blocks the pipeline. Typical timeouts: build (15 min), unit tests (10 min), e2e tests (20 min), deploy (10 min).
208
209### Environment Parity
210
211CI environments differ from local: different OS, different file system (case sensitivity), different network access, different available tools. Pin tool versions explicitly. Use Docker for reproducibility. Document required environment variables.