CI/CD and Automation

Automates CI/CD pipeline setup.

How to use it

Claude Code
  1. Run the line below. It pulls the whole folder into ~/.claude/skills/ci-cd-and-automation.
  2. Describe your job in plain words. Claude Code follows the skill from there.
Claude Code — installs the whole folder, not just SKILL.md
npx degit addyosmani/agent-skills/skills/ci-cd-and-automation#main ~/.claude/skills/ci-cd-and-automation

For one project only, change the path to .claude/skills/ci-cd-and-automation.

Claude (web or desktop app)
  1. On this page open ⋯ → Download .md.
  2. Save it as SKILL.md in a folder, zip the folder, then Customize → Skills → + → Create skill → Upload a skill.
  3. Pick the file and Save. Claude shows the name and description and runs a security scan.
  4. Check the skill is switched on.
  5. Start a new chat and describe your job in plain words. The AI follows the skill from there.
ChatGPT or another app
  1. ChatGPT: make a Project and paste it into Instructions.
  2. Neither? Paste it at the top of a new chat — it works for that chat.
Not working?
  • Check which app you pasted it into — the steps above name the right one.
  • Some skills need the paid tier of Claude or ChatGPT.
Step-by-step guide with screenshots · Ask in the forum

Paste into Claude, ChatGPT or Cursor.

Source of CI/CD and Automation

Show the full text391 lines
namedescription
ci-cd-and-automationAutomates CI/CD pipeline setup. Use when setting up or modifying build and deployment pipelines. Use when you need to automate quality gates, configure test runners in CI, or establish deployment strategies.

CI/CD and Automation

Overview

Automate quality gates so that no change reaches production without passing tests, lint, type checking, and build. CI/CD is the enforcement mechanism for every other skill — it catches what humans and agents miss, and it does so consistently on every single change.

Shift Left: Catch problems as early in the pipeline as possible. A bug caught in linting costs minutes; the same bug caught in production costs hours. Move checks upstream — static analysis before tests, tests before staging, staging before production.

Faster is Safer: Smaller batches and more frequent releases reduce risk, not increase it. A deployment with 3 changes is easier to debug than one with 30. Frequent releases build confidence in the release process itself.

When to Use

  • Setting up a new project's CI pipeline
  • Adding or modifying automated checks
  • Configuring deployment pipelines
  • When a change should trigger automated verification
  • Debugging CI failures

The Quality Gate Pipeline

Every change goes through these gates before merge:

Pull Request Opened
    │
    ▼
┌─────────────────┐
│   LINT CHECK     │  eslint, prettier
│   ↓ pass         │
│   TYPE CHECK     │  tsc --noEmit
│   ↓ pass         │
│   UNIT TESTS     │  jest/vitest
│   ↓ pass         │
│   BUILD          │  npm run build
│   ↓ pass         │
│   INTEGRATION    │  API/DB tests
│   ↓ pass         │
│   E2E (optional) │  Playwright/Cypress
│   ↓ pass         │
│   SECURITY AUDIT │  npm audit
│   ↓ pass         │
│   BUNDLE SIZE    │  bundlesize check
└─────────────────┘
    │
    ▼
  Ready for review

No gate can be skipped. If lint fails, fix lint — don't disable the rule. If a test fails, fix the code — don't skip the test.

GitHub Actions Configuration

Basic CI Pipeline
# .github/workflows/ci.yml
name: CI

on:
  pull_request:
    branches: [main]
  push:
    branches: [main]

jobs:
  quality:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '22'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Lint
        run: npm run lint

      - name: Type check
        run: npx tsc --noEmit

      - name: Test
        run: npm test -- --coverage

      - name: Build
        run: npm run build

      - name: Security audit
        run: npm audit --audit-level=high
With Database Integration Tests
  integration:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_DB: testdb
          POSTGRES_USER: ci_user
          POSTGRES_PASSWORD: ${{ secrets.CI_DB_PASSWORD }}
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '22'
          cache: 'npm'
      - run: npm ci
      - name: Run migrations
        run: npx prisma migrate deploy
        env:
          DATABASE_URL: postgresql://ci_user:${{ secrets.CI_DB_PASSWORD }}@localhost:5432/testdb
      - name: Integration tests
        run: npm run test:integration
        env:
          DATABASE_URL: postgresql://ci_user:${{ secrets.CI_DB_PASSWORD }}@localhost:5432/testdb

Note: Even for CI-only test databases, use GitHub Secrets for credentials rather than hardcoding values. This builds good habits and prevents accidental reuse of test credentials in other contexts.

E2E Tests
  e2e:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '22'
          cache: 'npm'
      - run: npm ci
      - name: Install Playwright
        run: npx playwright install --with-deps chromium
      - name: Build
        run: npm run build
      - name: Run E2E tests
        run: npx playwright test
      - uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: playwright-report
          path: playwright-report/

Feeding CI Failures Back to Agents

The power of CI with AI agents is the feedback loop. When CI fails:

CI fails
    │
    ▼
Copy the failure output
    │
    ▼
Feed it to the agent:
"The CI pipeline failed with this error:
[paste specific error]
Fix the issue and verify locally before pushing again."
    │
    ▼
Agent fixes → pushes → CI runs again

Key patterns:

Lint failure → Agent runs `npm run lint --fix` and commits
Type error  → Agent reads the error location and fixes the type
Test failure → Agent follows debugging-and-error-recovery skill
Build error → Agent checks config and dependencies

Deployment Strategies

Preview Deployments

Every PR gets a preview deployment for manual testing:

# Deploy preview on PR (Vercel/Netlify/etc.)
deploy-preview:
  runs-on: ubuntu-latest
  if: github.event_name == 'pull_request'
  steps:
    - uses: actions/checkout@v4
    - name: Deploy preview
      run: npx vercel --token=${{ secrets.VERCEL_TOKEN }}
Feature Flags

Feature flags decouple deployment from release. Deploy incomplete or risky features behind flags so you can:

  • Ship code without enabling it. Merge to main early, enable when ready.
  • Roll back without redeploying. Disable the flag instead of reverting code.
  • Canary new features. Enable for 1% of users, then 10%, then 100%.
  • Run A/B tests. Compare behavior with and without the feature.
// Simple feature flag pattern
if (featureFlags.isEnabled('new-checkout-flow', { userId })) {
  return renderNewCheckout();
}
return renderLegacyCheckout();

Flag lifecycle: Create → Enable for testing → Canary → Full rollout → Remove the flag and dead code. Flags that live forever become technical debt — set a cleanup date when you create them.

Staged Rollouts
PR merged to main
    │
    ▼
  Staging deployment (auto)
    │ Manual verification
    ▼
  Production deployment (manual trigger or auto after staging)
    │
    ▼
  Monitor for errors (15-minute window)
    │
    ├── Errors detected → Rollback
    └── Clean → Done
Rollback Plan

Every deployment should be reversible:

# Manual rollback workflow
name: Rollback
on:
  workflow_dispatch:
    inputs:
      version:
        description: 'Version to rollback to'
        required: true

jobs:
  rollback:
    runs-on: ubuntu-latest
    steps:
      - name: Rollback deployment
        run: |
          # Deploy the specified previous version
          npx vercel rollback ${{ inputs.version }}

Environment Management

.env.example       → Committed (template for developers)
.env                → NOT committed (local development)
.env.test           → Committed (test environment, no real secrets)
CI secrets          → Stored in GitHub Secrets / vault
Production secrets  → Stored in deployment platform / vault

CI should never have production secrets. Use separate secrets for CI testing.

Automation Beyond CI

Dependabot / Renovate
# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: npm
    directory: /
    schedule:
      interval: weekly
    open-pull-requests-limit: 5
Build Cop Role

Designate someone responsible for keeping CI green. When the build breaks, the Build Cop's job is to fix or revert — not the person whose change caused the break. This prevents broken builds from accumulating while everyone assumes someone else will fix it.

PR Checks
  • Required reviews: At least 1 approval before merge
  • Required status checks: CI must pass before merge
  • Branch protection: No force-pushes to main
  • Auto-merge: If all checks pass and approved, merge automatically

CI Optimization

When the pipeline exceeds 10 minutes, apply these strategies in order of impact:

Slow CI pipeline?
├── Cache dependencies
│   └── Use actions/cache or setup-node cache option for node_modules
├── Run jobs in parallel
│   └── Split lint, typecheck, test, build into separate parallel jobs
├── Only run what changed
│   └── Use path filters to skip unrelated jobs (e.g., skip e2e for docs-only PRs)
├── Use matrix builds
│   └── Shard test suites across multiple runners
├── Optimize the test suite
│   └── Remove slow tests from the critical path, run them on a schedule instead
└── Use larger runners
    └── GitHub-hosted larger runners or self-hosted for CPU-heavy builds

Example: caching and parallelism

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '22', 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: '22', cache: 'npm' }
      - run: npm ci
      - run: npx tsc --noEmit

  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '22', cache: 'npm' }
      - run: npm ci
      - run: npm test -- --coverage

Common Rationalizations

Rationalization Reality
"CI is too slow" Optimize the pipeline (see CI Optimization below), don't skip it. A 5-minute pipeline prevents hours of debugging.
"This change is trivial, skip CI" Trivial changes break builds. CI is fast for trivial changes anyway.
"The test is flaky, just re-run" Flaky tests mask real bugs and waste everyone's time. Fix the flakiness.
"We'll add CI later" Projects without CI accumulate broken states. Set it up on day one.
"Manual testing is enough" Manual testing doesn't scale and isn't repeatable. Automate what you can.

Red Flags

  • No CI pipeline in the project
  • CI failures ignored or silenced
  • Tests disabled in CI to make the pipeline pass
  • Production deploys without staging verification
  • No rollback mechanism
  • Secrets stored in code or CI config files (not secrets manager)
  • Long CI times with no optimization effort

Verification

After setting up or modifying CI:

  • All quality gates are present (lint, types, tests, build, audit)
  • Pipeline runs on every PR and push to main
  • Failures block merge (branch protection configured)
  • CI results feed back into the development loop
  • Secrets are stored in the secrets manager, not in code
  • Deployment has a rollback mechanism
  • Pipeline runs in under 10 minutes for the test suite
1---
2name: ci-cd-and-automation
3description: Automates CI/CD pipeline setup. Use when setting up or modifying build and deployment pipelines. Use when you need to automate quality gates, configure test runners in CI, or establish deployment strategies.
4---
5 
6# CI/CD and Automation
7 
8## Overview
9 
10Automate quality gates so that no change reaches production without passing tests, lint, type checking, and build. CI/CD is the enforcement mechanism for every other skill — it catches what humans and agents miss, and it does so consistently on every single change.
11 
12**Shift Left:** Catch problems as early in the pipeline as possible. A bug caught in linting costs minutes; the same bug caught in production costs hours. Move checks upstream — static analysis before tests, tests before staging, staging before production.
13 
14**Faster is Safer:** Smaller batches and more frequent releases reduce risk, not increase it. A deployment with 3 changes is easier to debug than one with 30. Frequent releases build confidence in the release process itself.
15 
16## When to Use
17 
18- Setting up a new project's CI pipeline
19- Adding or modifying automated checks
20- Configuring deployment pipelines
21- When a change should trigger automated verification
22- Debugging CI failures
23 
24## The Quality Gate Pipeline
25 
26Every change goes through these gates before merge:
27 
28```
29Pull Request Opened
30 │
31 ▼
32┌─────────────────┐
33│ LINT CHECK │ eslint, prettier
34│ ↓ pass │
35│ TYPE CHECK │ tsc --noEmit
36│ ↓ pass │
37│ UNIT TESTS │ jest/vitest
38│ ↓ pass │
39│ BUILD │ npm run build
40│ ↓ pass │
41│ INTEGRATION │ API/DB tests
42│ ↓ pass │
43│ E2E (optional) │ Playwright/Cypress
44│ ↓ pass │
45│ SECURITY AUDIT │ npm audit
46│ ↓ pass │
47│ BUNDLE SIZE │ bundlesize check
48└─────────────────┘
49 │
50 ▼
51 Ready for review
52```
53 
54**No gate can be skipped.** If lint fails, fix lint — don't disable the rule. If a test fails, fix the code — don't skip the test.
55 
56## GitHub Actions Configuration
57 
58### Basic CI Pipeline
59 
60```yaml
61# .github/workflows/ci.yml
62name: CI
63 
64on:
65 pull_request:
66 branches: [main]
67 push:
68 branches: [main]
69 
70jobs:
71 quality:
72 runs-on: ubuntu-latest
73 steps:
74 - uses: actions/checkout@v4
75 
76 - uses: actions/setup-node@v4
77 with:
78 node-version: '22'
79 cache: 'npm'
80 
81 - name: Install dependencies
82 run: npm ci
83 
84 - name: Lint
85 run: npm run lint
86 
87 - name: Type check
88 run: npx tsc --noEmit
89 
90 - name: Test
91 run: npm test -- --coverage
92 
93 - name: Build
94 run: npm run build
95 
96 - name: Security audit
97 run: npm audit --audit-level=high
98```
99 
100### With Database Integration Tests
101 
102```yaml
103 integration:
104 runs-on: ubuntu-latest
105 services:
106 postgres:
107 image: postgres:16
108 env:
109 POSTGRES_DB: testdb
110 POSTGRES_USER: ci_user
111 POSTGRES_PASSWORD: ${{ secrets.CI_DB_PASSWORD }}
112 ports:
113 - 5432:5432
114 options: >-
115 --health-cmd pg_isready
116 --health-interval 10s
117 --health-timeout 5s
118 --health-retries 5
119 
120 steps:
121 - uses: actions/checkout@v4
122 - uses: actions/setup-node@v4
123 with:
124 node-version: '22'
125 cache: 'npm'
126 - run: npm ci
127 - name: Run migrations
128 run: npx prisma migrate deploy
129 env:
130 DATABASE_URL: postgresql://ci_user:${{ secrets.CI_DB_PASSWORD }}@localhost:5432/testdb
131 - name: Integration tests
132 run: npm run test:integration
133 env:
134 DATABASE_URL: postgresql://ci_user:${{ secrets.CI_DB_PASSWORD }}@localhost:5432/testdb
135```
136 
137> **Note:** Even for CI-only test databases, use GitHub Secrets for credentials rather than hardcoding values. This builds good habits and prevents accidental reuse of test credentials in other contexts.
138 
139### E2E Tests
140 
141```yaml
142 e2e:
143 runs-on: ubuntu-latest
144 steps:
145 - uses: actions/checkout@v4
146 - uses: actions/setup-node@v4
147 with:
148 node-version: '22'
149 cache: 'npm'
150 - run: npm ci
151 - name: Install Playwright
152 run: npx playwright install --with-deps chromium
153 - name: Build
154 run: npm run build
155 - name: Run E2E tests
156 run: npx playwright test
157 - uses: actions/upload-artifact@v4
158 if: failure()
159 with:
160 name: playwright-report
161 path: playwright-report/
162```
163 
164## Feeding CI Failures Back to Agents
165 
166The power of CI with AI agents is the feedback loop. When CI fails:
167 
168```
169CI fails
170 │
171 ▼
172Copy the failure output
173 │
174 ▼
175Feed it to the agent:
176"The CI pipeline failed with this error:
177[paste specific error]
178Fix the issue and verify locally before pushing again."
179 │
180 ▼
181Agent fixes → pushes → CI runs again
182```
183 
184**Key patterns:**
185 
186```
187Lint failure → Agent runs `npm run lint --fix` and commits
188Type error → Agent reads the error location and fixes the type
189Test failure → Agent follows debugging-and-error-recovery skill
190Build error → Agent checks config and dependencies
191```
192 
193## Deployment Strategies
194 
195### Preview Deployments
196 
197Every PR gets a preview deployment for manual testing:
198 
199```yaml
200# Deploy preview on PR (Vercel/Netlify/etc.)
201deploy-preview:
202 runs-on: ubuntu-latest
203 if: github.event_name == 'pull_request'
204 steps:
205 - uses: actions/checkout@v4
206 - name: Deploy preview
207 run: npx vercel --token=${{ secrets.VERCEL_TOKEN }}
208```
209 
210### Feature Flags
211 
212Feature flags decouple deployment from release. Deploy incomplete or risky features behind flags so you can:
213 
214- **Ship code without enabling it.** Merge to main early, enable when ready.
215- **Roll back without redeploying.** Disable the flag instead of reverting code.
216- **Canary new features.** Enable for 1% of users, then 10%, then 100%.
217- **Run A/B tests.** Compare behavior with and without the feature.
218 
219```typescript
220// Simple feature flag pattern
221if (featureFlags.isEnabled('new-checkout-flow', { userId })) {
222 return renderNewCheckout();
223}
224return renderLegacyCheckout();
225```
226 
227**Flag lifecycle:** Create → Enable for testing → Canary → Full rollout → Remove the flag and dead code. Flags that live forever become technical debt — set a cleanup date when you create them.
228 
229### Staged Rollouts
230 
231```
232PR merged to main
233 │
234 ▼
235 Staging deployment (auto)
236 │ Manual verification
237 ▼
238 Production deployment (manual trigger or auto after staging)
239 │
240 ▼
241 Monitor for errors (15-minute window)
242 │
243 ├── Errors detected → Rollback
244 └── Clean → Done
245```
246 
247### Rollback Plan
248 
249Every deployment should be reversible:
250 
251```yaml
252# Manual rollback workflow
253name: Rollback
254on:
255 workflow_dispatch:
256 inputs:
257 version:
258 description: 'Version to rollback to'
259 required: true
260 
261jobs:
262 rollback:
263 runs-on: ubuntu-latest
264 steps:
265 - name: Rollback deployment
266 run: |
267 # Deploy the specified previous version
268 npx vercel rollback ${{ inputs.version }}
269```
270 
271## Environment Management
272 
273```
274.env.example → Committed (template for developers)
275.env → NOT committed (local development)
276.env.test → Committed (test environment, no real secrets)
277CI secrets → Stored in GitHub Secrets / vault
278Production secrets → Stored in deployment platform / vault
279```
280 
281CI should never have production secrets. Use separate secrets for CI testing.
282 
283## Automation Beyond CI
284 
285### Dependabot / Renovate
286 
287```yaml
288# .github/dependabot.yml
289version: 2
290updates:
291 - package-ecosystem: npm
292 directory: /
293 schedule:
294 interval: weekly
295 open-pull-requests-limit: 5
296```
297 
298### Build Cop Role
299 
300Designate someone responsible for keeping CI green. When the build breaks, the Build Cop's job is to fix or revert — not the person whose change caused the break. This prevents broken builds from accumulating while everyone assumes someone else will fix it.
301 
302### PR Checks
303 
304- **Required reviews:** At least 1 approval before merge
305- **Required status checks:** CI must pass before merge
306- **Branch protection:** No force-pushes to main
307- **Auto-merge:** If all checks pass and approved, merge automatically
308 
309## CI Optimization
310 
311When the pipeline exceeds 10 minutes, apply these strategies in order of impact:
312 
313```
314Slow CI pipeline?
315├── Cache dependencies
316│ └── Use actions/cache or setup-node cache option for node_modules
317├── Run jobs in parallel
318│ └── Split lint, typecheck, test, build into separate parallel jobs
319├── Only run what changed
320│ └── Use path filters to skip unrelated jobs (e.g., skip e2e for docs-only PRs)
321├── Use matrix builds
322│ └── Shard test suites across multiple runners
323├── Optimize the test suite
324│ └── Remove slow tests from the critical path, run them on a schedule instead
325└── Use larger runners
326 └── GitHub-hosted larger runners or self-hosted for CPU-heavy builds
327```
328 
329**Example: caching and parallelism**
330```yaml
331jobs:
332 lint:
333 runs-on: ubuntu-latest
334 steps:
335 - uses: actions/checkout@v4
336 - uses: actions/setup-node@v4
337 with: { node-version: '22', cache: 'npm' }
338 - run: npm ci
339 - run: npm run lint
340 
341 typecheck:
342 runs-on: ubuntu-latest
343 steps:
344 - uses: actions/checkout@v4
345 - uses: actions/setup-node@v4
346 with: { node-version: '22', cache: 'npm' }
347 - run: npm ci
348 - run: npx tsc --noEmit
349 
350 test:
351 runs-on: ubuntu-latest
352 steps:
353 - uses: actions/checkout@v4
354 - uses: actions/setup-node@v4
355 with: { node-version: '22', cache: 'npm' }
356 - run: npm ci
357 - run: npm test -- --coverage
358```
359 
360## Common Rationalizations
361 
362| Rationalization | Reality |
363|---|---|
364| "CI is too slow" | Optimize the pipeline (see CI Optimization below), don't skip it. A 5-minute pipeline prevents hours of debugging. |
365| "This change is trivial, skip CI" | Trivial changes break builds. CI is fast for trivial changes anyway. |
366| "The test is flaky, just re-run" | Flaky tests mask real bugs and waste everyone's time. Fix the flakiness. |
367| "We'll add CI later" | Projects without CI accumulate broken states. Set it up on day one. |
368| "Manual testing is enough" | Manual testing doesn't scale and isn't repeatable. Automate what you can. |
369 
370## Red Flags
371 
372- No CI pipeline in the project
373- CI failures ignored or silenced
374- Tests disabled in CI to make the pipeline pass
375- Production deploys without staging verification
376- No rollback mechanism
377- Secrets stored in code or CI config files (not secrets manager)
378- Long CI times with no optimization effort
379 
380## Verification
381 
382After setting up or modifying CI:
383 
384- [ ] All quality gates are present (lint, types, tests, build, audit)
385- [ ] Pipeline runs on every PR and push to main
386- [ ] Failures block merge (branch protection configured)
387- [ ] CI results feed back into the development loop
388- [ ] Secrets are stored in the secrets manager, not in code
389- [ ] Deployment has a rollback mechanism
390- [ ] Pipeline runs in under 10 minutes for the test suite
391 

Discussion

Alternatives

Also in CI/CD & releasesSee all 533 in Development →