Modh
AboutServicesWorkPlaybookResourcesBook a call
Book a call
Agent Skills/Workflow / Process/CI Pipeline Standards
Workflow / Processintermediate4 min

workflow CI Pipeline Standards

Enforce CI pipeline conventions. Use when adding CI checks, modifying GitHub Actions workflows, or discussing CI vs deployment. Prevents deployment steps in CI and ensures the extensible step pattern is followed.

Install this skill

git submodule add https://github.com/modh-labs/playbook.git .playbook

One submodule installs all 17 skills. Reference .playbook/skills/ci-pipeline/SKILL.md from your AGENTS.md.


CI Pipeline Skill

When This Skill Activates

This skill automatically activates when you:

  • Add or modify CI checks or steps
  • Edit GitHub Actions workflow files
  • Edit CI orchestration scripts
  • Discuss deployment in the context of CI
  • Add a new linting, testing, or validation step

Architecture: CI vs Deployment

CI Pipeline (GitHub Actions / CI service)  ->  Quality gate ONLY
Deployment Platform (Vercel, Railway, etc.)  ->  All deployments

NEVER add deployment commands to CI. Your deployment platform handles deployment automatically via Git integration or its own pipeline. CI is exclusively for quality checks.

Core Rules

1. Use an Extensible Step Pattern for New CI Checks

All CI steps should go in a central orchestration script (e.g., scripts/ci.sh) using a consistent step runner:

# Example: run_step function in scripts/ci.sh
run_step "My New Check" ./scripts/my-check.sh

# NOT inline in package.json
"ci": "... && ./scripts/my-check.sh && ..."

If your project uses a different pattern (Makefile, Turborepo pipeline, etc.), follow the existing convention. The principle is the same: one place to add steps, not scattered across config files.

2. Order Steps Cheapest-First

Steps run sequentially and fail fast. Put fast/cheap checks before slow/expensive ones:

1. Lint & Format (seconds)        <- cheapest
2. Convention checks (seconds)
3. Migration Safety Check (seconds)
4. TypeScript Typecheck (minutes)
5. Tests (minutes)                <- most expensive

3. Mirror Steps in GitHub Actions

Every step in your CI orchestration MUST have a corresponding step in the GitHub Actions workflow with:

  • A descriptive name: matching the step name
  • An id: for summary reporting
  • The same command
# CORRECT
- name: "My New Check"
  id: my-check
  run: ./scripts/my-check.sh

# WRONG -- missing id
- name: "My New Check"
  run: ./scripts/my-check.sh

4. Update the Summary Step

When adding a new check, add it to the summary step in the workflow:

echo "| My New Check | ${{ steps.my-check.outcome == 'failure' && 'FAIL' || 'PASS' }} |" >> $GITHUB_STEP_SUMMARY

5. NEVER Add Deployments to CI

# WRONG -- deployment in GitHub Actions
- name: Deploy to Production
  run: vercel --prod

# WRONG -- deploy script in CI
run_step "Deploy" npm run deploy

Deployment is handled by your deployment platform, not CI.

Performance Rules

Use efficient file searches in lint scripts

# WRONG -- walks into node_modules then filters (25s)
find . -name "X" -not -path "*/node_modules/*"

# RIGHT -- never enters node_modules at all (0.3s)
find . \( -path "*/node_modules" -o -path "*/.next" \) -prune -o -name "X" -print

Enable incremental compilation

All tsconfig.json files MUST include "incremental": true for faster subsequent builds:

{
  "compilerOptions": {
    "incremental": true
  }
}

Enable build caching

If using a build orchestrator (Turborepo, Nx, etc.), enable caching for CI-related tasks.

NEVER Rules

  • NEVER add deploy commands (vercel deploy, railway up, etc.) to CI
  • NEVER push directly to production branches without merging from the main branch first
  • NEVER add deployment-related secrets (deploy tokens, etc.) to CI workflows
  • NEVER inline new checks in package.json scripts -- use the orchestration script
  • NEVER put expensive checks before cheap ones
  • NEVER skip step IDs in GitHub Actions workflow steps
  • NEVER use continue-on-error: true on quality gate steps (defeats the purpose)
  • NEVER use find -not -path to exclude directories -- use -prune instead
  • NEVER create a tsconfig.json without "incremental": true

Adding a New CI Step -- Checklist

  1. Create the check script (e.g., scripts/my-check.sh) or identify the command
  2. Add the step to your CI orchestration script in the correct position (cheapest-first)
  3. Add a matching step with id: to the GitHub Actions workflow
  4. Add the step to the summary in the workflow
  5. Update CI documentation if it exists
  6. Test locally by running the full CI command

Key Files (Adapt to Your Project)

FilePurpose
scripts/ci.shCI orchestration script (source of truth for steps)
.github/workflows/ci.ymlGitHub Actions workflow (mirrors steps for PR visibility)
CI documentationExplains the architecture and step ordering

Related Skills

workflow

Background Job Right Sizing

Choose the LIGHTEST durable mechanism a background/async/side-effect job actually needs, instead of reaching for a full workflow engine by reflex. A four-rung ladder — in-process fire-and-forget → durable queue → workflow engine → dedicated orchestrator — routed by four axes: durability, step count, concurrency shape, and cross-app/bus membership. Activates when adding any background job, emitting a side-effect from a request handler, choosing between Vercel Queues / Workflows / Inngest / Temporal / SQS, or auditing an existing job fleet for over-engineering ("do we still need the orchestrator for this?").

Workflow / Process
workflow

Bug Cleanup Triage

Framework for backlog bug cleanup sessions. Triage is three sequential activities — Linear hygiene, root-cause investigation, and code fixing — that must be executed in order as a hard phase gate. Includes git log pre-flight, Sentry module-tag verification, and umbrella breakdown auto-detection. Use when planning to clean up N bugs from a backlog, before dispatching research agents, or when a ticket has been In Progress for weeks without shipping.

Workflow / Process
workflow

Control Flow Exceptions

Some "errors" are control flow, not failures. `redirect()` and `notFound()` in Next.js work by THROWING — a naive `try/catch` swallows the signal, cancels the navigation, and renders the internal digest string ("NEXT_REDIRECT;...") to the user. Any `catch` block wrapping code that might redirect MUST call `unstable_rethrow(error)` as its first line. Triggers on `try/catch` around a server action, Server Component, or route handler in Next.js App Router.

Workflow / Process
←Back to Agent Skills