# Ci Cd

> Builds a GitHub Actions merge gate for the app stack — parallel backend/frontend jobs that run manage.py check, makemigrations --check --dry-run (fail on model drift), pytest, ruff lint, tsc typecheck, and pnpm build, with cached deps and required status checks blocking red PRs. Use when adding or fixing a workflow under .github/workflows, wiring CI for Django/DRF plus Next.js, catching migration…

- **Type:** Skill
- **Install:** `agentstack add skill-deadlymind-nanolama-ci-cd`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [Deadlymind](https://agentstack.voostack.com/s/deadlymind)
- **Installs:** 0
- **Category:** [Cloud & Infrastructure](https://agentstack.voostack.com/c/cloud-infrastructure)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [Deadlymind](https://github.com/Deadlymind)
- **Source:** https://github.com/Deadlymind/nanolama/tree/main/skills/ci-cd

## Install

```sh
agentstack add skill-deadlymind-nanolama-ci-cd
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# CI/CD (GitHub Actions merge gate)

## When to use
Setting up or repairing the pipeline that must go green before any branch merges to
`main`. On this stack the gate has one job: refuse to merge a branch that fails a
static check, drifts from its migrations, breaks a test, or won't build.

## Pattern
**Fail closed at the PR boundary.** Split backend and frontend into parallel jobs,
cache their dependency stores, and make each check a distinct step so a red run points
at the exact failure. The migration-drift check (`makemigrations --check --dry-run`)
is the one people forget — it catches models edited without a migration, which passes
locally but breaks deploy. Mark every job a **required status check** in branch
protection so a red pipeline blocks merge instead of merely warning.

## Steps / idioms
1. One workflow, two jobs. Backend job (Postgres service, `manage.py check`, drift,
   pytest, ruff) and frontend job (`tsc`, `pnpm build`) run in parallel:

   ```yaml
   # .github/workflows/ci.yml
   name: CI
   on:
     pull_request: { branches: [main] }
     push: { branches: [main] }
   jobs:
     backend:
       runs-on: ubuntu-latest
       services:
         postgres:
           image: postgres:17
           env: { POSTGRES_PASSWORD: postgres, POSTGRES_DB: app }
           ports: ["5432:5432"]
           options: >-
             --health-cmd pg_isready --health-interval 10s --health-retries 5
       env:
         DATABASE_URL: postgres://postgres:postgres@localhost:5432/app
       steps:
         - uses: actions/checkout@v4
         - uses: actions/setup-python@v5
           with: { python-version: "3.12", cache: pip }  # cache the wheel dir
         - run: pip install -r requirements.txt
         - run: python manage.py check                     # settings/app sanity
         - run: python manage.py makemigrations --check --dry-run  # fail on drift
         - run: ruff check .                               # lint (non-zero fails job)
         - run: pytest -q                                  # Django/DRF tests
         - run: pip-audit                                  # dependency-audit gate

     frontend:
       runs-on: ubuntu-latest
       defaults: { run: { working-directory: web } }
       steps:
         - uses: actions/checkout@v4
         - uses: pnpm/action-setup@v4
           with: { version: 9 }
         - uses: actions/setup-node@v4
           with: { node-version: "20", cache: pnpm, cache-dependency-path: web/pnpm-lock.yaml }
         - run: pnpm install --frozen-lockfile
         - run: pnpm tsc --noEmit                          # typecheck, no output
         - run: pnpm build                                 # Next.js production build
   ```

2. **Block merge on red.** In repo Settings → Branches → protect `main`: require
   the `backend` and `frontend` checks to pass and require branches be up to date.
   A green-only merge button is what actually enforces the gate; the YAML alone does not.
3. **Keep steps granular.** Separate `ruff check` from `pytest` so the summary names
   the failure. Add `ruff format --check .` if you enforce formatting.
4. **Audit dependencies in CI.** `pip-audit` (Python) and `pnpm audit --prod` (Node)
   flag known-vuln packages on every PR (see `dependency-audit`).

## Security & hardening gates
Add security checks as their own required jobs (GitHub Actions), each failing the build
on **high severity** so a vuln can't merge:
- **SAST.** Run `bandit -r . -ll` for Python, plus `semgrep` (or CodeQL) with the
  Django/DRF and React rulesets for injection, XSS, and unsafe-deserialization patterns.
- **Secret scan.** Run `gitleaks detect` over both the diff and history — a secret in an
  old commit is still leaked. Fail on any finding, not just new ones.
- **Deploy sanity.** Run `python manage.py check --deploy` to catch insecure settings
  (`DEBUG`, weak `SECRET_KEY`, missing HSTS/cookie flags) before they ship.

Then harden the workflow itself — the pipeline is attackable too:
- **Pin actions to a commit SHA**, not a moving tag: `uses: actions/checkout@`.
  A tag like `@v4` can be re-pointed at malicious code; a SHA can't.
- **Least-privilege token.** Set `permissions: { contents: read }` at the workflow level
  and widen per-job only where needed (e.g. `pull-requests: write` for a comment step).
- **Bound and dedupe runs.** Give each job a `timeout-minutes:` so a hung step can't run
  for hours, and add a top-level `concurrency: { group: ci-${{ github.ref }},
  cancel-in-progress: true }` to cancel superseded runs on the same branch.

Mark each security job a **required status check** in branch protection so it blocks
merge — the same gate discipline as the test jobs (see `security-review`).

## Adapt to your repo
Rename the frontend dir (`web`), the Postgres image tag (16/17/18 all run Django 5.2),
and the Python/Node versions to match your project. If you use Poetry or uv, swap the
install step and its cache key. Point `cache-dependency-path` at your real lockfile.
Match the required-check names in branch protection to your actual job names, or the
gate silently passes. If a job needs secrets (RDS, S3), inject them via repository
secrets — never commit them.

## Gotchas
- `makemigrations --check --dry-run` exits non-zero **only** when a migration is
  missing — it is the drift guard; running plain `makemigrations` in CI would instead
  write files and hide the problem (see `migrations`).
- A cache alone doesn't install — you still run `pip install` / `pnpm install`; the
  cache only skips the download. `--frozen-lockfile` fails if the lockfile is stale.
- `pnpm build` needs any build-time env vars (`NEXT_PUBLIC_*`) present, or the build
  errors on missing config — set them as non-secret env in the job.
- Branch protection is per-branch and per-check-name; a renamed job silently stops
  being required until you re-add it. Verify a red PR is actually unmergeable.
- Deploy is a separate workflow triggered after this one is green — keep it here or
  see `deploy-aws`; don't couple test steps to deploy credentials.

## See also
- `deploy-aws`
- `write-tests`
- `migrations`
- `dependency-audit`
- `security-review`
- `version-check`

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [Deadlymind](https://github.com/Deadlymind)
- **Source:** [Deadlymind/nanolama](https://github.com/Deadlymind/nanolama)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-deadlymind-nanolama-ci-cd
- Seller: https://agentstack.voostack.com/s/deadlymind
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
