--- name: CI on: push: branches: [main, master] pull_request: jobs: lint-and-test: runs-on: ubuntu-latest # No job container: actions/checkout@v4 needs Node (act_runner fails in python-only images) services: postgres: image: postgres:15 env: POSTGRES_USER: poteuser POSTGRES_PASSWORD: ${{ secrets.DB_PASSWORD || 'testpass123' }} POSTGRES_DB: potedb_test options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 steps: - name: Check out code uses: actions/checkout@v4 - name: Set up Python venv run: | python3 -m venv .venv .venv/bin/pip install --upgrade pip .venv/bin/pip install -e ".[dev]" - name: Run linters run: | echo "Running ruff..." .venv/bin/ruff check src/ tests/ || true echo "Running black check..." .venv/bin/black --check src/ tests/ || true echo "Running mypy..." .venv/bin/mypy src/ --install-types --non-interactive || true - name: Run tests with coverage env: DATABASE_URL: postgresql://poteuser:${{ secrets.DB_PASSWORD || 'testpass123' }}@postgres:5432/potedb_test SMTP_HOST: ${{ secrets.SMTP_HOST || 'localhost' }} SMTP_PORT: 587 SMTP_USER: ${{ secrets.SMTP_USER || 'test@example.com' }} SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD || 'dummy' }} FROM_EMAIL: ${{ secrets.FROM_EMAIL || 'test@example.com' }} run: | .venv/bin/pytest tests/ -v --cov=src/pote --cov-report=term --cov-report=xml - name: Test scripts env: DATABASE_URL: postgresql://poteuser:${{ secrets.DB_PASSWORD || 'testpass123' }}@postgres:5432/potedb_test run: | echo "Testing database migrations..." .venv/bin/alembic upgrade head echo "Testing price loader..." .venv/bin/python scripts/fetch_sample_prices.py || true security-scan: runs-on: ubuntu-latest steps: - name: Check out code uses: actions/checkout@v4 - name: Set up Python venv run: | python3 -m venv .venv .venv/bin/pip install --upgrade pip .venv/bin/pip install -e ".[dev]" safety bandit - name: Run safety check run: | .venv/bin/safety check --json || true continue-on-error: true - name: Run bandit security scan run: | .venv/bin/bandit -r src/ -f json -o bandit-report.json || true .venv/bin/bandit -r src/ -f screen continue-on-error: true dependency-scan: runs-on: ubuntu-latest container: image: aquasec/trivy:latest steps: - name: Install Node.js for checkout action run: | apk add --no-cache nodejs npm curl - name: Check out code uses: actions/checkout@v4 - name: Scan dependencies run: trivy fs --scanners vuln --exit-code 0 . docker-build-test: runs-on: ubuntu-latest steps: - name: Check out code uses: actions/checkout@v4 - name: Build and test Docker image run: | # Plain docker build โ€” buildx images are not visible to act_runner's docker run docker build -t pote:test . docker run --rm pote:test python -c "import pote; print('POTE import successful')" workflow-summary: runs-on: ubuntu-latest needs: [lint-and-test, security-scan, dependency-scan, docker-build-test] if: always() steps: - name: Generate workflow summary run: | echo "## ๐Ÿ” CI Workflow Summary" >> $GITHUB_STEP_SUMMARY || true echo "" >> $GITHUB_STEP_SUMMARY || true echo "### Job Results" >> $GITHUB_STEP_SUMMARY || true echo "" >> $GITHUB_STEP_SUMMARY || true echo "| Job | Status |" >> $GITHUB_STEP_SUMMARY || true echo "|-----|--------|" >> $GITHUB_STEP_SUMMARY || true echo "| ๐Ÿงช Lint & Test | ${{ needs.lint-and-test.result }} |" >> $GITHUB_STEP_SUMMARY || true echo "| ๐Ÿ”’ Security Scan | ${{ needs.security-scan.result }} |" >> $GITHUB_STEP_SUMMARY || true echo "| ๐Ÿ“ฆ Dependency Scan | ${{ needs.dependency-scan.result }} |" >> $GITHUB_STEP_SUMMARY || true echo "| ๐Ÿณ Docker Build | ${{ needs.docker-build-test.result }} |" >> $GITHUB_STEP_SUMMARY || true echo "" >> $GITHUB_STEP_SUMMARY || true echo "### ๐Ÿ“Š Summary" >> $GITHUB_STEP_SUMMARY || true echo "" >> $GITHUB_STEP_SUMMARY || true echo "All checks have completed. Review individual job logs for details." >> $GITHUB_STEP_SUMMARY || true