From 3719e318d19486d423ca9855768379cc1ac73c00 Mon Sep 17 00:00:00 2001 From: Markus Frei Date: Fri, 10 Jul 2026 16:34:08 +0200 Subject: [PATCH] ci: install tox from a hash-pinned requirements file `pip install tox` was unpinned, which OpenSSF Scorecard flags as PinnedDependenciesID (alert #41). A single hash-pinned file cannot serve the whole 3.9-3.13 matrix: from Python 3.10 on, virtualenv requires `filelock >= 3.24.2`, and no filelock that new supports 3.9, so `pip install --require-hashes` fails on one end or the other. tox is therefore installed under a fixed Python 3.13 and pointed at the matrix interpreter with `--discover`, using the absolute path that `actions/setup-python` reports. The test envs still run under the matrix Python. `--discover` is used instead of relying on PATH order because actions/setup-python does not document that an earlier version stays reachable as `pythonX.Y` once a later one is set up. Also quotes the tox factor subshell, silencing a pre-existing shellcheck SC2046 warning. Verified in a Fedora 44 container: tox 4.56.4 running under Python 3.13 builds and runs a py39 env with Python 3.9.25 when that interpreter is off PATH and passed via `--discover`; without it, tox fails with "could not find python interpreter matching any of the specs py39". --- .github/dependabot.yml | 8 ++++ .github/tox/requirements.in | 1 + .github/tox/requirements.txt | 64 +++++++++++++++++++++++++++++ .github/workflows/lf-unit-tests.yml | 20 +++++++-- 4 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 .github/tox/requirements.in create mode 100644 .github/tox/requirements.txt diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 38a82315..a28bdbb3 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -19,3 +19,11 @@ updates: day: 'friday' time: '05:00' timezone: 'Etc/UTC' + + - package-ecosystem: 'pip' + directory: '/.github/tox' + schedule: + interval: 'weekly' + day: 'friday' + time: '05:00' + timezone: 'Etc/UTC' diff --git a/.github/tox/requirements.in b/.github/tox/requirements.in new file mode 100644 index 00000000..1853ec0a --- /dev/null +++ b/.github/tox/requirements.in @@ -0,0 +1 @@ +tox==4.56.4 diff --git a/.github/tox/requirements.txt b/.github/tox/requirements.txt new file mode 100644 index 00000000..938a14fa --- /dev/null +++ b/.github/tox/requirements.txt @@ -0,0 +1,64 @@ +# +# This file is autogenerated by pip-compile with Python 3.13 +# by the following command: +# +# pip-compile --generate-hashes --output-file=requirements.txt --strip-extras requirements.in +# +cachetools==7.1.4 \ + --hash=sha256:323dc4127934744db5b54eb4924482d7edafbf9554e820d1531c2e08c0e4ef54 \ + --hash=sha256:437f55a4e0c1b01a4f3077cc470e6991d47430970e36fbcb77e2be0df4fc1cd6 + # via tox +colorama==0.4.6 \ + --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ + --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 + # via tox +distlib==0.4.3 \ + --hash=sha256:4b0ce306c966eb73bc3a7b6abad017c556dadd92c44701562cd528ac7fde4d5b \ + --hash=sha256:f152097224a0ae24be5a0f6bae1b9359af82133bce63f98a95f86cae1aede9ed + # via virtualenv +filelock==3.29.7 \ + --hash=sha256:5b481979797ae69e72f0b389d89a80bdd585c260c5b3f1fb9c0a5ba9bb3f195d \ + --hash=sha256:987db6f789a3a2a59f55081801b2b3697cb97e2a736b5f1a9e99b559285fbc51 + # via + # python-discovery + # tox + # virtualenv +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 + # via + # pyproject-api + # tox +platformdirs==4.10.0 \ + --hash=sha256:31e761a6a0ca04faf7353ea759bdba55652be214725111e5aac52dfa29d4bef7 \ + --hash=sha256:fb516cdb12eb0d857d0cd85a7c57cea4d060bee4578d6cf5a14dfdf8cbf8784a + # via + # python-discovery + # tox + # virtualenv +pluggy==1.6.0 \ + --hash=sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3 \ + --hash=sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 + # via tox +pyproject-api==1.10.1 \ + --hash=sha256:c2b2726bd7aa9217b6c50b621fef5b2ae5def4d55b779c9e0694c15e0a8517ba \ + --hash=sha256:fa9e6f66c35b5017e909825d8f2b5d5482ea699d7be809d21c03bd1f7317f36a + # via tox +python-discovery==1.4.4 \ + --hash=sha256:5cad33982d412c1f3ffb8f9ca4ea292c9680bca3942451d30b69c37fce53a4a3 \ + --hash=sha256:abebe9120b43453b68c908acfb1e72a19d1a959ed2cb620ad38fc57d08056dbe + # via + # tox + # virtualenv +tomli-w==1.2.0 \ + --hash=sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90 \ + --hash=sha256:2dd14fac5a47c27be9cd4c976af5a12d87fb1f0b4512f81d69cce3b35ae25021 + # via tox +tox==4.56.4 \ + --hash=sha256:53bac88382b9638a5ce40fbaddd6076e1c8f638751af7bf8e759392c953df2f0 \ + --hash=sha256:d49e371119ebfafb15054ad7ccff3d03027ccb65195fae3ac656b431b5524055 + # via -r requirements.in +virtualenv==21.6.0 \ + --hash=sha256:bce9d097950fef9d81129b333babfb7767072850c2f1acce0ec536708401bfd1 \ + --hash=sha256:e18a4d750f2b64dea73e72ffde3922f3c52365fabdc8157ebd3da20d031c4734 + # via tox diff --git a/.github/workflows/lf-unit-tests.yml b/.github/workflows/lf-unit-tests.yml index 95120e5b..be1389db 100644 --- a/.github/workflows/lf-unit-tests.yml +++ b/.github/workflows/lf-unit-tests.yml @@ -34,15 +34,29 @@ jobs: - name: 'Checkout repository' uses: 'actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0' # v7.0.0 - - name: 'Set up Python' + # The interpreter tox builds the test env for. Its absolute path is + # handed to tox via `--discover` below, so this step does not rely on + # the executable staying on PATH once the next step runs. + - name: 'Set up the target Python ${{ matrix.python-version }}' + id: 'target-python' uses: 'actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1' # v6.3.0 with: python-version: '${{ matrix.python-version }}' + # The interpreter tox itself runs under. Pinned to one version so that + # a single hash-pinned requirements file covers the whole matrix: + # tox cannot be resolved for 3.9 and 3.10+ at once, because virtualenv + # requires `filelock >= 3.24.2` from 3.10 on and no filelock that new + # supports 3.9. Listed last, so `python` and `pip` refer to it. + - name: 'Set up the Python that runs tox' + uses: 'actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1' # v6.3.0 + with: + python-version: '3.13' + - name: 'Install tox' - run: 'pip install tox' + run: 'pip install --require-hashes --requirement .github/tox/requirements.txt' - name: 'Run tox for this Python (all matching ansible-core envs)' # `-f pyXYZ` selects every tox env carrying this Python's factor, # e.g. py311 -> py311-ansible215/216/217/218. - run: 'tox -f py$(echo "${{ matrix.python-version }}" | tr -d ".")' + run: 'tox --discover "${{ steps.target-python.outputs.python-path }}" -f "py$(echo "${{ matrix.python-version }}" | tr -d ".")"'