name: ci on: push: pull_request: workflow_dispatch: permissions: contents: read concurrency: group: ci-${{ gitea.ref }} cancel-in-progress: true jobs: static: runs-on: ubuntu-latest timeout-minutes: 15 steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: '3.12' - run: python tools/validate_v16.py - run: python -m unittest -v working-directory: research/hardening - run: python -m unittest -v scripts.tests.test_scaffold_slice scripts.tests.test_scaffold_ui_screen backend: runs-on: ubuntu-latest timeout-minutes: 30 services: postgres: image: postgres:17 env: POSTGRES_DB: kartsell POSTGRES_USER: kartsell POSTGRES_PASSWORD: kartsell ports: ["5432:5432"] options: >- --health-cmd "pg_isready -U kartsell" --health-interval 10s --health-timeout 5s --health-retries 5 steps: - uses: actions/checkout@v4 - uses: actions/setup-dotnet@v4 with: dotnet-version: '10.0.x' - run: dotnet restore KArtSell.sln - run: dotnet build KArtSell.sln --no-restore -c Release - run: dotnet run --project src/KArtSell.DbMigrator -c Release --no-build env: KARTSELL_POSTGRES: Host=localhost;Port=5432;Database=kartsell;Username=kartsell;Password=kartsell - run: dotnet run --project src/KArtSell.DbMigrator -c Release --no-build env: KARTSELL_POSTGRES: Host=localhost;Port=5432;Database=kartsell;Username=kartsell;Password=kartsell - run: dotnet test KArtSell.sln --no-build -c Release --logger trx env: KARTSELL_POSTGRES: Host=localhost;Port=5432;Database=kartsell;Username=kartsell;Password=kartsell frontend: runs-on: ubuntu-latest timeout-minutes: 30 steps: - uses: actions/checkout@v4 - run: test -f frontend/pnpm-lock.yaml || (echo "pnpm-lock.yaml is required for reproducible CI" && exit 1) - uses: pnpm/action-setup@v4 with: version: 10 - uses: actions/setup-node@v4 with: node-version: 22 cache: pnpm cache-dependency-path: frontend/pnpm-lock.yaml - run: pnpm install --frozen-lockfile working-directory: frontend - run: pnpm typecheck && pnpm test && pnpm build working-directory: frontend - run: pnpm exec playwright install --with-deps chromium && pnpm e2e working-directory: frontend deploy: if: github.event_name == 'push' && github.ref == 'refs/heads/main' needs: [static, backend, frontend] runs-on: ubuntu-latest timeout-minutes: 20 steps: - uses: actions/checkout@v4 - uses: actions/setup-dotnet@v4 with: dotnet-version: '10.0.x' - name: Publish run: | dotnet restore KArtSell.sln dotnet publish -c Release -o ./publish src/KArtSell.Host - name: Deploy to production env: DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }} DEPLOY_USER: ${{ secrets.DEPLOY_USER }} DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} run: | mkdir -p ~/.ssh echo "$DEPLOY_KEY" > ~/.ssh/deploy_key chmod 600 ~/.ssh/deploy_key ssh-keyscan -H $DEPLOY_HOST >> ~/.ssh/known_hosts 2>/dev/null || true # Copy published app scp -i ~/.ssh/deploy_key -r ./publish/* $DEPLOY_USER@$DEPLOY_HOST:/app/kartsell/ # Restart service ssh -i ~/.ssh/deploy_key $DEPLOY_USER@$DEPLOY_HOST "sudo systemctl restart kartsell" # Health check sleep 5 curl -f http://$DEPLOY_HOST:5002/health || echo "Health check pending" rm ~/.ssh/deploy_key