Repository navigation
feat(security): middleware-driven rate limiting with policy table #493
Workflow file for this run
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 | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| jobs: | |
| changes: | |
| name: Detect Changes | |
| runs-on: ubuntu-latest | |
| outputs: | |
| code: ${{ steps.filter.outputs.code }} | |
| steps: | |
| - name: Check for code changes | |
| id: filter | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| CHANGED=$(gh pr view ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --json files --jq '.files[].path') | |
| else | |
| CHANGED=$(gh api repos/${{ github.repository }}/commits/${{ github.sha }} --jq '.files[].filename') | |
| fi | |
| echo "Changed files:" | |
| echo "$CHANGED" | |
| # Docs-only files that should not trigger CI | |
| CODE=false | |
| while IFS= read -r file; do | |
| [[ -z "$file" ]] && continue | |
| [[ "$file" == *.md ]] && continue | |
| [[ "$file" == .context/* ]] && continue | |
| [[ "$file" == .instructions/* ]] && continue | |
| [[ "$file" == LICENSE ]] && continue | |
| CODE=true | |
| echo "Code change detected: $file" | |
| break | |
| done <<< "$CHANGED" | |
| echo "code=$CODE" >> "$GITHUB_OUTPUT" | |
| validate: | |
| name: Validate | |
| runs-on: ubuntu-latest | |
| needs: changes | |
| if: needs.changes.outputs.code == 'true' | |
| # Postgres service exercises migrations and seeds against a real DB so | |
| # broken migrations / seed units fail CI at PR time. pgvector image | |
| # matches production so the vector extension is available. | |
| services: | |
| postgres: | |
| image: pgvector/pgvector:pg15 | |
| env: | |
| POSTGRES_USER: postgres | |
| POSTGRES_PASSWORD: postgres | |
| POSTGRES_DB: sunrise_ci | |
| ports: | |
| - 5432:5432 | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| # Environment variables needed for Prisma generate (postinstall), migrations, seeds, and build | |
| env: | |
| DATABASE_URL: 'postgresql://postgres:postgres@localhost:5432/sunrise_ci' | |
| BETTER_AUTH_SECRET: 'ci-build-secret-not-for-production-use' | |
| BETTER_AUTH_URL: 'http://localhost:3000' | |
| NEXT_PUBLIC_APP_URL: 'http://localhost:3000' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Apply database migrations | |
| run: npm run db:migrate:deploy | |
| - name: Run seeds | |
| run: npm run db:seed | |
| - name: Type check | |
| run: npm run type-check | |
| - name: Lint | |
| run: npm run lint | |
| - name: Format check | |
| run: npm run format:check | |
| - name: Run tests | |
| run: npm run test | |
| - name: Build | |
| run: npm run build | |
| docker: | |
| name: Docker Build | |
| runs-on: ubuntu-latest | |
| needs: [changes, validate] | |
| if: needs.changes.outputs.code == 'true' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Build Docker image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| push: false | |
| tags: sunrise:${{ github.sha }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| build-args: | | |
| DATABASE_URL=postgresql://postgres:postgres@localhost:5432/sunrise | |
| BETTER_AUTH_URL=http://localhost:3000 | |
| BETTER_AUTH_SECRET=ci-build-secret-not-for-production-use | |
| NEXT_PUBLIC_APP_URL=http://localhost:3000 | |
| # Gate job for branch protection - always runs and reports success | |
| ci-status: | |
| name: CI Status | |
| runs-on: ubuntu-latest | |
| needs: [validate, docker] | |
| if: always() | |
| steps: | |
| - name: Check CI result | |
| run: | | |
| if [[ "${{ needs.validate.result }}" == "failure" || "${{ needs.docker.result }}" == "failure" ]]; then | |
| echo "CI failed" | |
| exit 1 | |
| fi | |
| echo "CI passed (jobs succeeded or were skipped for docs-only changes)" |