fix: regenerate package-lock.json for CI compatibility #3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI/CD | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| env: | |
| REGISTRY: ghcr.io | |
| BACKEND_IMAGE: ghcr.io/${{ github.repository }}/backend | |
| FRONTEND_IMAGE: ghcr.io/${{ github.repository }}/frontend | |
| jobs: | |
| # ── CI: Lint, Test & Security Audit ────────────────────────── | |
| backend-test: | |
| name: Backend — Lint & Test | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: backend | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| cache-dependency-path: backend/requirements.txt | |
| - name: Install dependencies | |
| run: pip install -r requirements.txt | |
| - name: Lint with pyright | |
| run: pip install pyright && pyright app/ | |
| - name: Run tests | |
| env: | |
| SECRET_KEY: ci-test-secret | |
| JWT_SECRET_KEY: ci-test-jwt-secret | |
| DATABASE_URL: "sqlite:///:memory:" | |
| run: python -m pytest tests/ -v --tb=short | |
| - name: Security audit | |
| continue-on-error: true | |
| run: pip install pip-audit && pip-audit | |
| frontend-test: | |
| name: Frontend — Lint, Type Check & Test | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: frontend | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 24 | |
| cache: npm | |
| cache-dependency-path: frontend/package-lock.json | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Type check | |
| run: npx tsc --noEmit | |
| - name: Lint | |
| run: npm run lint | |
| - name: Run tests | |
| run: npm test | |
| - name: Security audit | |
| continue-on-error: true | |
| run: npm audit --audit-level=high | |
| # ── CD: Build & Push Docker Images ────────────────────────── | |
| build-and-push: | |
| name: Build & Push Docker Images | |
| runs-on: ubuntu-latest | |
| needs: [backend-test, frontend-test] | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Extract metadata | |
| id: meta | |
| run: | | |
| echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT | |
| echo "date=$(date +'%Y%m%d')" >> $GITHUB_OUTPUT | |
| - name: Build & push backend image | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: ./backend | |
| push: true | |
| tags: | | |
| ${{ env.BACKEND_IMAGE }}:latest | |
| ${{ env.BACKEND_IMAGE }}:${{ steps.meta.outputs.sha_short }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Build & push frontend image | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: ./frontend | |
| push: true | |
| tags: | | |
| ${{ env.FRONTEND_IMAGE }}:latest | |
| ${{ env.FRONTEND_IMAGE }}:${{ steps.meta.outputs.sha_short }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| # ── CD: Deploy (staging simulation) ───────────────────────── | |
| deploy: | |
| name: Deploy to Staging | |
| runs-on: ubuntu-latest | |
| needs: [build-and-push] | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| environment: | |
| name: staging | |
| url: https://staging.example.com | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Deploy notification | |
| run: | | |
| echo "🚀 Deploying commit ${{ github.sha }}" | |
| echo " Backend: ${{ env.BACKEND_IMAGE }}:latest" | |
| echo " Frontend: ${{ env.FRONTEND_IMAGE }}:latest" | |
| - name: Verify Docker Compose config | |
| env: | |
| DB_PASSWORD: ci-placeholder | |
| SECRET_KEY: ci-placeholder | |
| JWT_SECRET_KEY: ci-placeholder | |
| run: docker compose config --quiet | |
| - name: Smoke test — container builds | |
| env: | |
| DB_PASSWORD: ci-placeholder | |
| SECRET_KEY: ci-placeholder | |
| JWT_SECRET_KEY: ci-placeholder | |
| FRONTEND_URL: "https://staging.example.com" | |
| run: | | |
| docker compose build | |
| echo "✅ All containers build successfully" | |
| - name: Deployment summary | |
| run: | | |
| echo "## Deployment Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "| Item | Value |" >> $GITHUB_STEP_SUMMARY | |
| echo "|------|-------|" >> $GITHUB_STEP_SUMMARY | |
| echo "| **Commit** | \`$(git rev-parse --short HEAD)\` |" >> $GITHUB_STEP_SUMMARY | |
| echo "| **Backend Image** | \`${{ env.BACKEND_IMAGE }}:latest\` |" >> $GITHUB_STEP_SUMMARY | |
| echo "| **Frontend Image** | \`${{ env.FRONTEND_IMAGE }}:latest\` |" >> $GITHUB_STEP_SUMMARY | |
| echo "| **Status** | ✅ Ready for production |" >> $GITHUB_STEP_SUMMARY |