test: quality fixes, parallel execution, and user scenario gap tests #51
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] | |
| jobs: | |
| test: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| - name: Install dependencies | |
| run: uv sync --all-extras | |
| - name: Lint | |
| run: uv run ruff check src/ | |
| - name: Test | |
| run: uv run pytest tests/ -x -q | |
| frontend: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| - name: Install pnpm | |
| run: corepack enable | |
| - name: Install dependencies | |
| working-directory: frontend | |
| run: pnpm install --frozen-lockfile | |
| - name: Type check & build | |
| working-directory: frontend | |
| run: pnpm build | |
| extension: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| - name: Install pnpm | |
| run: corepack enable | |
| - name: Install dependencies | |
| working-directory: extension | |
| run: pnpm install --frozen-lockfile | |
| - name: Build Chrome extension | |
| working-directory: extension | |
| run: pnpm build | |
| docker: | |
| runs-on: ubuntu-latest | |
| needs: [test, frontend] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Build image (no push) | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| push: false | |
| load: true | |
| tags: 4dpocket:ci | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Smoke test Docker image | |
| run: | | |
| docker run -d --name 4dp-smoke -p 4040:4040 \ | |
| -e FDP_DATABASE__URL=sqlite:////data/4dpocket.db \ | |
| -e FDP_AUTH__MODE=single \ | |
| 4dpocket:ci | |
| # Wait for health | |
| for i in $(seq 1 30); do | |
| if curl -sf http://localhost:4040/api/v1/health > /dev/null 2>&1; then | |
| echo "Container ready" | |
| break | |
| fi | |
| sleep 1 | |
| done | |
| # Validate SPA root serves index.html | |
| STATUS=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:4040/) | |
| if [ "$STATUS" != "200" ]; then | |
| echo "FAIL: GET / returned $STATUS (expected 200)" | |
| docker logs 4dp-smoke | |
| exit 1 | |
| fi | |
| echo "SPA root: OK ($STATUS)" | |
| # Validate API | |
| STATUS=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:4040/api/v1/health) | |
| if [ "$STATUS" != "200" ]; then | |
| echo "FAIL: GET /api/v1/health returned $STATUS (expected 200)" | |
| docker logs 4dp-smoke | |
| exit 1 | |
| fi | |
| echo "API health: OK ($STATUS)" | |
| docker stop 4dp-smoke |