Skip to content

ci: install tox from a hash-pinned requirements file#293

Merged
markuslf merged 1 commit into
mainfrom
ci/hash-pin-tox
Jul 10, 2026
Merged

ci: install tox from a hash-pinned requirements file#293
markuslf merged 1 commit into
mainfrom
ci/hash-pin-tox

Conversation

@markuslf

Copy link
Copy Markdown
Member

Resolves the PinnedDependenciesID Scorecard alert (#41): pip install tox was unpinned.

Why this is not just a requirements file

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. Compiling on 3.9 pins filelock==3.19.1, and installing that with --require-hashes under 3.12 fails:

The conflict is caused by:
    The user requested filelock==3.19.1
    tox 4.30.3 depends on filelock>=3.18
    virtualenv 20.39.1 depends on filelock<4 and >=3.24.2; python_version >= "3.10"

So tox is installed under a fixed Python 3.13 and pointed at the matrix interpreter with --discover. The test envs still run under the matrix Python; only the tox process itself moves. That is what tox is designed for.

--discover takes the absolute path from actions/setup-pythons python-path output rather than relying on PATH order, because the action documents only that "the last specified version will be used as a default one" - it does not promise that an earlier version stays reachable as pythonX.Y.

Verification

In a Fedora 44 container with Python 3.13.14 and 3.9.25, tox 4.56.4 installed under 3.13:

  • with python3.9 moved off PATH and no --discover: py39-ansible215: failed with could not find python interpreter matching any of the specs py39
  • same state, with --discover /opt/py39: env builds and sys.version_info reports 3.9, congratulations :)

pip install --require-hashes -r .github/tox/requirements.txt resolves cleanly under 3.13. actionlint is clean.

Dependabot already maintains the hash-pinned .github/pre-commit/requirements.txt (#234), so a watchpoint for .github/tox keeps these hashes current too.

Also quotes the tox factor subshell, silencing a pre-existing shellcheck SC2046 warning.

`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".
@markuslf markuslf merged commit 66bc22d into main Jul 10, 2026
11 checks passed
@markuslf markuslf deleted the ci/hash-pin-tox branch July 10, 2026 14:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant