Change dashboard rate windows to 1m #73
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 Pipeline | |
| on: | |
| push: | |
| branches: [main, staging] | |
| pull_request: | |
| branches: [main] | |
| jobs: | |
| test: | |
| name: Tests & Coverage | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| - name: Set up Python | |
| run: uv python install 3.13 | |
| - name: Install dependencies | |
| run: uv sync --dev | |
| - name: Run tests with coverage | |
| run: uv run pytest tests/ -v --cov=app --cov-report=term-missing --cov-report=xml --cov-fail-under=70 | |
| - name: Coverage comment on PR | |
| if: github.event_name == 'pull_request' | |
| uses: MishaKav/pytest-coverage-comment@main | |
| with: | |
| pytest-xml-coverage-path: coverage.xml | |
| e2e-staging: | |
| name: E2E Smoke Tests (Staging) | |
| needs: test | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| - name: Set up Python | |
| run: uv python install 3.13 | |
| - name: Install dependencies | |
| run: uv sync --dev | |
| - name: Install doctl | |
| uses: digitalocean/action-doctl@v2 | |
| with: | |
| token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} | |
| - name: Deploy PR to staging | |
| run: doctl apps create-deployment ${{ secrets.DO_STAGING_APP_ID }} --wait | |
| - name: Wait for staging health | |
| run: | | |
| for i in $(seq 1 30); do | |
| STATUS=$(curl -s -o /dev/null -w "%{http_code}" ${{ secrets.STAGING_APP_URL }}/health) | |
| if [ "$STATUS" = "200" ]; then echo "Staging healthy!"; exit 0; fi | |
| echo "Attempt $i: status=$STATUS, retrying in 10s..." | |
| sleep 10 | |
| done | |
| echo "Staging unhealthy after 5 minutes" | |
| exit 1 | |
| - name: Run E2E smoke tests | |
| env: | |
| BASE_URL: ${{ secrets.STAGING_APP_URL }} | |
| run: uv run pytest tests/test_e2e_smoke.py -v | |
| deploy-staging: | |
| needs: test | |
| runs-on: ubuntu-latest | |
| if: github.ref == 'refs/heads/staging' && github.event_name == 'push' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install doctl | |
| uses: digitalocean/action-doctl@v2 | |
| with: | |
| token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} | |
| - name: Deploy to staging | |
| run: doctl apps create-deployment ${{ secrets.DO_STAGING_APP_ID }} --wait | |
| - name: Verify staging health | |
| run: | | |
| for i in $(seq 1 30); do | |
| STATUS=$(curl -s -o /dev/null -w "%{http_code}" ${{ secrets.STAGING_APP_URL }}/health) | |
| if [ "$STATUS" = "200" ]; then echo "Staging healthy!"; exit 0; fi | |
| echo "Attempt $i: status=$STATUS, retrying in 10s..." | |
| sleep 10 | |
| done | |
| echo "Staging unhealthy after 5 minutes" | |
| exit 1 | |
| deploy-prod: | |
| needs: test | |
| runs-on: ubuntu-latest | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install doctl | |
| uses: digitalocean/action-doctl@v2 | |
| with: | |
| token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} | |
| - name: Deploy to production | |
| run: doctl apps create-deployment ${{ secrets.DO_APP_ID }} --wait | |
| - name: Verify prod health | |
| run: | | |
| for i in $(seq 1 30); do | |
| STATUS=$(curl -s -o /dev/null -w "%{http_code}" ${{ secrets.APP_URL }}/health) | |
| if [ "$STATUS" = "200" ]; then echo "Prod healthy!"; exit 0; fi | |
| echo "Attempt $i: status=$STATUS, retrying in 10s..." | |
| sleep 10 | |
| done | |
| echo "Prod unhealthy after 5 minutes" | |
| exit 1 |