Bump pypdf from 6.13.3 to 6.16.1 #870
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: AutoControl Code Quality | |
| # Static analysis (ruff, bandit) plus the headless pytest suite added in | |
| # rounds 22-30. Decoupled from the existing dev/stable workflows, which | |
| # run legacy standalone test scripts and exist for hardware integration | |
| # coverage on Windows runners. | |
| on: | |
| push: | |
| branches: [ "dev", "main", "stable" ] | |
| pull_request: | |
| branches: [ "dev", "main", "stable" ] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| jobs: | |
| dependency-review: | |
| if: github.event_name == 'pull_request' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/dependency-review-action@v4 | |
| lint: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| cache: "pip" | |
| - name: Install ruff | |
| run: "pip install --only-binary :all: ruff==0.15.22" | |
| - name: Run ruff | |
| run: ruff check je_auto_control/ | |
| security: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| cache: "pip" | |
| - name: Install bandit | |
| run: "pip install --only-binary :all: bandit==1.9.4" | |
| - name: Run bandit (recursive, skip tests + i18n dicts) | |
| run: bandit -r je_auto_control/ -c pyproject.toml | |
| pytest-headless: | |
| # The suite ran on Windows alone for its whole life, so every | |
| # platform assumption it holds went unmeasured on the two operating | |
| # systems the project also claims to support. Linux and macOS are | |
| # here to measure them; they carry the two ends of the supported | |
| # Python range rather than all five, because what differs between | |
| # 3.10 and 3.14 is Python and what differs here is the OS. | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - { os: windows-2022, python-version: "3.10" } | |
| - { os: windows-2022, python-version: "3.11" } | |
| - { os: windows-2022, python-version: "3.12" } | |
| - { os: windows-2022, python-version: "3.13" } | |
| - { os: windows-2022, python-version: "3.14" } | |
| - { os: ubuntu-22.04, python-version: "3.10" } | |
| - { os: ubuntu-22.04, python-version: "3.14" } | |
| - { os: macos-14, python-version: "3.10" } | |
| - { os: macos-14, python-version: "3.14" } | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| cache: "pip" | |
| # Same set the container image installs, and for the same reasons: | |
| # the X11 backend connects to a display at import time, opencv and | |
| # PySide6 hard-require libGL/glib, and Qt's platform plugin needs | |
| # the xcb libraries. Without these the suite fails at collection | |
| # with a linker error rather than a test result. | |
| - name: Install X11 and Qt runtime libraries (Linux) | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y --no-install-recommends \ | |
| xvfb xauth x11-utils \ | |
| libgl1 libegl1 libglib2.0-0 \ | |
| libxkbcommon-x11-0 libdbus-1-3 \ | |
| libxcb-cursor0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 \ | |
| libxcb-randr0 libxcb-render-util0 libxcb-shape0 libxcb-sync1 \ | |
| libxcb-xfixes0 libxcb-xinerama0 libxcb-xkb1 | |
| # One command per step, each on a single line: a `run: |` block scalar | |
| # swallows NOSONAR markers, so a justification inside one is a comment | |
| # that reads as handled and suppresses nothing. | |
| - name: Upgrade the installer | |
| shell: bash | |
| run: python -m pip install --upgrade pip wheel # NOSONAR githubactions:S8544 # reason: pip and wheel are the installer; pinning them here would pin the tool that applies the pins below | |
| # Install the editable package FIRST so its source dir is the one | |
| # Python sees on subsequent imports. We deliberately avoid | |
| # `pip install -r dev_requirements.txt` here because that file pulls in | |
| # `je_auto_control_dev` (a separate PyPI package), which ships its own | |
| # snapshot of `je_auto_control/` straight into site-packages and masks | |
| # the editable install for any sub-package the snapshot doesn't include | |
| # (admin, usb, remote_desktop, vision, …). | |
| - name: Install the project itself | |
| shell: bash | |
| run: pip install -e . # NOSONAR githubactions:S8544 githubactions:S8541 # reason: installs the checked-out project itself, so there is no upstream version to lock and no third-party setup script to run | |
| - name: Install the test tooling | |
| shell: bash | |
| # Quoted: `--only-binary :all:` puts a colon-space inside the | |
| # scalar, which YAML reads as a mapping and refuses. | |
| run: "pip install --only-binary :all: ruff==0.15.22 bandit==1.9.4 pytest==9.1.1 pytest-timeout==2.4.0 pytest-rerunfailures==15.1 coverage==7.15.4 PySide6==6.11.1" | |
| # Paths come from `testpaths` in pyproject.toml. Do NOT pass an explicit | |
| # path here: an argument overrides testpaths, which previously meant the | |
| # flow_control tests were configured to run but silently never did. | |
| # | |
| # Linux runs under a real Xvfb rather than Qt's offscreen platform: | |
| # the X11 backend opens a display at import time, and offscreen | |
| # would hide exactly the breakage this job exists to find. | |
| # | |
| # `coverage run -m pytest`, NOT `pytest --cov`, and that is load-bearing: | |
| # this package registers a `pytest11` entry point, so pytest imports | |
| # `je_auto_control.utils.pytest_plugin.plugin` while loading plugins — | |
| # which executes `je_auto_control/__init__.py`, the facade, and with it | |
| # several hundred modules. pytest-cov only starts measuring after that, | |
| # so every one of those modules' import-time lines was recorded as never | |
| # executed. Measured on this tree: 11,962 statements, 24 points, and the | |
| # worst-hit files were the biggest ones (`action_executor` +786, | |
| # `_handlers` +684). A package that registers a pytest plugin cannot | |
| # measure itself with `pytest --cov`; `coverage run` starts first. | |
| - name: Run headless pytest suite under coverage | |
| shell: bash | |
| run: >- | |
| ${{ runner.os == 'Linux' && 'xvfb-run -a -s "-screen 0 1280x800x24"' || '' }} | |
| python -m coverage run -m pytest -v --tb=short --timeout=120 | |
| # XML before the floor check, so a square that fails the floor still | |
| # uploads the report that says which lines it was short of. | |
| - name: Write the coverage XML | |
| shell: bash | |
| run: python -m coverage xml | |
| - name: Enforce the coverage floor | |
| shell: bash | |
| run: python -m coverage report # the floor is `fail_under` in pyproject.toml, so the ratchet lives in exactly one place | |
| - name: Upload coverage report | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-${{ matrix.os }}-${{ matrix.python-version }} | |
| path: coverage.xml | |
| # The job id is still `typing-stable-api` because it is a required check and | |
| # renaming it silently drops the requirement, but the scope is no longer the | |
| # stable API alone: mypy now checks the whole package, minus the shrink-only | |
| # list in `test/verify/typing_contract_exempt.txt`. The verify script also | |
| # runs the three target platforms mypy can be pointed at, so the Windows and | |
| # macOS backends are checked from this Ubuntu runner rather than skipped. | |
| typing-stable-api: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - run: pip install -e . # NOSONAR githubactions:S8541,githubactions:S8544 # reason: installs the checked-out project itself, there is no upstream version to lock and the build must run | |
| - run: "pip install --only-binary :all: mypy==2.3.0" | |
| # Deliberately NOT installing the optional extras: the contract forces | |
| # every non-base third-party module to `Any` so the result cannot depend | |
| # on what is installed, and installing them here would only hide a | |
| # regression in that arrangement. | |
| - run: python test/verify/typing_contract_verify.py |