From 2b464c8263f22e0aed64cd7fa63c4dd86ddf1d3c Mon Sep 17 00:00:00 2001 From: Dmitrii Gridnev Date: Thu, 14 May 2026 09:46:02 +0300 Subject: [PATCH] build: bootstrap pip>=26.0 with ISO datetime cutoff to fix Python 3.9 CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "P3D" relative-duration form of PIP_UPLOADED_PRIOR_TO requires pip>=26.1, but pip 26.1 itself requires Python>=3.10. As a result every job running against Python 3.9 — including the test matrix and the build-n-publish step pinned to 3.9 — failed with "No matching distribution found for pip>=26.1" the moment the supply-chain guard was introduced. The failure only surfaced in PRs that touched a reporter directory, because the test job's paths-filter gate skipped the install step on unrelated pushes. Compute the cutoff as an ISO 8601 datetime in each job and lower the required pip to >=26.0, which is available on Python 3.9 through 3.13 and accepts the ISO form. The env-unset bootstrap is kept to guard against older seeded pips in fresh venvs that would reject the PIP_UPLOADED_PRIOR_TO env var as an unknown flag. --- .github/workflows/pythonpackage.yml | 43 +++++++++++++++++++---------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index c2a6eab7..5a06a60c 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -2,10 +2,10 @@ name: Python package on: [ push ] -env: - # Supply-chain protection: refuse PyPI packages uploaded less than 3 days ago. - # Honored by pip>=26.1 (relative durations); silently ignored by older pip. - PIP_UPLOADED_PRIOR_TO: "P3D" +# Supply-chain protection: refuse PyPI packages uploaded less than 3 days ago. +# The cutoff is computed per job as an ISO 8601 datetime (see the "Compute +# supply-chain cutoff" step). pip 26.1 added the relative-duration form +# ("P3D"), but that requires Python>=3.10 and we still test on 3.9. jobs: test: @@ -43,13 +43,18 @@ jobs: uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + - name: Compute supply-chain cutoff + if: steps.filter.outputs.changes == 'true' + run: | + cutoff=$(date -u -d '3 days ago' +%Y-%m-%dT%H:%M:%SZ) + echo "PIP_UPLOADED_PRIOR_TO=$cutoff" >> "$GITHUB_ENV" - name: Install dependencies if: steps.filter.outputs.changes == 'true' run: | - # Bootstrap with PIP_UPLOADED_PRIOR_TO unset: the seeded pip may be - # 26.0, which validates the value but only accepts ISO datetimes — - # the P3D form was added in 26.1. - env -u PIP_UPLOADED_PRIOR_TO python -m pip install --upgrade 'pip>=26.1' + # Bootstrap with PIP_UPLOADED_PRIOR_TO unset: a seeded pip older than + # 26.0 would treat the env var as an unknown --uploaded-prior-to flag + # and abort. + env -u PIP_UPLOADED_PRIOR_TO python -m pip install --upgrade 'pip>=26.0' pip install tox tox-gh-actions - name: Run tox if: steps.filter.outputs.changes == 'true' @@ -66,9 +71,14 @@ jobs: with: python-version: '3.12' + - name: Compute supply-chain cutoff + run: | + cutoff=$(date -u -d '3 days ago' +%Y-%m-%dT%H:%M:%SZ) + echo "PIP_UPLOADED_PRIOR_TO=$cutoff" >> "$GITHUB_ENV" + - name: Install reporters-validator run: | - env -u PIP_UPLOADED_PRIOR_TO python -m pip install --upgrade 'pip>=26.1' + env -u PIP_UPLOADED_PRIOR_TO python -m pip install --upgrade 'pip>=26.0' pip install git+https://github.com/qase-tms/reporters-validator.git - name: Download report schemas @@ -77,7 +87,7 @@ jobs: - name: Validate Pytest reporter run: | python -m venv /tmp/venv-pytest - env -u PIP_UPLOADED_PRIOR_TO /tmp/venv-pytest/bin/python -m pip install --upgrade 'pip>=26.1' + env -u PIP_UPLOADED_PRIOR_TO /tmp/venv-pytest/bin/python -m pip install --upgrade 'pip>=26.0' /tmp/venv-pytest/bin/pip install -q \ ./qase-api-client ./qase-api-v2-client ./qase-python-commons ./qase-pytest @@ -93,7 +103,7 @@ jobs: - name: Validate Behave reporter run: | python -m venv /tmp/venv-behave - env -u PIP_UPLOADED_PRIOR_TO /tmp/venv-behave/bin/python -m pip install --upgrade 'pip>=26.1' + env -u PIP_UPLOADED_PRIOR_TO /tmp/venv-behave/bin/python -m pip install --upgrade 'pip>=26.0' /tmp/venv-behave/bin/pip install -q \ ./qase-api-client ./qase-api-v2-client ./qase-python-commons ./qase-behave @@ -111,7 +121,7 @@ jobs: - name: Validate Robot Framework reporter run: | python -m venv /tmp/venv-robot - env -u PIP_UPLOADED_PRIOR_TO /tmp/venv-robot/bin/python -m pip install --upgrade 'pip>=26.1' + env -u PIP_UPLOADED_PRIOR_TO /tmp/venv-robot/bin/python -m pip install --upgrade 'pip>=26.0' /tmp/venv-robot/bin/pip install -q \ ./qase-api-client ./qase-api-v2-client ./qase-python-commons ./qase-robotframework \ robotframework @@ -130,7 +140,7 @@ jobs: - name: Validate Tavern reporter run: | python -m venv /tmp/venv-tavern - env -u PIP_UPLOADED_PRIOR_TO /tmp/venv-tavern/bin/python -m pip install --upgrade 'pip>=26.1' + env -u PIP_UPLOADED_PRIOR_TO /tmp/venv-tavern/bin/python -m pip install --upgrade 'pip>=26.0' /tmp/venv-tavern/bin/pip install -q \ ./qase-api-client ./qase-api-v2-client ./qase-python-commons ./qase-tavern \ tavern @@ -170,10 +180,15 @@ jobs: uses: actions/setup-python@v5 with: python-version: 3.9 + - name: Compute supply-chain cutoff + if: contains(github.event.ref, matrix.prefix) + run: | + cutoff=$(date -u -d '3 days ago' +%Y-%m-%dT%H:%M:%SZ) + echo "PIP_UPLOADED_PRIOR_TO=$cutoff" >> "$GITHUB_ENV" - name: Install build dependencies if: contains(github.event.ref, matrix.prefix) run: | - env -u PIP_UPLOADED_PRIOR_TO python -m pip install --upgrade 'pip>=26.1' + env -u PIP_UPLOADED_PRIOR_TO python -m pip install --upgrade 'pip>=26.0' pip install --upgrade setuptools wheel build - name: Build the package if: contains(github.event.ref, matrix.prefix)