Maintenance/code cleanup 2026-05 Phase VI (pure python resolver) #4700
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: CI | |
| concurrency: | |
| group: >- | |
| ${{ github.workflow }}- | |
| ${{ github.ref_type }}- | |
| ${{ github.event.pull_request.number || github.sha }} | |
| cancel-in-progress: true | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| git-ref: | |
| description: Git Ref (Optional) | |
| required: false | |
| push: | |
| paths-ignore: | |
| - ".editorconfig" | |
| - ".gitattributes" | |
| - ".gitignore" | |
| - ".gitmodules" | |
| - "*.ini" | |
| - "*.md" | |
| - "**/*.txt" | |
| - "examples/**" | |
| - "news/**" | |
| branches: | |
| - main | |
| pull_request: | |
| paths-ignore: | |
| - ".editorconfig" | |
| - ".gitattributes" | |
| - ".gitignore" | |
| - ".gitmodules" | |
| - "*.ini" | |
| - "*.md" | |
| - "**/*.txt" | |
| - "examples/**" | |
| - "news/**" | |
| permissions: | |
| contents: read # to fetch code (actions/checkout) | |
| jobs: | |
| lint: | |
| name: Check code linting | |
| runs-on: ubuntu-latest | |
| env: | |
| PIPENV_DEFAULT_PYTHON_VERSION: ${{ matrix.python-version }} | |
| PYTHONWARNINGS: ignore:DEPRECATION | |
| PYTHONIOENCODING: "utf-8" | |
| GIT_ASK_YESNO: "false" | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: 3.x | |
| - run: | | |
| python -m pip install pre-commit | |
| pre-commit run --all-files --verbose --show-diff-on-failure | |
| vendor: | |
| name: Vendoring | |
| needs: [lint] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: 3.x | |
| - run: | | |
| python -m pip install --upgrade wheel invoke parver beautifulsoup4 towncrier requests parse hatch-fancy-pypi-readme semver | |
| python -m invoke vendoring.update | |
| tests-smoke: | |
| name: Smoke / ${{ matrix.os }} / 3.12 | |
| needs: [lint] | |
| runs-on: ${{ matrix.os }}-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [MacOS, Ubuntu, Windows] | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Disable Windows Defender for Python paths | |
| if: contains(matrix.os, 'Windows') | |
| shell: powershell | |
| run: | | |
| Add-MpPreference -ExclusionPath "C:\hostedtoolcache\windows\Python" | |
| Add-MpPreference -ExclusionPath "$env:GITHUB_WORKSPACE" | |
| Add-MpPreference -ExclusionPath "$env:USERPROFILE\.virtualenvs" | |
| Add-MpPreference -ExclusionPath "$env:LOCALAPPDATA\pip" | |
| - name: Set up Python 3.12 | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| - name: Get python path | |
| id: python-path | |
| run: | | |
| echo "path=$(python -c 'import sys; print(sys.executable)')" >> $GITHUB_OUTPUT | |
| - name: Install latest pip, setuptools, wheel | |
| run: | | |
| python -m pip install --upgrade pip setuptools wheel | |
| - name: Install dependencies | |
| env: | |
| PIPENV_DEFAULT_PYTHON_VERSION: "3.12" | |
| PYTHONWARNINGS: ignore:DEPRECATION | |
| PYTHONIOENCODING: "utf-8" | |
| GIT_ASK_YESNO: "false" | |
| run: | | |
| git submodule sync | |
| git submodule update --init --recursive | |
| python -m pip install -e . --upgrade | |
| pipenv install --deploy --dev --python=3.12 | |
| pipenv run python -m pip install -e ".[tests,dev]" --upgrade | |
| - name: Run pypiserver with pipenv (Python 3.10+) | |
| run: | | |
| pipenv run pypi-server --version | |
| pipenv run pypi-server run -v --host=0.0.0.0 --port=8080 --hash-algo=sha256 --disable-fallback --welcome /dev/null ./tests/pypi/ ./tests/fixtures & | |
| if: (contains(matrix.os, 'Ubuntu') || contains(matrix.os, 'MacOS')) | |
| - name: Run pypiserver with pipenv on Windows (Python 3.10+) | |
| run: | | |
| pipenv run pypi-server --version | |
| cmd /c start pipenv run pypi-server run -v --host=0.0.0.0 --port=8080 --hash-algo=sha256 --disable-fallback --welcome NUL ./tests/pypi/ ./tests/fixtures | |
| if: contains(matrix.os, 'Windows') | |
| - name: Run tests | |
| env: | |
| PIPENV_DEFAULT_PYTHON_VERSION: "3.12" | |
| PYTHONWARNINGS: ignore:DEPRECATION | |
| PIPENV_NOSPIN: "1" | |
| CI: "1" | |
| GIT_ASK_YESNO: "false" | |
| PYPI_VENDOR_DIR: "./tests/pypi/" | |
| PYTHONIOENCODING: "utf-8" | |
| GIT_SSH_COMMAND: ssh -o StrictHostKeyChecking=accept-new -o CheckHostIP=no | |
| run: | | |
| pipenv run pytest -ra -n auto -v --fulltrace tests | |
| tests: | |
| name: ${{matrix.os}} / ${{ matrix.python-version }} | |
| needs: [tests-smoke] | |
| runs-on: ${{ matrix.os }}-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # Note: Python 3.15 removed until upstream pip supports it | |
| # (pip's typing_extensions uses typing.no_type_check_decorator which was removed in 3.15) | |
| python-version: ["3.10", 3.11, 3.13, 3.14] | |
| os: [MacOS, Ubuntu, Windows] | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Disable Windows Defender for Python paths | |
| if: contains(matrix.os, 'Windows') | |
| shell: powershell | |
| run: | | |
| Add-MpPreference -ExclusionPath "C:\hostedtoolcache\windows\Python" | |
| Add-MpPreference -ExclusionPath "$env:GITHUB_WORKSPACE" | |
| Add-MpPreference -ExclusionPath "$env:USERPROFILE\.virtualenvs" | |
| Add-MpPreference -ExclusionPath "$env:LOCALAPPDATA\pip" | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| allow-prereleases: true | |
| check-latest: true | |
| - name: Get python path | |
| id: python-path | |
| run: | | |
| echo "path=$(python -c 'import sys; print(sys.executable)')" >> $GITHUB_OUTPUT | |
| - name: Install latest pip, setuptools, wheel | |
| run: | | |
| python -m pip install --upgrade pip setuptools wheel | |
| - name: Install dependencies | |
| env: | |
| PIPENV_DEFAULT_PYTHON_VERSION: ${{ matrix.python-version }} | |
| PYTHONWARNINGS: ignore:DEPRECATION | |
| PYTHONIOENCODING: "utf-8" | |
| GIT_ASK_YESNO: "false" | |
| run: | | |
| git submodule sync | |
| git submodule update --init --recursive | |
| python -m pip install -e . --upgrade | |
| pipenv install --deploy --dev --python=${{ matrix.python-version }} | |
| pipenv run python -m pip install -e ".[tests,dev]" --upgrade | |
| - name: Run pypiserver with pipenv (Python 3.10+) | |
| run: | | |
| pipenv run pypi-server --version | |
| pipenv run pypi-server run -v --host=0.0.0.0 --port=8080 --hash-algo=sha256 --disable-fallback --welcome /dev/null ./tests/pypi/ ./tests/fixtures & | |
| if: (contains(matrix.os, 'Ubuntu') || contains(matrix.os, 'macOS')) | |
| - name: Run pypiserver with pipenv on Windows (Python 3.10+) | |
| run: | | |
| pipenv run pypi-server --version | |
| cmd /c start pipenv run pypi-server run -v --host=0.0.0.0 --port=8080 --hash-algo=sha256 --disable-fallback --welcome NUL ./tests/pypi/ ./tests/fixtures | |
| if: contains(matrix.os, 'Windows') | |
| - name: Run tests | |
| env: | |
| PIPENV_DEFAULT_PYTHON_VERSION: ${{ matrix.python-version }} | |
| PYTHONWARNINGS: ignore:DEPRECATION | |
| PIPENV_NOSPIN: "1" | |
| CI: "1" | |
| GIT_ASK_YESNO: "false" | |
| PYPI_VENDOR_DIR: "./tests/pypi/" | |
| PYTHONIOENCODING: "utf-8" | |
| GIT_SSH_COMMAND: ssh -o StrictHostKeyChecking=accept-new -o CheckHostIP=no | |
| run: | | |
| pipenv run pytest -ra -n auto -v --fulltrace tests | |
| tests-pure-python-backend: | |
| # Initiative G phase 3b (T_CI1): run the full pipenv test suite | |
| # under ``PIPENV_RESOLVER=pure-python`` to dogfood the new | |
| # pure-Python resolver backend. Non-blocking | |
| # (``continue-on-error: true``) — the acceptance gate is "matrix | |
| # runs and produces a result", not "matrix passes", until the | |
| # backend reaches feature parity with pip. Ubuntu + 3.12 only at | |
| # this phase to keep CI minutes reasonable; widen the matrix once | |
| # the backend is consistently green. | |
| name: Tests (pure-python backend) / Ubuntu / 3.12 | |
| needs: [tests-smoke] | |
| runs-on: ubuntu-latest | |
| continue-on-error: true | |
| timeout-minutes: 45 | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Set up Python 3.12 | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| - name: Install latest pip, setuptools, wheel | |
| run: | | |
| python -m pip install --upgrade pip setuptools wheel | |
| - name: Install dependencies | |
| env: | |
| PIPENV_DEFAULT_PYTHON_VERSION: "3.12" | |
| PYTHONWARNINGS: ignore:DEPRECATION | |
| PYTHONIOENCODING: "utf-8" | |
| GIT_ASK_YESNO: "false" | |
| run: | | |
| git submodule sync | |
| git submodule update --init --recursive | |
| python -m pip install -e . --upgrade | |
| pipenv install --deploy --dev --python=3.12 | |
| pipenv run python -m pip install -e ".[tests,dev]" --upgrade | |
| - name: Run pypiserver with pipenv | |
| run: | | |
| pipenv run pypi-server --version | |
| pipenv run pypi-server run -v --host=0.0.0.0 --port=8080 --hash-algo=sha256 --disable-fallback --welcome /dev/null ./tests/pypi/ ./tests/fixtures & | |
| - name: Run tests with pure-python backend | |
| env: | |
| PIPENV_DEFAULT_PYTHON_VERSION: "3.12" | |
| PYTHONWARNINGS: ignore:DEPRECATION | |
| PIPENV_NOSPIN: "1" | |
| CI: "1" | |
| GIT_ASK_YESNO: "false" | |
| PYPI_VENDOR_DIR: "./tests/pypi/" | |
| PYTHONIOENCODING: "utf-8" | |
| GIT_SSH_COMMAND: ssh -o StrictHostKeyChecking=accept-new -o CheckHostIP=no | |
| # T_CI1 (Initiative G phase 3b): select the pure-Python | |
| # backend via the documented env-var path. Honoured by | |
| # ``pipenv.resolver.core._selected_backend_name`` after the | |
| # parent-side CLI / Pipfile chain falls through. | |
| PIPENV_RESOLVER: pure-python | |
| run: | | |
| pipenv run pytest -ra -n auto -v --fulltrace tests | |
| resolver-module-coverage: | |
| # Initiative G phase 1 (T17): enforce per-module coverage floors | |
| # for the new pure-Python simple-API client surface. Without this | |
| # gate the 90-100% coverage claims in T11-T16 would silently | |
| # regress over time. The default ``addopts = -ra --no-cov`` in | |
| # pyproject.toml keeps the regular test workflow coverage-free; | |
| # this step overrides it to enable ``--cov``. | |
| name: Resolver-module coverage gate | |
| needs: [lint] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip setuptools wheel | |
| python -m pip install -e ".[tests]" --upgrade | |
| python -m pip install coverage pytest-cov | |
| - name: Run resolver-module suite with coverage gate | |
| run: | | |
| python -m pytest \ | |
| tests/unit/test_candidate.py \ | |
| tests/unit/test_resolver_auth.py \ | |
| tests/unit/test_manifest_cache.py \ | |
| tests/unit/test_pep691_parser.py \ | |
| tests/unit/test_pep691_client.py \ | |
| tests/unit/test_parallel_fetcher.py \ | |
| --cov=pipenv.resolver.candidate \ | |
| --cov=pipenv.resolver.auth \ | |
| --cov=pipenv.resolver.manifest_cache \ | |
| --cov=pipenv.resolver.pep691 \ | |
| --cov=pipenv.resolver.pep691_types \ | |
| --cov=pipenv.resolver.fetcher \ | |
| --cov-fail-under=90 \ | |
| --override-ini="addopts=-ra" | |
| benchmark: | |
| name: Package Manager Benchmark | |
| needs: [lint] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.11" | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update -qq | |
| sudo apt-get install -y libxmlsec1-dev librdkafka-dev | |
| - name: Install benchmark utilities | |
| run: pip install csv2md | |
| - name: Run benchmark suite | |
| working-directory: benchmarks | |
| run: python benchmark.py | |
| - name: Display benchmark results | |
| working-directory: benchmarks | |
| run: | | |
| if [ -f stats.csv ]; then | |
| csv2md stats.csv >> $GITHUB_STEP_SUMMARY | |
| fi | |
| - uses: actions/upload-artifact@v5 | |
| with: | |
| name: pipenv-benchmark-stats | |
| path: | | |
| benchmarks/stats.csv | |
| benchmarks/benchmark-results.json | |
| retention-days: 30 | |
| build: | |
| name: Build Package | |
| needs: [lint] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: 3.x | |
| - run: pip install -U build twine | |
| - run: | | |
| python -m build | |
| twine check dist/* |