Files
Jason Woltje 5e7346adc7
Some checks failed
ci/woodpecker/push/ci Pipeline failed
ci/woodpecker/manual/infra Pipeline failed
ci/woodpecker/manual/coordinator Pipeline was successful
ci/woodpecker/manual/ci Pipeline was successful
ci: unify pipelines — single install, ~50% faster CI (#588)
Co-authored-by: Jason Woltje <jason@diversecanvas.com>
Co-committed-by: Jason Woltje <jason@diversecanvas.com>
2026-03-01 02:32:54 +00:00
..

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 latest 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

The codex-review.yml pipeline runs independently on all PRs:

  • Code review: Correctness, code quality, testing, performance
  • Security review: OWASP Top 10, hardcoded secrets, injection flaws

Fails on blockers or critical/high severity security findings.

Local Testing

~/.claude/scripts/codex/codex-code-review.sh --uncommitted
~/.claude/scripts/codex/codex-security-review.sh --uncommitted

Troubleshooting

"unauthorized: authentication required"

  • Verify gitea_username and gitea_token secrets in Woodpecker
  • Verify token has package:write scope

Trivy scan fails with HIGH/CRITICAL

  • 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

Package linking returns 404

  • Normal for recently pushed packages — retry logic handles this
  • If persistent: verify package name matches exactly (case-sensitive)

Pipeline runs Docker builds on pull requests

  • Docker build steps have when: branch: [main] guards
  • PRs only run quality gates, not Docker builds