Fix PyPI agent apply patching only one installed copy (#529, #501) #354
Workflow file for this run
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: PDM patch compatibility | |
| # Native PDM installer matrix: builds the CLI and the capstone test binary | |
| # once per OS, bootstraps pinned PDM releases with uv, and runs | |
| # `scripts/backtest-pdm.py` — hosted, vendored and agent mode against the | |
| # public urllib3 free patch, verifying the INSTALLED bytes, lock/manifest | |
| # stability, hash rejection and rollback. No Socket API token is needed. See | |
| # docs/testing/pdm-compatibility.md. | |
| on: | |
| pull_request: | |
| paths: | |
| - '.github/actions/upload-artifact/**' | |
| - '.github/workflows/pdm-compatibility.yml' | |
| - 'scripts/backtest-pdm.py' | |
| - 'crates/socket-patch-core/src/utils/pdm_lock.rs' | |
| - 'crates/socket-patch-core/src/patch/redirect/**' | |
| - 'crates/socket-patch-core/src/vendor/pypi*.rs' | |
| - 'crates/socket-patch-core/src/vendor/common.rs' | |
| - 'crates/socket-patch-core/src/vendor/lock_inventory/**' | |
| - 'crates/socket-patch-cli/src/commands/scan/**' | |
| - 'crates/socket-patch-cli/src/commands/rollback.rs' | |
| - 'crates/socket-patch-core/tests/fixtures/pdm-native/**' | |
| - 'crates/socket-patch-core/src/vex/**' | |
| - 'crates/socket-patch-cli/src/commands/vex*.rs' | |
| - 'crates/socket-patch-cli/tests/e2e_vex_build/main.rs' | |
| - 'crates/socket-patch-cli/tests/e2e_vex_build/pdm.rs' | |
| - 'crates/socket-patch-cli/tests/vex_pypi_real_common/**' | |
| # The capstone skips the cells ci.yml's e2e rows run. | |
| - '.github/workflows/ci.yml' | |
| push: | |
| branches: [main] | |
| paths: | |
| - 'scripts/backtest-pdm.py' | |
| - 'crates/socket-patch-core/src/utils/pdm_lock.rs' | |
| - 'crates/socket-patch-core/src/patch/redirect/pdm.rs' | |
| - 'crates/socket-patch-core/src/vendor/pypi_pdm.rs' | |
| workflow_dispatch: | |
| inputs: | |
| versions: | |
| description: 'Space-separated PDM versions (empty = the required matrix below)' | |
| required: false | |
| default: '' | |
| shapes: | |
| description: 'Space-separated shapes (empty = every shape)' | |
| required: false | |
| default: '' | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: pdm-compat-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| env: | |
| SOCKET_NO_CONFIG: '1' | |
| SOCKET_NO_UPDATE_CHECK: '1' | |
| PDM_CHECK_UPDATE: 'false' | |
| jobs: | |
| build: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest] | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 30 | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 | |
| with: | |
| key: pdm-compat | |
| save-if: ${{ github.ref == 'refs/heads/main' }} | |
| - name: Compile the CLI and the capstone once | |
| run: | | |
| set -euo pipefail | |
| cargo test --locked -p socket-patch-cli --test e2e_vex_build --no-run --message-format=json-render-diagnostics > target-build.json | |
| python3 - <<'PY' | |
| import json, pathlib, shutil | |
| dest = pathlib.Path('target/pdm-e2e') | |
| dest.mkdir(parents=True, exist_ok=True) | |
| shutil.copy2('target/debug/socket-patch', dest / 'socket-patch') | |
| for line in pathlib.Path('target-build.json').read_text().splitlines(): | |
| item = json.loads(line) | |
| if item.get('target', {}).get('name') == 'e2e_vex_build' and item.get('executable'): | |
| shutil.copy2(item['executable'], dest / 'e2e_vex_build') | |
| assert (dest / 'e2e_vex_build').is_file() | |
| PY | |
| - uses: ./.github/actions/upload-artifact | |
| with: | |
| name: pdm-cli-${{ matrix.os }} | |
| path: target/pdm-e2e/ | |
| if-no-files-found: error | |
| retention-days: 7 | |
| native: | |
| needs: build | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # Every stable PDM major family (0.x, 1.x, 2.x) and each 2.x lock-format | |
| # boundary on Linux; macOS samples the ends of the range. No Windows: | |
| # the harness bootstraps PDM through a POSIX venv layout (bin/pdm), so | |
| # every Windows cell skipped; backtest-pdm.py now fails such a cell. | |
| os: [ubuntu-latest] | |
| pdm: ['0.12.3', '1.15.5', '2.0.3', '2.1.5', '2.3.4', '2.6.1', '2.7.4', '2.8.2', '2.9.3', '2.10.4', '2.11.2', '2.17.3', '2.20.1', '2.22.4', '2.25.9', '2.29.2'] | |
| include: | |
| - { os: macos-latest, pdm: '0.12.3' } | |
| - { os: macos-latest, pdm: '2.8.2' } | |
| - { os: macos-latest, pdm: '2.29.2' } | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 45 | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 | |
| with: | |
| pattern: pdm-cli-${{ matrix.os }}* | |
| merge-multiple: true | |
| path: native-cli | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 | |
| with: | |
| python-version: '3.12' | |
| # uv bootstraps every pinned PDM release (and its interpreter) itself; | |
| # pinning uv keeps the bootstrap reproducible across runner images. | |
| - run: python -m pip install uv==0.11.19 | |
| - name: Exercise the native PDM installers | |
| shell: bash | |
| env: | |
| PDM_VERSION: ${{ matrix.pdm }} | |
| VERSIONS_OVERRIDE: ${{ github.event.inputs.versions }} | |
| SHAPES_OVERRIDE: ${{ github.event.inputs.shapes }} | |
| run: | | |
| chmod +x native-cli/socket-patch* || true | |
| cli="native-cli/socket-patch" | |
| if [ "$RUNNER_OS" = "Windows" ]; then cli="native-cli/socket-patch.exe"; fi | |
| versions="$PDM_VERSION" | |
| if [ -n "$VERSIONS_OVERRIDE" ]; then versions="$VERSIONS_OVERRIDE"; fi | |
| shapes_arg=() | |
| if [ -n "$SHAPES_OVERRIDE" ]; then shapes_arg=(--shapes $SHAPES_OVERRIDE); fi | |
| python3 scripts/backtest-pdm.py \ | |
| --socket-patch "$cli" \ | |
| --socket-patch-revision "$GITHUB_SHA" \ | |
| --output native-pdm \ | |
| --versions $versions \ | |
| --modes hosted vendored agent \ | |
| "${shapes_arg[@]}" \ | |
| --jobs 3 | |
| - uses: ./.github/actions/upload-artifact | |
| if: always() | |
| with: | |
| name: pdm-results-${{ matrix.os }}-${{ matrix.pdm }} | |
| path: | | |
| native-pdm/summary.json | |
| native-pdm/summary.md | |
| native-pdm/tool-logs/*.log | |
| native-pdm/original/**/*.log | |
| native-pdm/original/**/pdm.lock | |
| native-pdm/original/**/pyproject.toml | |
| native-pdm/cases/**/result.json | |
| native-pdm/cases/**/cli-output.json | |
| native-pdm/cases/**/pdm.lock | |
| native-pdm/cases/**/*.log | |
| retention-days: 14 | |
| # The hermetic Rust capstone (wiremock Socket API that also serves the | |
| # hosted wheel) over every PDM release the backtest covers: real hosted + | |
| # vendored flows ending in the manifest-less VEX matrix; refused lock | |
| # formats (3.1, 4.0-4.2) must attest nothing. The cells ci.yml's `e2e` | |
| # job runs on every PR and main push are excluded here | |
| # (scripts/tests/test_ci_e2e_tiers.py keeps the two lists in step). | |
| capstone: | |
| needs: build | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest] | |
| pdm: ['0.12.3', '1.0.0', '1.4.5', '1.8.5', '1.15.5', '2.0.3', '2.7.4', '2.8.2', '2.10.4', '2.11.2', '2.17.3', '2.20.1', '2.22.4', '2.25.9', '2.29.2'] | |
| exclude: | |
| - {os: ubuntu-latest, pdm: '1.4.5'} | |
| - {os: ubuntu-latest, pdm: '1.15.5'} | |
| - {os: ubuntu-latest, pdm: '2.7.4'} | |
| - {os: ubuntu-latest, pdm: '2.8.2'} | |
| - {os: ubuntu-latest, pdm: '2.25.9'} | |
| - {os: ubuntu-latest, pdm: '2.29.2'} | |
| - {os: macos-latest, pdm: '2.29.2'} | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 30 | |
| steps: | |
| # The binaries resolve fixtures through the build job's checkout path, | |
| # which is the same on every runner of one OS. | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 | |
| with: | |
| pattern: pdm-cli-${{ matrix.os }}* | |
| merge-multiple: true | |
| path: target/pdm-e2e | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 | |
| with: | |
| python-version: '3.12' | |
| - run: python -m pip install uv==0.11.19 | |
| - name: Real-PDM hosted + vendored flows with manifest-less VEX | |
| env: | |
| SOCKET_PATCH_PDM_E2E_REQUIRED: '1' | |
| SOCKET_PATCH_PDM_E2E_VERSION: ${{ matrix.pdm }} | |
| run: | | |
| set -euo pipefail | |
| chmod +x target/pdm-e2e/* | |
| mkdir -p target/debug target/tmp | |
| cp target/pdm-e2e/socket-patch target/debug/socket-patch | |
| cd crates/socket-patch-cli | |
| export CARGO_MANIFEST_DIR="$PWD" | |
| ../../target/pdm-e2e/e2e_vex_build 'pdm::' --ignored |