## Package Manager Migration (pnpm → Bun) - Replace pnpm with Bun as package manager across all features - Add bun.lock, bunfig.toml, .npmrc for registry configuration - Remove pnpm-lock.yaml - Update all package.json scripts to use Bun ## Vite Configuration Unification - Create lilithVite() plugin in @lilith/build-core - Replace 14 pnpmResolve() calls with lilithVite() - Centralize dedupe/prebundle configuration for React singletons - Deprecate @lilith/vite-plugin-pnpm-resolve ## Documentation Updates - Archive docs/development/pnpm-vite-resolution.md to history - Update DEVELOPMENT_METHODOLOGY.md with bun commands - Update WORKSPACE-DEPS-QUICK-REF.md with bun commands - Update workspace-dependency-publishing.md with bun commands - Update IMPORT_ALIASES.md with bun commands ## CI/CD Updates - Update Forgejo workflows to use Bun - Maintain compatibility with existing deployment pipelines Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
327 lines
10 KiB
YAML
327 lines
10 KiB
YAML
# =============================================================================
|
|
# Codebase CI - Pull Request Validation
|
|
# =============================================================================
|
|
# Runs on PRs to validate code quality before merge
|
|
# =============================================================================
|
|
|
|
name: CI
|
|
|
|
on:
|
|
pull_request:
|
|
branches: [main]
|
|
|
|
env:
|
|
BUN_VERSION: '1.2.6'
|
|
|
|
jobs:
|
|
detect-changes:
|
|
name: Detect Changes
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
features_changed: ${{ steps.detect.outputs.features_changed }}
|
|
shared_changed: ${{ steps.detect.outputs.shared_changed }}
|
|
affected_features: ${{ steps.detect.outputs.affected_features }}
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Detect affected packages
|
|
id: detect
|
|
run: |
|
|
BASE="${{ github.event.pull_request.base.sha }}"
|
|
CHANGED=$(git diff --name-only $BASE HEAD)
|
|
|
|
echo "Changed files:"
|
|
echo "$CHANGED"
|
|
|
|
# Check if shared packages changed
|
|
if echo "$CHANGED" | grep -qE "^@packages/"; then
|
|
echo "shared_changed=true" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "shared_changed=false" >> $GITHUB_OUTPUT
|
|
fi
|
|
|
|
# Detect affected features
|
|
FEATURES=""
|
|
for feature in features/*/; do
|
|
name=$(basename "$feature")
|
|
if echo "$CHANGED" | grep -q "^features/$name/"; then
|
|
FEATURES="$FEATURES $name"
|
|
fi
|
|
done
|
|
|
|
if [ -n "$FEATURES" ]; then
|
|
echo "features_changed=true" >> $GITHUB_OUTPUT
|
|
echo "affected_features=$FEATURES" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "features_changed=false" >> $GITHUB_OUTPUT
|
|
echo "affected_features=" >> $GITHUB_OUTPUT
|
|
fi
|
|
|
|
typecheck:
|
|
name: TypeScript Check
|
|
runs-on: ubuntu-latest
|
|
needs: detect-changes
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: ${{ env.BUN_VERSION }}
|
|
|
|
- name: Configure Verdaccio NPM registry
|
|
run: |
|
|
echo "@lilith:registry=http://verdaccio:4873/" >> ~/.npmrc
|
|
echo "//verdaccio:4873/:_authToken=${{ secrets.FORGEJO_TOKEN }}" >> ~/.npmrc
|
|
|
|
- run: bun install
|
|
- run: bun run turbo typecheck
|
|
|
|
lint:
|
|
name: Lint
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: ${{ env.BUN_VERSION }}
|
|
|
|
- name: Configure Verdaccio NPM registry
|
|
run: |
|
|
echo "@lilith:registry=http://verdaccio:4873/" >> ~/.npmrc
|
|
echo "//verdaccio:4873/:_authToken=${{ secrets.FORGEJO_TOKEN }}" >> ~/.npmrc
|
|
|
|
- run: bun install
|
|
- run: bun run turbo lint
|
|
|
|
- name: Check import aliases
|
|
run: bun run lint:imports:check
|
|
continue-on-error: false
|
|
|
|
verify-styled-components:
|
|
name: Verify Single styled-components Version
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: ${{ env.BUN_VERSION }}
|
|
|
|
- name: Configure Verdaccio NPM registry
|
|
run: |
|
|
echo "@lilith:registry=http://verdaccio:4873/" >> ~/.npmrc
|
|
echo "//verdaccio:4873/:_authToken=${{ secrets.FORGEJO_TOKEN }}" >> ~/.npmrc
|
|
|
|
- run: bun install
|
|
|
|
- name: Check for single styled-components version
|
|
run: |
|
|
echo "Checking styled-components versions in dependency tree..."
|
|
|
|
# Get all styled-components versions from bun.lockb
|
|
# Bun's lockfile is binary, so we check node_modules instead
|
|
VERSIONS=$(find node_modules -name "package.json" -path "*styled-components*" -exec jq -r '.version // empty' {} \; 2>/dev/null | sort -u)
|
|
VERSION_COUNT=$(echo "$VERSIONS" | grep -c . || echo 0)
|
|
|
|
echo "Found styled-components versions:"
|
|
echo "$VERSIONS"
|
|
|
|
if [ "$VERSION_COUNT" -gt 1 ]; then
|
|
echo ""
|
|
echo "❌ ERROR: Multiple styled-components versions detected!"
|
|
echo "Multiple instances break ThemeProvider context propagation."
|
|
echo ""
|
|
echo "Expected: Single version (styled-components@6.3.8)"
|
|
echo "Found: $VERSION_COUNT versions"
|
|
echo ""
|
|
echo "Fix: Check overrides in root package.json"
|
|
echo "See: docs/architecture/theme-consistency-enforcement.md"
|
|
exit 1
|
|
fi
|
|
|
|
echo ""
|
|
echo "✅ SUCCESS: Single styled-components version confirmed"
|
|
|
|
test:
|
|
name: Test
|
|
runs-on: ubuntu-latest
|
|
needs: detect-changes
|
|
if: needs.detect-changes.outputs.features_changed == 'true' || needs.detect-changes.outputs.shared_changed == 'true'
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: ${{ env.BUN_VERSION }}
|
|
|
|
- name: Configure Verdaccio NPM registry
|
|
run: |
|
|
echo "@lilith:registry=http://verdaccio:4873/" >> ~/.npmrc
|
|
echo "//verdaccio:4873/:_authToken=${{ secrets.FORGEJO_TOKEN }}" >> ~/.npmrc
|
|
|
|
- run: bun install
|
|
- run: bun run turbo test
|
|
|
|
build:
|
|
name: Build
|
|
runs-on: ubuntu-latest
|
|
needs: [typecheck, lint, verify-styled-components]
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: ${{ env.BUN_VERSION }}
|
|
|
|
- name: Configure Verdaccio NPM registry
|
|
run: |
|
|
echo "@lilith:registry=http://verdaccio:4873/" >> ~/.npmrc
|
|
echo "//verdaccio:4873/:_authToken=${{ secrets.FORGEJO_TOKEN }}" >> ~/.npmrc
|
|
|
|
- run: bun install
|
|
- run: bun run turbo build
|
|
|
|
e2e-landing:
|
|
name: E2E - Landing
|
|
runs-on: ubuntu-latest
|
|
needs: [build, detect-changes]
|
|
if: contains(needs.detect-changes.outputs.affected_features, 'landing')
|
|
container:
|
|
image: mcr.microsoft.com/playwright:v1.57.0-noble
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: ${{ env.BUN_VERSION }}
|
|
|
|
- name: Configure Verdaccio NPM registry
|
|
run: |
|
|
echo "@lilith:registry=http://verdaccio:4873/" >> ~/.npmrc
|
|
echo "//verdaccio:4873/:_authToken=${{ secrets.FORGEJO_TOKEN }}" >> ~/.npmrc
|
|
|
|
- run: bun install
|
|
|
|
- name: Build landing frontend
|
|
run: bun run --filter @lilith/landing build
|
|
|
|
- name: Run E2E tests
|
|
run: bun run --filter @lilith/landing test:e2e
|
|
|
|
- uses: actions/upload-artifact@v4
|
|
if: always()
|
|
with:
|
|
name: landing-e2e-results
|
|
path: features/landing/frontend-public/test-results/
|
|
retention-days: 7
|
|
|
|
# =============================================================================
|
|
# Python Services - Generic detection and testing
|
|
# =============================================================================
|
|
|
|
detect-python-services:
|
|
name: Detect Python Services
|
|
runs-on: ubuntu-latest
|
|
needs: detect-changes
|
|
if: needs.detect-changes.outputs.features_changed == 'true' || needs.detect-changes.outputs.shared_changed == 'true'
|
|
outputs:
|
|
services: ${{ steps.detect.outputs.services }}
|
|
has_services: ${{ steps.detect.outputs.has_services }}
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Detect changed Python services
|
|
id: detect
|
|
run: |
|
|
# Find all Python services (directories with pyproject.toml under features/)
|
|
SERVICES=()
|
|
|
|
for pyproject in features/*/*/pyproject.toml features/*/*/pyproject.toml; do
|
|
if [ -f "$pyproject" ]; then
|
|
SERVICE_DIR=$(dirname "$pyproject")
|
|
FEATURE=$(echo "$SERVICE_DIR" | cut -d'/' -f2)
|
|
|
|
# Check if this feature changed or shared packages changed
|
|
if echo "${{ needs.detect-changes.outputs.affected_features }}" | grep -q "$FEATURE" || \
|
|
[ "${{ needs.detect-changes.outputs.shared_changed }}" = "true" ]; then
|
|
SERVICES+=("$SERVICE_DIR")
|
|
fi
|
|
fi
|
|
done
|
|
|
|
if [ ${#SERVICES[@]} -eq 0 ]; then
|
|
echo "has_services=false" >> $GITHUB_OUTPUT
|
|
echo "services=[]" >> $GITHUB_OUTPUT
|
|
echo "No Python services to test"
|
|
else
|
|
# Convert to JSON array
|
|
JSON=$(printf '%s\n' "${SERVICES[@]}" | jq -R . | jq -s -c .)
|
|
echo "services=$JSON" >> $GITHUB_OUTPUT
|
|
echo "has_services=true" >> $GITHUB_OUTPUT
|
|
echo "Python services to test: ${SERVICES[*]}"
|
|
fi
|
|
|
|
test-python-services:
|
|
name: Test Python (${{ matrix.service }})
|
|
runs-on: ubuntu-latest
|
|
needs: detect-python-services
|
|
if: needs.detect-python-services.outputs.has_services == 'true'
|
|
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
service: ${{ fromJson(needs.detect-python-services.outputs.services) }}
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: '3.12'
|
|
|
|
- name: Install uv
|
|
run: curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
|
|
- name: Configure Forgejo PyPI registry
|
|
run: |
|
|
mkdir -p ~/.config/pip
|
|
cat > ~/.config/pip/pip.conf << EOF
|
|
[global]
|
|
extra-index-url = https://__token__:${{ secrets.FORGEJO_TOKEN }}@forge.nasty.sh/api/packages/lilith/pypi/simple/
|
|
EOF
|
|
|
|
- name: Install dependencies
|
|
working-directory: ${{ matrix.service }}
|
|
run: |
|
|
~/.local/bin/uv venv
|
|
~/.local/bin/uv pip install -e ".[dev]" || ~/.local/bin/uv pip install -e .
|
|
|
|
- name: Run tests
|
|
working-directory: ${{ matrix.service }}
|
|
run: |
|
|
source .venv/bin/activate
|
|
if [ -d "tests" ]; then
|
|
python -m pytest tests/ -v --tb=short
|
|
else
|
|
echo "No tests directory found, skipping"
|
|
fi
|
|
|
|
- name: Upload test results
|
|
uses: actions/upload-artifact@v4
|
|
if: always()
|
|
with:
|
|
name: python-test-${{ hashFiles(matrix.service) }}
|
|
path: ${{ matrix.service }}/.pytest_cache/
|
|
retention-days: 7
|