The lint and typecheck steps fail because @mosaic/shared isn't built. Add a build-shared step that compiles the shared package before lint and typecheck run, both of which now depend on build-shared in addition to prisma-generate. Fixes #364 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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
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_usernameandgitea_tokensecrets in Woodpecker - Verify token has
package:writescope
Trivy scan fails with HIGH/CRITICAL
- Check if the vulnerability is in the base image (not our code)
- Add to
.trivyignoreif 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, develop]guards - PRs only run quality gates, not Docker builds