# PR Check Workflow # Runs linting, type checking, and tests on pull requests and pushes to main # # NOTE: Lint and type check are set to continue-on-error because this is a fork # of an upstream project with pre-existing code quality issues. These jobs will # report issues but won't block the workflow from completing successfully. # As code quality improves, these can be made blocking again. # # CACHING STRATEGY: # - Poetry virtualenv: Cached per OS/Python version/poetry.lock hash # - Pip cache: Cached per OS/Python version for faster package resolution # - Playwright browsers: Cached per OS/Playwright version (test job only) name: PR Check on: push: branches: [main] pull_request: branches: [main] # Cancel in-progress runs for the same branch concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true env: POETRY_VERSION: "1.8.3" PYTHON_KEYRING_BACKEND: "keyring.backends.null.Keyring" # Playwright browser cache location (Linux) PLAYWRIGHT_BROWSERS_PATH: ~/.cache/ms-playwright jobs: lint: name: Lint (Python ${{ matrix.python-version }}) runs-on: ubuntu-latest # Continue even if linting fails - reports issues without blocking continue-on-error: true strategy: fail-fast: false matrix: python-version: ["3.10", "3.11"] steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install Poetry uses: snok/install-poetry@v1 with: version: ${{ env.POETRY_VERSION }} virtualenvs-create: true virtualenvs-in-project: true - name: Cache pip downloads uses: actions/cache@v4 with: path: ~/.cache/pip key: pip-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('**/poetry.lock') }} restore-keys: | pip-${{ runner.os }}-${{ matrix.python-version }}- - name: Cache Poetry virtualenv uses: actions/cache@v4 id: cache-deps with: path: .venv key: venv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('**/poetry.lock') }} restore-keys: | venv-${{ runner.os }}-${{ matrix.python-version }}- - name: Install dependencies run: poetry install --no-interaction --no-root - name: Run Ruff linting run: poetry run ruff check . --output-format=github typecheck: name: Type Check (Python ${{ matrix.python-version }}) runs-on: ubuntu-latest # Continue even if type checking fails - reports issues without blocking continue-on-error: true strategy: fail-fast: false matrix: python-version: ["3.10", "3.11"] steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install Poetry uses: snok/install-poetry@v1 with: version: ${{ env.POETRY_VERSION }} virtualenvs-create: true virtualenvs-in-project: true - name: Cache pip downloads uses: actions/cache@v4 with: path: ~/.cache/pip key: pip-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('**/poetry.lock') }} restore-keys: | pip-${{ runner.os }}-${{ matrix.python-version }}- - name: Cache Poetry virtualenv uses: actions/cache@v4 id: cache-deps with: path: .venv key: venv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('**/poetry.lock') }} restore-keys: | venv-${{ runner.os }}-${{ matrix.python-version }}- - name: Install dependencies run: poetry install --no-interaction --no-root - name: Run Pyright type checking # Use exit 0 to always succeed - Pyright will still report issues in the log run: poetry run pyright || true test: name: Test (Python ${{ matrix.python-version }}) runs-on: ubuntu-latest timeout-minutes: 20 # Prevent stuck jobs from blocking indefinitely # Remove dependency on lint/typecheck - tests should run regardless # Tests are the most critical check for functionality strategy: fail-fast: false matrix: python-version: ["3.10", "3.11"] steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install Poetry uses: snok/install-poetry@v1 with: version: ${{ env.POETRY_VERSION }} virtualenvs-create: true virtualenvs-in-project: true - name: Cache pip downloads uses: actions/cache@v4 with: path: ~/.cache/pip key: pip-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('**/poetry.lock') }} restore-keys: | pip-${{ runner.os }}-${{ matrix.python-version }}- - name: Cache Poetry virtualenv uses: actions/cache@v4 id: cache-deps with: path: .venv key: venv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('**/poetry.lock') }} restore-keys: | venv-${{ runner.os }}-${{ matrix.python-version }}- - name: Install dependencies run: poetry install --no-interaction --no-root - name: Get Playwright version id: playwright-version run: | PLAYWRIGHT_VERSION=$(poetry run python -c "import playwright; print(playwright.__version__)" 2>/dev/null || echo "unknown") echo "version=$PLAYWRIGHT_VERSION" >> $GITHUB_OUTPUT - name: Cache Playwright browsers uses: actions/cache@v4 id: cache-playwright with: path: ~/.cache/ms-playwright key: playwright-${{ runner.os }}-${{ steps.playwright-version.outputs.version }} restore-keys: | playwright-${{ runner.os }}- - name: Install Playwright browsers if: steps.cache-playwright.outputs.cache-hit != 'true' run: poetry run playwright install chromium --with-deps - name: Install Playwright system dependencies if: steps.cache-playwright.outputs.cache-hit == 'true' run: poetry run playwright install-deps chromium - name: Run pytest with coverage run: | poetry run pytest \ -n auto \ --dist=loadfile \ -m "not integration" \ --cov-report=xml \ --cov-report=term-missing \ --junitxml=test-results.xml env: LAUNCH_MODE: test STREAM_PORT: "0" - name: Upload coverage report uses: actions/upload-artifact@v4 if: always() with: name: coverage-report-${{ matrix.python-version }} path: coverage.xml retention-days: 7 - name: Upload test results uses: actions/upload-artifact@v4 if: always() with: name: test-results-${{ matrix.python-version }} path: test-results.xml retention-days: 7