refactor(ci): split monolithic pipeline into per-package pipelines
Some checks failed
ci/woodpecker/push/infra Pipeline failed
ci/woodpecker/push/api Pipeline failed
ci/woodpecker/push/web Pipeline failed
ci/woodpecker/push/coordinator Pipeline failed
ci/woodpecker/push/orchestrator Pipeline failed

Replace single build.yml with split pipelines per the CI/CD guide:
- api.yml: API with postgres, prisma, Trivy scan
- web.yml: Web with Trivy scan
- orchestrator.yml: Orchestrator with Trivy scan
- coordinator.yml: Python with ruff/mypy/bandit/pip-audit/Trivy
- infra.yml: postgres + openbao builds with Trivy

Adds path filtering (only affected packages rebuild), Trivy container
scanning for all images, and scoped per-package quality gates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jason Woltje
2026-02-12 10:29:53 -06:00
parent e368083e84
commit 5a35fd69bc
7 changed files with 1038 additions and 455 deletions

View File

@@ -1,120 +1,142 @@
# Woodpecker CI Configuration for Mosaic Stack
## Pipeline Architecture
Split per-package pipelines with path filtering. Only affected packages rebuild on push.
```
.woodpecker/
├── api.yml # @mosaic/api (NestJS)
├── web.yml # @mosaic/web (Next.js)
├── orchestrator.yml # @mosaic/orchestrator (NestJS)
├── coordinator.yml # mosaic-coordinator (Python/FastAPI)
├── infra.yml # postgres + openbao Docker images
├── codex-review.yml # AI code/security review (PRs only)
├── README.md
└── schemas/
├── code-review-schema.json
└── security-review-schema.json
```
## Path Filtering
| Pipeline | Triggers On |
| ------------------ | --------------------------------------------------- |
| `api.yml` | `apps/api/**`, `packages/**`, root configs |
| `web.yml` | `apps/web/**`, `packages/**`, root configs |
| `orchestrator.yml` | `apps/orchestrator/**`, `packages/**`, root configs |
| `coordinator.yml` | `apps/coordinator/**` |
| `infra.yml` | `docker/**` |
| `codex-review.yml` | All PRs (no path filter) |
**Root configs** = `pnpm-lock.yaml`, `pnpm-workspace.yaml`, `turbo.json`, `package.json`
## Security Chain
Every pipeline follows the full security chain required by the CI/CD guide:
```
source scanning (lint + pnpm audit / bandit + pip-audit)
-> docker build (Kaniko)
-> container scanning (Trivy: HIGH,CRITICAL)
-> package linking (Gitea registry)
```
Docker builds gate on ALL quality + security steps passing.
## Pipeline Dependency Graphs
### Node.js Apps (api, web, orchestrator)
```
install -> [security-audit, lint, prisma-generate*]
prisma-generate* -> [typecheck, prisma-migrate*]
prisma-migrate* -> test
[all quality gates] -> build -> docker-build -> trivy -> link
```
_\*prisma steps: api.yml only_
### Coordinator (Python)
```
install -> [ruff-check, mypy, security-bandit, security-pip-audit, test]
[all quality gates] -> docker-build -> trivy -> link
```
### Infrastructure
```
[docker-build-postgres, docker-build-openbao]
-> [trivy-postgres, trivy-openbao]
-> link
```
## Docker Images
| Image | Registry Path | Context |
| ------------------ | ----------------------------------------------- | ------------------- |
| stack-api | `git.mosaicstack.dev/mosaic/stack-api` | `.` (monorepo root) |
| stack-web | `git.mosaicstack.dev/mosaic/stack-web` | `.` (monorepo root) |
| stack-orchestrator | `git.mosaicstack.dev/mosaic/stack-orchestrator` | `.` (monorepo root) |
| stack-coordinator | `git.mosaicstack.dev/mosaic/stack-coordinator` | `apps/coordinator` |
| stack-postgres | `git.mosaicstack.dev/mosaic/stack-postgres` | `docker/postgres` |
| stack-openbao | `git.mosaicstack.dev/mosaic/stack-openbao` | `docker/openbao` |
## Image Tagging
| Condition | Tag | Purpose |
| ---------------- | -------------------------- | -------------------------- |
| Always | `${CI_COMMIT_SHA:0:8}` | Immutable commit reference |
| `main` branch | `latest` | Current production release |
| `develop` branch | `dev` | Current development build |
| Git tag | tag value (e.g., `v1.0.0`) | Semantic version release |
## Required Secrets
Configure in Woodpecker UI (Settings > Secrets):
| Secret | Scope | Purpose |
| ---------------- | ----------------- | ------------------------------------------- |
| `gitea_username` | push, manual, tag | Gitea registry auth |
| `gitea_token` | push, manual, tag | Gitea registry auth (`package:write` scope) |
| `codex_api_key` | pull_request | Codex AI reviews |
## Codex AI Review Pipeline
This directory contains the Codex AI review pipeline configuration for automated code and security reviews on pull requests.
The `codex-review.yml` pipeline runs independently on all PRs:
### Setup
- **Code review**: Correctness, code quality, testing, performance
- **Security review**: OWASP Top 10, hardcoded secrets, injection flaws
1. **Add Codex API key to Woodpecker:**
- Go to mosaic-stack repo at `https://ci.mosaicstack.dev`
- Settings → Secrets
- Add secret: `codex_api_key` with your OpenAI API key
2. **Enable the pipeline:**
- The `codex-review.yml` pipeline will automatically run on all PRs
- The main `.woodpecker.yml` handles primary CI tasks
- This codex pipeline is independent and focused solely on reviews
### What Gets Reviewed
**Code Review (`code-review` step):**
- Correctness — logic errors, edge cases, error handling
- Code Quality — complexity, duplication, naming
- Testing — coverage, test quality
- Performance — N+1 queries, blocking ops
- Dependencies — deprecated packages
- Documentation — comments, API docs
**Security Review (`security-review` step):**
- OWASP Top 10 vulnerabilities
- Hardcoded secrets/credentials
- Injection flaws (SQL, NoSQL, OS command)
- XSS, CSRF, SSRF
- Auth/authz gaps
- Data exposure in logs
### Pipeline Behavior
- **Triggers:** Every pull request
- **Runs:** Code review + Security review in parallel
- **Fails if:**
- Code review finds **blockers**
- Security review finds **critical** or **high** severity issues
- **Outputs:** Structured JSON results in CI logs
Fails on blockers or critical/high severity security findings.
### Local Testing
Test the review scripts locally before pushing:
```bash
# Code review of uncommitted changes
~/.claude/scripts/codex/codex-code-review.sh --uncommitted
# Security review of uncommitted changes
~/.claude/scripts/codex/codex-security-review.sh --uncommitted
# Code review against main branch
~/.claude/scripts/codex/codex-code-review.sh -b main
# Security review and save JSON
~/.claude/scripts/codex/codex-security-review.sh -b main -o security.json
```
### Schema Files
## Troubleshooting
The `schemas/` directory contains JSON schemas that enforce structured output from Codex:
### "unauthorized: authentication required"
- `code-review-schema.json` — Defines output for code quality reviews
- `security-review-schema.json` — Defines output for security reviews
- Verify `gitea_username` and `gitea_token` secrets in Woodpecker
- Verify token has `package:write` scope
These schemas ensure consistent, machine-readable findings that the CI pipeline can parse and fail on.
### Trivy scan fails with HIGH/CRITICAL
### Integration with Main Pipeline
- Check if the vulnerability is in the base image (not our code)
- Add to `.trivyignore` if it's a known, accepted risk
- Use `--ignore-unfixed` (already set) to skip unfixable CVEs
The main `.woodpecker.yml` in the repo root handles:
### Package linking returns 404
- Type checking (TypeScript)
- Linting (ESLint)
- Unit tests (Vitest)
- Integration tests (Playwright)
- Docker image builds
- Normal for recently pushed packages — retry logic handles this
- If persistent: verify package name matches exactly (case-sensitive)
This `codex-review.yml` is independent and focuses solely on:
### Pipeline runs Docker builds on pull requests
- AI-powered code quality review
- AI-powered security vulnerability scanning
Both pipelines run in parallel on PRs.
### Troubleshooting
**Pipeline fails with "codex: command not found"**
- Check that the node image in `codex-review.yml` matches a version with npm
- Current: `node:22-slim`
**Pipeline fails with auth errors**
- Verify `codex_api_key` secret is set in Woodpecker
- Test the key locally: `CODEX_API_KEY=<key> codex exec "test"`
**Pipeline passes but should fail**
- Check the failure conditions in `codex-review.yml`
- Current thresholds: blockers, critical, or high findings
## Files
| File | Purpose |
| ------------------------------------- | -------------------------------------- |
| `codex-review.yml` | Codex AI review pipeline configuration |
| `schemas/code-review-schema.json` | Code review output schema |
| `schemas/security-review-schema.json` | Security review output schema |
| `README.md` | This file |
## Parent CI Pipeline
The main `.woodpecker.yml` is located at the repository root and handles all build/test tasks.
- Docker build steps have `when: branch: [main, develop]` guards
- PRs only run quality gates, not Docker builds