refactor(ci): split monolithic pipeline into per-package pipelines
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:
172
.woodpecker/coordinator.yml
Normal file
172
.woodpecker/coordinator.yml
Normal file
@@ -0,0 +1,172 @@
|
||||
# Coordinator Pipeline - Mosaic Stack
|
||||
# Quality gates, build, and Docker publish for mosaic-coordinator (Python)
|
||||
#
|
||||
# Triggers on: apps/coordinator/**
|
||||
# Security chain: bandit + pip-audit + Trivy container scan
|
||||
|
||||
when:
|
||||
- event: [push, pull_request, manual]
|
||||
path:
|
||||
include:
|
||||
- "apps/coordinator/**"
|
||||
- ".woodpecker/coordinator.yml"
|
||||
|
||||
variables:
|
||||
- &python_image "python:3.11-slim"
|
||||
- &activate_venv |
|
||||
cd apps/coordinator
|
||||
. venv/bin/activate
|
||||
- &kaniko_setup |
|
||||
mkdir -p /kaniko/.docker
|
||||
echo "{\"auths\":{\"git.mosaicstack.dev\":{\"username\":\"$GITEA_USER\",\"password\":\"$GITEA_TOKEN\"}}}" > /kaniko/.docker/config.json
|
||||
|
||||
steps:
|
||||
# === Quality Gates ===
|
||||
|
||||
install:
|
||||
image: *python_image
|
||||
commands:
|
||||
- cd apps/coordinator
|
||||
- python -m venv venv
|
||||
- . venv/bin/activate
|
||||
- pip install --no-cache-dir -e ".[dev]"
|
||||
- pip install --no-cache-dir bandit pip-audit
|
||||
|
||||
ruff-check:
|
||||
image: *python_image
|
||||
commands:
|
||||
- *activate_venv
|
||||
- ruff check src/ tests/
|
||||
depends_on:
|
||||
- install
|
||||
|
||||
mypy:
|
||||
image: *python_image
|
||||
commands:
|
||||
- *activate_venv
|
||||
- mypy src/
|
||||
depends_on:
|
||||
- install
|
||||
|
||||
security-bandit:
|
||||
image: *python_image
|
||||
commands:
|
||||
- *activate_venv
|
||||
- bandit -r src/ -f screen
|
||||
depends_on:
|
||||
- install
|
||||
|
||||
security-pip-audit:
|
||||
image: *python_image
|
||||
commands:
|
||||
- *activate_venv
|
||||
- pip-audit
|
||||
depends_on:
|
||||
- install
|
||||
|
||||
test:
|
||||
image: *python_image
|
||||
commands:
|
||||
- *activate_venv
|
||||
- pytest
|
||||
depends_on:
|
||||
- install
|
||||
|
||||
# === Docker Build & Push ===
|
||||
|
||||
docker-build-coordinator:
|
||||
image: gcr.io/kaniko-project/executor:debug
|
||||
environment:
|
||||
GITEA_USER:
|
||||
from_secret: gitea_username
|
||||
GITEA_TOKEN:
|
||||
from_secret: gitea_token
|
||||
CI_COMMIT_BRANCH: ${CI_COMMIT_BRANCH}
|
||||
CI_COMMIT_TAG: ${CI_COMMIT_TAG}
|
||||
CI_COMMIT_SHA: ${CI_COMMIT_SHA}
|
||||
commands:
|
||||
- *kaniko_setup
|
||||
- |
|
||||
DESTINATIONS="--destination git.mosaicstack.dev/mosaic/stack-coordinator:${CI_COMMIT_SHA:0:8}"
|
||||
if [ "$CI_COMMIT_BRANCH" = "main" ]; then
|
||||
DESTINATIONS="$DESTINATIONS --destination git.mosaicstack.dev/mosaic/stack-coordinator:latest"
|
||||
elif [ "$CI_COMMIT_BRANCH" = "develop" ]; then
|
||||
DESTINATIONS="$DESTINATIONS --destination git.mosaicstack.dev/mosaic/stack-coordinator:dev"
|
||||
fi
|
||||
if [ -n "$CI_COMMIT_TAG" ]; then
|
||||
DESTINATIONS="$DESTINATIONS --destination git.mosaicstack.dev/mosaic/stack-coordinator:$CI_COMMIT_TAG"
|
||||
fi
|
||||
/kaniko/executor --context apps/coordinator --dockerfile apps/coordinator/Dockerfile $DESTINATIONS
|
||||
when:
|
||||
- branch: [main, develop]
|
||||
event: [push, manual, tag]
|
||||
depends_on:
|
||||
- ruff-check
|
||||
- mypy
|
||||
- security-bandit
|
||||
- security-pip-audit
|
||||
- test
|
||||
|
||||
# === Container Security Scan ===
|
||||
|
||||
security-trivy-coordinator:
|
||||
image: aquasec/trivy:latest
|
||||
environment:
|
||||
GITEA_USER:
|
||||
from_secret: gitea_username
|
||||
GITEA_TOKEN:
|
||||
from_secret: gitea_token
|
||||
CI_COMMIT_SHA: ${CI_COMMIT_SHA}
|
||||
commands:
|
||||
- |
|
||||
mkdir -p ~/.docker
|
||||
echo "{\"auths\":{\"git.mosaicstack.dev\":{\"username\":\"$$GITEA_USER\",\"password\":\"$$GITEA_TOKEN\"}}}" > ~/.docker/config.json
|
||||
trivy image --exit-code 1 --severity HIGH,CRITICAL --ignore-unfixed \
|
||||
git.mosaicstack.dev/mosaic/stack-coordinator:$${CI_COMMIT_SHA:0:8}
|
||||
when:
|
||||
- branch: [main, develop]
|
||||
event: [push, manual, tag]
|
||||
depends_on:
|
||||
- docker-build-coordinator
|
||||
|
||||
# === Package Linking ===
|
||||
|
||||
link-packages:
|
||||
image: alpine:3
|
||||
environment:
|
||||
GITEA_TOKEN:
|
||||
from_secret: gitea_token
|
||||
commands:
|
||||
- apk add --no-cache curl
|
||||
- sleep 10
|
||||
- |
|
||||
set -e
|
||||
link_package() {
|
||||
PKG="$$1"
|
||||
echo "Linking $$PKG..."
|
||||
for attempt in 1 2 3; do
|
||||
STATUS=$$(curl -s -o /tmp/link-response.txt -w "%{http_code}" -X POST \
|
||||
-H "Authorization: token $$GITEA_TOKEN" \
|
||||
"https://git.mosaicstack.dev/api/v1/packages/mosaic/container/$$PKG/-/link/stack")
|
||||
if [ "$$STATUS" = "201" ] || [ "$$STATUS" = "204" ]; then
|
||||
echo " Linked $$PKG"
|
||||
return 0
|
||||
elif [ "$$STATUS" = "400" ]; then
|
||||
echo " $$PKG already linked"
|
||||
return 0
|
||||
elif [ "$$STATUS" = "404" ] && [ $$attempt -lt 3 ]; then
|
||||
echo " $$PKG not found yet, retrying in 5s (attempt $$attempt/3)..."
|
||||
sleep 5
|
||||
else
|
||||
echo " FAILED: $$PKG status $$STATUS"
|
||||
cat /tmp/link-response.txt
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
link_package "stack-coordinator"
|
||||
when:
|
||||
- branch: [main, develop]
|
||||
event: [push, manual, tag]
|
||||
depends_on:
|
||||
- security-trivy-coordinator
|
||||
Reference in New Issue
Block a user