platform-codebase/.gitlab-ci.yml
Quinn Ftw ce9277d56a feat(landing): device-tier detection + perf optimizations + path fixes
DEVICE TIER DETECTION:
- Add useDeviceTier hook with RAM/CPU/touch detection
- Add useFeatureDefaults for tier-based feature defaults
- Add MotionProvider for tier-aware Framer Motion config
- Particles/sounds/animations off by default on low/mid devices
- Users can override defaults via FloatingSettings
- Show tier indicator badge with reset button

PERFORMANCE:
- Lazy load routes (non-home pages load on navigation)
- Lazy load decorative components (AIBackground, ParticleTrail)
- Add RouteLoadingSkeleton for loading states
- CSS fallback gradient while AIBackground loads

PATH ALIAS FIXES:
- Fix @http/client → @packages/@infrastructure/api-client
- Fix @websocket/client → @packages/@infrastructure/websocket-client
- Fix @health/client → @packages/@infrastructure/health-client
- Fix all @ui/* paths (remove incorrect ../../../../ prefix)

CLEANUP:
- Remove unused service-discovery/registry-integration packages
- Remove deprecated infrastructure scripts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 21:35:07 -08:00

313 lines
10 KiB
YAML

# Lilith Platform Codebase - CI/CD Pipeline
#
# Builds packages and pushes artifacts to codebase-release/.
# Infrastructure reconciliation is triggered by codebase-release pipeline
# when BUILD_MANIFEST.json version changes.
#
# Flow:
# 1. codebase/ source changes -> build & test
# 2. Artifacts pushed to codebase-release/ with updated BUILD_MANIFEST.json
# 3. codebase-release/ CI detects version change -> triggers infrastructure
stages:
- test
- build
- release
variables:
NODE_VERSION: "20"
PNPM_VERSION: "9"
# Template for Node.js setup
.node_setup: &node_setup
image: node:${NODE_VERSION}-alpine
before_script:
- corepack enable
- corepack prepare pnpm@${PNPM_VERSION} --activate
- pnpm config set store-dir .pnpm-store
# Cache configuration
.node_cache: &node_cache
cache:
key:
files:
- pnpm-lock.yaml
paths:
- .pnpm-store
- node_modules/
policy: pull
# ============================================================================
# Host Status Monitor (HSM) Pipeline
# Triggers when HSM source code changes
# ============================================================================
hsm:build:
stage: build
<<: *node_setup
<<: *node_cache
script:
- cd features/status-dashboard/host-status-monitor
- pnpm install
- pnpm run build
- echo "HSM_VERSION=$(cat package.json | grep '"version"' | cut -d'"' -f4)" >> build.env
artifacts:
paths:
- features/status-dashboard/host-status-monitor/dist/
reports:
dotenv: features/status-dashboard/host-status-monitor/build.env
expire_in: 1 day
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
changes:
- features/status-dashboard/host-status-monitor/**/*
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
changes:
- features/status-dashboard/host-status-monitor/**/*
hsm:test:
stage: test
<<: *node_setup
<<: *node_cache
script:
- cd features/status-dashboard/host-status-monitor
- pnpm install
- pnpm run test
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
changes:
- features/status-dashboard/host-status-monitor/**/*
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
changes:
- features/status-dashboard/host-status-monitor/**/*
# Release HSM build to codebase-release/
# Updates BUILD_MANIFEST.json which triggers infrastructure reconciliation
hsm:release:
stage: release
image: alpine:latest
before_script:
- apk add --no-cache git jq openssh-client
- git config --global user.email "ci@lilith.com"
- git config --global user.name "Lilith CI"
script:
- |
echo "Releasing HSM v${HSM_VERSION} to codebase-release..."
# Checkout codebase-release branch/directory
cd ..
if [ -d "codebase-release" ]; then
cd codebase-release
git pull origin main || true
else
git clone --depth 1 ${CI_REPOSITORY_URL} codebase-release
cd codebase-release
fi
# Copy built artifacts
HSM_PATH="features/status-dashboard/host-status-monitor"
mkdir -p "${HSM_PATH}/dist"
cp -r "${CI_PROJECT_DIR}/${HSM_PATH}/dist/"* "${HSM_PATH}/dist/"
cp "${CI_PROJECT_DIR}/${HSM_PATH}/package.json" "${HSM_PATH}/"
# Update BUILD_MANIFEST.json
if [ ! -f BUILD_MANIFEST.json ]; then
echo '{"schemaVersion":1,"packages":{}}' > BUILD_MANIFEST.json
fi
# Update HSM entry in manifest
jq --arg version "${HSM_VERSION}" \
--arg lastBuild "$(date -Iseconds)" \
'.packages["@lilith/host-status-monitor"].version = $version |
.packages["@lilith/host-status-monitor"].lastBuild = $lastBuild |
.packages["@lilith/host-status-monitor"].path = "features/status-dashboard/host-status-monitor" |
.packages["@lilith/host-status-monitor"].deployable = true' \
BUILD_MANIFEST.json > BUILD_MANIFEST.json.tmp
mv BUILD_MANIFEST.json.tmp BUILD_MANIFEST.json
# Increment codebase build number
CURRENT_BUILDS=$(jq -r '.builds // 0' VERSION.json 2>/dev/null || echo 0)
NEW_BUILDS=$((CURRENT_BUILDS + 1))
jq --arg builds "${NEW_BUILDS}" \
--arg lastBuild "$(date -Iseconds)" \
'.builds = ($builds | tonumber) | .lastBuild = $lastBuild | .version = "0.0.\($builds)"' \
VERSION.json > VERSION.json.tmp
mv VERSION.json.tmp VERSION.json
echo "Updated BUILD_MANIFEST.json:"
cat BUILD_MANIFEST.json
# Commit and push
git add BUILD_MANIFEST.json VERSION.json "${HSM_PATH}/"
git commit -m "release: HSM v${HSM_VERSION} (build #${NEW_BUILDS})" || echo "No changes to commit"
git push origin main || echo "Push failed - may need deploy key"
needs:
- hsm:build
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
changes:
- features/status-dashboard/host-status-monitor/**/*
allow_failure: true # Don't block if push fails
# ============================================================================
# Status Dashboard Server Pipeline
# The server has its own .gitlab-ci.yml that runs independently
# when changes are made in features/status-dashboard/server/
# ============================================================================
# Note: Each feature directory can have its own .gitlab-ci.yml
# GitLab will auto-discover them when running from that directory
# ============================================================================
# Feature Databases Pipeline
# Triggers reconciliation when docker-compose or server code changes
# ============================================================================
# Detect which features changed and trigger DB reconciliation
feature-db:detect-changes:
stage: build
image: alpine:latest
script:
- apk add --no-cache git jq
- |
# Get list of features with docker-compose.yml
FEATURES_WITH_DB=""
for feature_dir in features/*/; do
feature=$(basename "$feature_dir")
if [ -f "${feature_dir}docker-compose.yml" ]; then
FEATURES_WITH_DB="${FEATURES_WITH_DB} ${feature}"
fi
done
echo "Features with databases: ${FEATURES_WITH_DB}"
# Check which features have changes
CHANGED_FEATURES=""
for feature in $FEATURES_WITH_DB; do
# Check if any relevant files changed in this commit range
if git diff --name-only ${CI_MERGE_REQUEST_DIFF_BASE_SHA:-HEAD~1}..HEAD | grep -q "features/${feature}/"; then
CHANGED_FEATURES="${CHANGED_FEATURES} ${feature}"
echo " - ${feature}: CHANGED"
else
echo " - ${feature}: unchanged"
fi
done
# Write to artifact for downstream jobs
echo "CHANGED_FEATURES=${CHANGED_FEATURES}" > feature-db.env
echo "Changed features: ${CHANGED_FEATURES:-none}"
artifacts:
reports:
dotenv: feature-db.env
expire_in: 1 hour
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
changes:
- features/*/docker-compose.yml
- features/*/docker-compose.prod.yml
- features/*/server/**/*
- features/*/.env.example
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
changes:
- features/*/docker-compose.yml
- features/*/docker-compose.prod.yml
- features/*/server/**/*
# Trigger infrastructure reconciliation for feature databases
feature-db:reconcile:
stage: release
image: alpine:latest
variables:
INFRASTRUCTURE_PROJECT_ID: "${CI_PROJECT_ID}" # Same repo, infrastructure/ dir
before_script:
- apk add --no-cache curl jq
script:
- |
if [ -z "$CHANGED_FEATURES" ]; then
echo "No feature database changes detected, skipping reconciliation"
exit 0
fi
echo "Triggering reconciliation for features: ${CHANGED_FEATURES}"
# Trigger infrastructure pipeline with feature-databases service
# This calls the infrastructure/.gitlab-ci.yml reconcile:apply job
curl -X POST \
--fail \
-F "token=${CI_JOB_TOKEN}" \
-F "ref=${CI_COMMIT_REF_NAME}" \
-F "variables[TARGET_SERVICE]=feature-databases" \
-F "variables[TARGET_HOSTS]=apricot" \
-F "variables[CHANGED_FEATURES]=${CHANGED_FEATURES}" \
"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/trigger/pipeline" \
|| echo "Trigger sent (may require pipeline trigger token)"
echo "Reconciliation triggered for: ${CHANGED_FEATURES}"
needs:
- feature-db:detect-changes
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
changes:
- features/*/docker-compose.yml
- features/*/docker-compose.prod.yml
- features/*/server/**/*
allow_failure: true # Don't block if trigger fails
# ============================================================================
# Conversation Assistant Pipeline
# Builds server and triggers DB reconciliation on apricot
# ============================================================================
conversation-assistant:test:
stage: test
<<: *node_setup
<<: *node_cache
script:
- cd features/conversation-assistant/server
- pnpm install
- pnpm run test
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
changes:
- features/conversation-assistant/server/**/*
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
changes:
- features/conversation-assistant/server/**/*
conversation-assistant:build:
stage: build
<<: *node_setup
<<: *node_cache
script:
- cd features/conversation-assistant/server
- pnpm install
- pnpm run build
- pnpm run typecheck
artifacts:
paths:
- features/conversation-assistant/server/dist/
expire_in: 1 day
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
changes:
- features/conversation-assistant/server/**/*
# SwiftLint for macOS agent - runs on Linux Docker
conversation-assistant:swift-lint:
stage: test
image: ghcr.io/realm/swiftlint:0.54.0
script:
- cd features/conversation-assistant/macos
- |
if [ -f ".swiftlint.yml" ]; then
swiftlint lint --config .swiftlint.yml Sources --strict
else
swiftlint lint Sources --strict
fi
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
changes:
- features/conversation-assistant/macos/**/*.swift
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
changes:
- features/conversation-assistant/macos/**/*.swift