All checks were successful
Remove develop branch references from CI, compose, env, and docs now that all development uses trunk-based workflow on main. - CI: remove develop branch filters and dev tag logic - Compose: default IMAGE_TAG from dev to latest - Env: update IMAGE_TAG default and comments - Docs: update branching strategy, PR targets, and image tag docs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
203 lines
5.3 KiB
YAML
203 lines
5.3 KiB
YAML
# Web Pipeline - Mosaic Stack
|
|
# Quality gates, build, and Docker publish for @mosaic/web
|
|
#
|
|
# Triggers on: apps/web/**, packages/**, root configs
|
|
# Security chain: source audit + Trivy container scan
|
|
|
|
when:
|
|
- event: [push, pull_request, manual]
|
|
path:
|
|
include:
|
|
- "apps/web/**"
|
|
- "packages/**"
|
|
- "pnpm-lock.yaml"
|
|
- "pnpm-workspace.yaml"
|
|
- "turbo.json"
|
|
- "package.json"
|
|
- ".woodpecker/web.yml"
|
|
- ".trivyignore"
|
|
|
|
variables:
|
|
- &node_image "node:24-alpine"
|
|
- &install_deps |
|
|
corepack enable
|
|
pnpm install --frozen-lockfile
|
|
- &use_deps |
|
|
corepack enable
|
|
- &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: *node_image
|
|
commands:
|
|
- *install_deps
|
|
|
|
security-audit:
|
|
image: *node_image
|
|
commands:
|
|
- *use_deps
|
|
- pnpm audit --audit-level=high
|
|
depends_on:
|
|
- install
|
|
|
|
build-shared:
|
|
image: *node_image
|
|
environment:
|
|
SKIP_ENV_VALIDATION: "true"
|
|
commands:
|
|
- *use_deps
|
|
- pnpm --filter "@mosaic/shared" build
|
|
- pnpm --filter "@mosaic/ui" build
|
|
depends_on:
|
|
- install
|
|
|
|
lint:
|
|
image: *node_image
|
|
environment:
|
|
SKIP_ENV_VALIDATION: "true"
|
|
commands:
|
|
- *use_deps
|
|
- pnpm --filter "@mosaic/web" lint
|
|
depends_on:
|
|
- build-shared
|
|
|
|
typecheck:
|
|
image: *node_image
|
|
environment:
|
|
SKIP_ENV_VALIDATION: "true"
|
|
commands:
|
|
- *use_deps
|
|
- pnpm --filter "@mosaic/web" typecheck
|
|
depends_on:
|
|
- build-shared
|
|
|
|
test:
|
|
image: *node_image
|
|
environment:
|
|
SKIP_ENV_VALIDATION: "true"
|
|
commands:
|
|
- *use_deps
|
|
- pnpm --filter "@mosaic/web" test
|
|
depends_on:
|
|
- build-shared
|
|
|
|
# === Build ===
|
|
|
|
build:
|
|
image: *node_image
|
|
environment:
|
|
SKIP_ENV_VALIDATION: "true"
|
|
NODE_ENV: "production"
|
|
commands:
|
|
- *use_deps
|
|
- pnpm turbo build --filter=@mosaic/web
|
|
depends_on:
|
|
- lint
|
|
- typecheck
|
|
- test
|
|
- security-audit
|
|
|
|
# === Docker Build & Push ===
|
|
|
|
docker-build-web:
|
|
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}
|
|
commands:
|
|
- *kaniko_setup
|
|
- |
|
|
DESTINATIONS=""
|
|
if [ -n "$CI_COMMIT_TAG" ]; then
|
|
DESTINATIONS="--destination git.mosaicstack.dev/mosaic/stack-web:$CI_COMMIT_TAG"
|
|
elif [ "$CI_COMMIT_BRANCH" = "main" ]; then
|
|
DESTINATIONS="--destination git.mosaicstack.dev/mosaic/stack-web:latest"
|
|
fi
|
|
/kaniko/executor --context . --dockerfile apps/web/Dockerfile --snapshot-mode=redo --build-arg NEXT_PUBLIC_API_URL=https://api.mosaicstack.dev $DESTINATIONS
|
|
when:
|
|
- branch: [main]
|
|
event: [push, manual, tag]
|
|
depends_on:
|
|
- build
|
|
|
|
# === Container Security Scan ===
|
|
|
|
security-trivy-web:
|
|
image: aquasec/trivy:latest
|
|
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}
|
|
commands:
|
|
- |
|
|
if [ -n "$$CI_COMMIT_TAG" ]; then
|
|
SCAN_TAG="$$CI_COMMIT_TAG"
|
|
elif [ "$$CI_COMMIT_BRANCH" = "main" ]; then
|
|
SCAN_TAG="latest"
|
|
else
|
|
SCAN_TAG="latest"
|
|
fi
|
|
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 \
|
|
--ignorefile .trivyignore \
|
|
git.mosaicstack.dev/mosaic/stack-web:$$SCAN_TAG
|
|
when:
|
|
- branch: [main]
|
|
event: [push, manual, tag]
|
|
depends_on:
|
|
- docker-build-web
|
|
|
|
# === 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-web"
|
|
when:
|
|
- branch: [main]
|
|
event: [push, manual, tag]
|
|
depends_on:
|
|
- security-trivy-web
|