Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
496 changes: 351 additions & 145 deletions .github/workflows/ci.yml

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions .github/workflows/npm-compatibility.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,28 @@ name: npm hosted/vendored compatibility
# installs one pinned npm and runs them. See docs/testing/npm-compatibility.md.

on:
# PRs: any crate source, but only the test files these capstones
# compile (a later `!` pattern excludes, a later plain one re-includes).
# Main pushes stay unfiltered.
pull_request:
paths:
- '.github/actions/upload-artifact/**'
- 'Cargo.lock'
- 'Cargo.toml'
- 'rust-toolchain.toml'
- '.cargo/config.toml'
- '.github/workflows/npm-compatibility.yml'
- 'docs/testing/npm-compatibility.md'
- 'crates/**'
- '!crates/**/*.md'
- '!crates/socket-patch-node/**'
- '!crates/socket-patch-core/tests/**'
- '!crates/socket-patch-cli/tests/**'
- 'crates/socket-patch-cli/tests/vex_e2e_common/**'
- 'crates/socket-patch-cli/tests/e2e_redirect_npm_build.rs'
- 'crates/socket-patch-cli/tests/e2e_vendor_npm_build.rs'
- 'crates/socket-patch-cli/tests/npm_e2e_common/**'
- 'crates/socket-patch-cli/tests/common/cache_env.rs'
push:
branches: [main]
workflow_dispatch:
Expand Down
75 changes: 56 additions & 19 deletions .github/workflows/pdm-compatibility.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
name: PDM patch compatibility

# Native PDM installer matrix: builds the CLI 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.
# 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:
Expand All @@ -25,6 +26,8 @@ on:
- '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:
Expand Down Expand Up @@ -60,7 +63,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
timeout-minutes: 30
steps:
Expand All @@ -70,13 +73,26 @@ jobs:
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
key: pdm-compat
- run: cargo build --locked -p socket-patch-cli
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/debug/socket-patch
target/debug/socket-patch.exe
path: target/pdm-e2e/
if-no-files-found: error
retention-days: 7

Expand All @@ -86,8 +102,10 @@ jobs:
fail-fast: false
matrix:
# Every stable PDM major family (0.x, 1.x, 2.x) and each 2.x lock-format
# boundary, on Linux and Windows; macOS samples the ends of the range.
os: [ubuntu-latest, windows-latest]
# 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' }
Expand Down Expand Up @@ -152,25 +170,37 @@ jobs:
# 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.
# 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: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
key: pdm-vex-capstone
# Only main writes the cache: 30 PR matrix cells saving would churn
# the repo's 10 GiB budget (ci.yml's rust-cache note).
save-if: ${{ github.ref == 'refs/heads/main' }}
pattern: pdm-cli-${{ matrix.os }}*
merge-multiple: true
path: target/pdm-e2e
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: '3.12'
Expand All @@ -179,4 +209,11 @@ jobs:
env:
SOCKET_PATCH_PDM_E2E_REQUIRED: '1'
SOCKET_PATCH_PDM_E2E_VERSION: ${{ matrix.pdm }}
run: cargo test --locked -p socket-patch-cli --test e2e_vex_build -- 'pdm::' --ignored
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
19 changes: 19 additions & 0 deletions .github/workflows/pnpm-compatibility.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
name: pnpm hosted compatibility

on:
# PRs: any crate source, but only the test files these capstones
# compile (a later `!` pattern excludes, a later plain one re-includes).
# Main pushes stay unfiltered.
pull_request:
paths:
- '.github/actions/upload-artifact/**'
- 'Cargo.lock'
- 'Cargo.toml'
- 'rust-toolchain.toml'
- '.cargo/config.toml'
- '.github/workflows/pnpm-compatibility.yml'
- 'crates/**'
- '!crates/**/*.md'
- '!crates/socket-patch-node/**'
- '!crates/socket-patch-core/tests/**'
- '!crates/socket-patch-cli/tests/**'
- 'crates/socket-patch-cli/tests/vex_e2e_common/**'
- 'crates/socket-patch-cli/tests/e2e_redirect_pnpm_build.rs'
- 'crates/socket-patch-cli/tests/e2e_vendor_pnpm_build.rs'
- 'crates/socket-patch-cli/tests/common/cache_env.rs'
push:
branches: [main]
workflow_dispatch:
Expand Down
19 changes: 19 additions & 0 deletions .github/workflows/vlt-compatibility.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ on:
- 'scripts/install-vlt.sh'
- 'scripts/vlt-historical-integrity.json'
- 'scripts/gen-vlt-collation-golden.mjs'
- 'scripts/ci-vlt-proof-suites.py'
- '.github/workflows/ci.yml'
- 'scripts/tests/test_ci_vlt_rows.py'
push:
branches: [main]
paths:
Expand Down Expand Up @@ -89,6 +92,9 @@ on:
- 'scripts/install-vlt.sh'
- 'scripts/vlt-historical-integrity.json'
- 'scripts/gen-vlt-collation-golden.mjs'
- 'scripts/ci-vlt-proof-suites.py'
- '.github/workflows/ci.yml'
- 'scripts/tests/test_ci_vlt_rows.py'
schedule:
# Nightly: vlt releases and the production service drift with no PR open.
- cron: '17 4 * * *'
Expand Down Expand Up @@ -311,6 +317,8 @@ jobs:
SOCKET_PATCH_VLT_E2E_STORE_LINKER: ${{ matrix.linker }}
SOCKET_PATCH_VLT_E2E_CACHE_ROOT: ${{ matrix.cache_root }}
VLT_SUITES: ${{ matrix.suites || 'e2e_redirect_vlt_build e2e_vendor_vlt_build mode_migration_vlt e2e_safety_vlt e2e_vlt' }}
MATRIX_OS: ${{ matrix.os }}
NODE_PIN: ${{ matrix.node }}
run: |
set -uo pipefail
exe=''
Expand All @@ -326,6 +334,17 @@ jobs:
mkdir -p "$SOCKET_PATCH_VLT_E2E_CACHE_ROOT"
fi
py=$(command -v python3 || command -v python)
# Cells ci.yml's e2e rows run identically (every PR, main push and
# nightly) are left to them; a dispatch runs every cell.
if [ "$GITHUB_EVENT_NAME" != workflow_dispatch ]; then
# shellcheck disable=SC2086 # VLT_SUITES is a word list
VLT_SUITES=$("$py" scripts/ci-vlt-proof-suites.py --os "$MATRIX_OS" --vlt "$SOCKET_PATCH_VLT_E2E_VERSION" \
--node "$NODE_PIN" --linker "${SOCKET_PATCH_VLT_E2E_STORE_LINKER:-}" \
--cache-root "${SOCKET_PATCH_VLT_E2E_CACHE_ROOT:-}" $VLT_SUITES | tr -d '\r') || exit 1
fi
if [ -z "$VLT_SUITES" ]; then
echo "::notice::every capstone of this cell runs in ci.yml's e2e rows; nothing left to run here"
fi
status=0
for suite in $VLT_SUITES; do
echo "::group::$suite"
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/vlt-serve-watchdog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ name: vlt serve watchdog
# Like installer-drift.yml it checks a deployed service, not the diff. It is
# `continue-on-error` until the serve fix (`Cache-Control: no-transform`) is
# verified in production; removing that line arms it (DESIGN §8.4, the depscan
# rollout's last step).
# rollout's last step). Until then it cannot alert, so it runs once a day to
# record the probe; go back to every 6 hours when arming it.
on:
schedule:
- cron: '23 */6 * * *'
- cron: '23 4 * * *'
workflow_dispatch:

permissions:
Expand Down
4 changes: 1 addition & 3 deletions crates/socket-patch-cli/tests/e2e_maven.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//!
//! # Running
//! ```sh
//! cargo test -p socket-patch-cli --test e2e_maven -- --ignored
//! cargo test -p socket-patch-cli --test e2e_maven
//! ```

use std::path::{Path, PathBuf};
Expand Down Expand Up @@ -99,7 +99,6 @@ async fn assert_proxy_served_scans(server: &MockServer, scans: usize) {

/// Verify that `socket-patch scan` discovers artifacts in a fake Maven local repo.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
#[ignore = "opt-in maven crawl e2e; run with --ignored"]
async fn scan_discovers_maven_artifacts() {
let server = start_proxy().await;
let proxy_url = server.uri();
Expand Down Expand Up @@ -226,7 +225,6 @@ async fn scan_discovers_maven_artifacts() {

/// Verify that `socket-patch scan` discovers Gradle project artifacts.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
#[ignore = "opt-in maven crawl e2e; run with --ignored"]
async fn scan_discovers_gradle_project_artifacts() {
let server = start_proxy().await;
let proxy_url = server.uri();
Expand Down
4 changes: 1 addition & 3 deletions crates/socket-patch-cli/tests/e2e_nuget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//!
//! # Running
//! ```sh
//! cargo test -p socket-patch-cli --test e2e_nuget -- --ignored
//! cargo test -p socket-patch-cli --test e2e_nuget
//! ```

use std::path::{Path, PathBuf};
Expand Down Expand Up @@ -179,7 +179,6 @@ async fn assert_proxy_served_scans(server: &MockServer, scans: usize) {

/// Verify that `socket-patch scan` discovers packages in a fake global cache layout.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
#[ignore = "opt-in nuget crawl e2e; run with --ignored"]
async fn scan_discovers_global_cache_packages() {
let server = start_proxy().await;
let proxy_url = server.uri();
Expand Down Expand Up @@ -247,7 +246,6 @@ async fn scan_discovers_global_cache_packages() {

/// Verify that `socket-patch scan` discovers packages in a fake legacy packages/ layout.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
#[ignore = "opt-in nuget crawl e2e; run with --ignored"]
async fn scan_discovers_legacy_packages() {
let server = start_proxy().await;
let proxy_url = server.uri();
Expand Down
7 changes: 5 additions & 2 deletions docs/testing/pdm-compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,11 @@ the patched `urllib3/response.py` (git-blob SHA-256 matches the ledger
`afterHash`), ordinary `pdm install` keeps the lock stable, a tampered hash is
rejected, a relock-then-rescan keeps rollback invertible, and rollback restores
the lock and `pyproject.toml` byte for byte. `.github/workflows/pdm-compatibility.yml`
runs it on Linux, Windows and macOS across every PDM major family. The matrix
needs no Socket API token (the `urllib3@1.26.18` patch is a free tier).
runs it on Linux and macOS across every PDM major family. It does not run on
Windows: the harness bootstraps PDM through a POSIX venv layout (`bin/pdm`), so
every Windows cell used to skip, and a run whose cells all skip or whose PDM
bootstrap fails is now an error. The matrix needs no Socket API token (the
`urllib3@1.26.18` patch is a free tier).

> **Note (v5.0):** the "refused vendored scan still writes a `.socket/manifest.json`
> record" observation in the notes column below describes the 4.0.0 binary the run
Expand Down
3 changes: 2 additions & 1 deletion docs/testing/vlt-compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ asserted and each named test or row exists.
`install-proof` (every capstone on 31 Linux, 11 macOS and 15 Windows
releases, the Node floors 22.22.0 / 22.13.0 / 22.7.0 / 22.0.0 with the
collation golden, and the store linkers auto / hardlink / copy / unpack / a `/dev/shm`
cache root); `native` (the backtest against production, artifacts
cache root; a cell `ci.yml`'s `e2e` rows run identically is left to them,
see `scripts/ci-vlt-proof-suites.py`, except on dispatch); `native` (the backtest against production, artifacts
`vlt-results-<os>-<vlt>` in depscan's capture `result.json` shape);
`lock-diff` (the same cell's `vlt-lock.json` must be byte-identical on Linux,
macOS and Windows); `matrix-coverage` (every era × suite × OS).
Expand Down
3 changes: 3 additions & 0 deletions docs/testing/yarn-berry-compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ The `yarn-berry-e2e` job in `.github/workflows/ci.yml` runs
| macos-latest | 4.12.0 |
| windows-latest | 4.12.0 |

Pull requests skip ubuntu 4.6.0 and 4.12.0 (the `yarn-berry-full` job, which
runs on main pushes, nightly and dispatch).

Each release drives four real-yarn suites — `e2e_redirect_yarn_berry_build`,
`e2e_vendor_yarn_berry_build`, `e2e_yarn4_pnpm_linker_build` and
`e2e_yarn4_workspaces_build` — each ending in the manifest-less VEX matrix of
Expand Down
6 changes: 5 additions & 1 deletion scripts/backtest-pdm.py
Original file line number Diff line number Diff line change
Expand Up @@ -1362,7 +1362,7 @@ def uninstall(log):
for s in args.shapes:
for m in args.modes:
if wanted(v, s, m):
results.append({"pdm": v, "python": python_for(v), "shape": s, "mode": m, "outcome": "SKIP", "passed": None, "checks": {}, "info": {"skip": "tool bootstrap failed: " + tool_environments.get(v, {}).get("error", "?")[-300:]}})
results.append({"pdm": v, "python": python_for(v), "shape": s, "mode": m, "outcome": "ERROR", "passed": False, "checks": {}, "info": {"error": "tool bootstrap failed: " + tool_environments.get(v, {}).get("error", "?")[-300:]}})
jobs = [j for j in jobs if tool_environments.get(j[0], {}).get("ok")]

def persist():
Expand Down Expand Up @@ -1394,6 +1394,10 @@ def persist():
say(render_matrix(summary))
bad = [r for r in summary["results"] if r["outcome"] in ("FAIL", "ERROR")]
say(f"{len(summary['results'])} rows: " + ", ".join(f"{o} {sum(1 for r in summary['results'] if r['outcome'] == o)}" for o in ("PASS", "REFUSED-EXPECTED", "UNSUPPORTED", "SKIP", "FAIL", "ERROR")))
# A cell whose every row skipped exercised nothing; it must not read as green.
if summary["results"] and all(r["outcome"] == "SKIP" for r in summary["results"]):
say("every row SKIPPED: this cell exercised nothing")
sys.exit(1)
if bad or errors:
sys.exit(1)

Expand Down
Loading
Loading