Skip to content

Commit f9cb7e1

Browse files
v5 CI: build e2e binaries once and tier the PM matrix (#291)
* Build e2e test binaries once and tier PM legs The e2e matrix recompiled the CLI and its test binary in each of its 176 legs. e2e-build now compiles every CLI test target once per OS and the legs run the downloaded binaries from the same checkout path. That compile also replaces the --all-features --no-run pass in test and test-release, so each of those compiles one feature set. PR runs keep every named version boundary, the oldest and newest release of each tool and every vlt era. The 31 middle e2e rows, 2 yarn-berry releases and 10 cargo toolchain x lock cells move to *-full jobs that run on main pushes, a new nightly schedule and dispatch. - e2e-docker (a subset of coverage-docker) runs nightly only. - Dockerfile.base is built once per run and loaded by each docker leg. - The hermetic maven/nuget crawl tests run in `test`; their rows and e2e_composer's are gone. e2e_safety_cargo_build rides cargo-vex. - pdm-compat builds the capstone once, skips the 7 cells ci.yml runs, drops the Windows native rows (they never ran), and fails a cell whose bootstrap fails or whose rows all skip. - vlt-compat install-proof leaves ci.yml's identical cells to it. - npm/pnpm compatibility are path-filtered on PRs; the disarmed vlt serve watchdog runs daily instead of every 6 hours. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HK6zFsizxHRUtyxPvdhM4c * Address review: env parity, filters, PR cells - The legs that run test binaries directly set SOCKET_NO_CONFIG and SOCKET_NO_UPDATE_CHECK, which cargo's [env] gave `cargo test`. - cargo 1.93.1 with its own lock (the pinned toolchain the removed e2e_safety_cargo_build rows ran) stays on PRs; 1.82.0 own-lock moves to the full tier. - Poetry 2.0.1, the first lock 2.1 writer, stays on PRs. - e2e-build gets 60 minutes on Windows. - npm/pnpm filters also watch .cargo/config.toml and cache_env.rs. - vlt install-proof notes a cell left entirely to ci.yml. - pdm-compat saves its build cache from main only. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HK6zFsizxHRUtyxPvdhM4c * Run the full tier on v5 pushes; review fixes - ci.yml also runs on pushes to release/v5-prerelease, whose PRs skip the full tier and which has no nightly; e2e-docker runs there too. - cargo 1.93.1 with its own lock runs on macOS and Windows on PRs, the cell the old e2e_safety_cargo_build rows ran there. - e2e-build and pdm-compat print rendered compile errors (json-render-diagnostics). - vlt-compat and pdm-compat also trigger on ci.yml changes, and the vlt dedupe only counts ci rows with the same test filter. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HK6zFsizxHRUtyxPvdhM4c * Run the vlt agent get test in agent mode get now defaults to hosted mode (5e5f5ed), so the real-vlt get_and_remove leg ran a hosted get and found the installed copy unpatched. It now passes --mode agent, like the other agent-mode fixtures that commit updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R11RZRvYFL3fzmEnkFAU4A (cherry picked from commit cc5f1b6) * Give the nightly CI run its own concurrency group A concurrency group holds one pending run. Sharing main's group let a queued main push and the nightly cancel each other, and the nightly is the only automatic run of e2e-docker. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HK6zFsizxHRUtyxPvdhM4c --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 14a9cb0 commit f9cb7e1

17 files changed

Lines changed: 838 additions & 182 deletions

‎.github/workflows/ci.yml‎

Lines changed: 351 additions & 145 deletions
Large diffs are not rendered by default.

‎.github/workflows/npm-compatibility.yml‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,28 @@ name: npm hosted/vendored compatibility
77
# installs one pinned npm and runs them. See docs/testing/npm-compatibility.md.
88

99
on:
10+
# PRs: any crate source, but only the test files these capstones
11+
# compile (a later `!` pattern excludes, a later plain one re-includes).
12+
# Main pushes stay unfiltered.
1013
pull_request:
14+
paths:
15+
- '.github/actions/upload-artifact/**'
16+
- 'Cargo.lock'
17+
- 'Cargo.toml'
18+
- 'rust-toolchain.toml'
19+
- '.cargo/config.toml'
20+
- '.github/workflows/npm-compatibility.yml'
21+
- 'docs/testing/npm-compatibility.md'
22+
- 'crates/**'
23+
- '!crates/**/*.md'
24+
- '!crates/socket-patch-node/**'
25+
- '!crates/socket-patch-core/tests/**'
26+
- '!crates/socket-patch-cli/tests/**'
27+
- 'crates/socket-patch-cli/tests/vex_e2e_common/**'
28+
- 'crates/socket-patch-cli/tests/e2e_redirect_npm_build.rs'
29+
- 'crates/socket-patch-cli/tests/e2e_vendor_npm_build.rs'
30+
- 'crates/socket-patch-cli/tests/npm_e2e_common/**'
31+
- 'crates/socket-patch-cli/tests/common/cache_env.rs'
1132
push:
1233
branches: [main]
1334
workflow_dispatch:

‎.github/workflows/pdm-compatibility.yml‎

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
name: PDM patch compatibility
22

3-
# Native PDM installer matrix: builds the CLI once per OS, bootstraps pinned
4-
# PDM releases with uv, and runs `scripts/backtest-pdm.py` — hosted, vendored
5-
# and agent mode against the public urllib3 free patch, verifying the
6-
# INSTALLED bytes, lock/manifest stability, hash rejection and rollback. No
7-
# Socket API token is needed. See docs/testing/pdm-compatibility.md.
3+
# Native PDM installer matrix: builds the CLI and the capstone test binary
4+
# once per OS, bootstraps pinned PDM releases with uv, and runs
5+
# `scripts/backtest-pdm.py` — hosted, vendored and agent mode against the
6+
# public urllib3 free patch, verifying the INSTALLED bytes, lock/manifest
7+
# stability, hash rejection and rollback. No Socket API token is needed. See
8+
# docs/testing/pdm-compatibility.md.
89

910
on:
1011
pull_request:
@@ -25,6 +26,8 @@ on:
2526
- 'crates/socket-patch-cli/tests/e2e_vex_build/main.rs'
2627
- 'crates/socket-patch-cli/tests/e2e_vex_build/pdm.rs'
2728
- 'crates/socket-patch-cli/tests/vex_pypi_real_common/**'
29+
# The capstone skips the cells ci.yml's e2e rows run.
30+
- '.github/workflows/ci.yml'
2831
push:
2932
branches: [main]
3033
paths:
@@ -60,7 +63,7 @@ jobs:
6063
strategy:
6164
fail-fast: false
6265
matrix:
63-
os: [ubuntu-latest, windows-latest, macos-latest]
66+
os: [ubuntu-latest, macos-latest]
6467
runs-on: ${{ matrix.os }}
6568
timeout-minutes: 30
6669
steps:
@@ -70,13 +73,26 @@ jobs:
7073
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
7174
with:
7275
key: pdm-compat
73-
- run: cargo build --locked -p socket-patch-cli
76+
save-if: ${{ github.ref == 'refs/heads/main' }}
77+
- name: Compile the CLI and the capstone once
78+
run: |
79+
set -euo pipefail
80+
cargo test --locked -p socket-patch-cli --test e2e_vex_build --no-run --message-format=json-render-diagnostics > target-build.json
81+
python3 - <<'PY'
82+
import json, pathlib, shutil
83+
dest = pathlib.Path('target/pdm-e2e')
84+
dest.mkdir(parents=True, exist_ok=True)
85+
shutil.copy2('target/debug/socket-patch', dest / 'socket-patch')
86+
for line in pathlib.Path('target-build.json').read_text().splitlines():
87+
item = json.loads(line)
88+
if item.get('target', {}).get('name') == 'e2e_vex_build' and item.get('executable'):
89+
shutil.copy2(item['executable'], dest / 'e2e_vex_build')
90+
assert (dest / 'e2e_vex_build').is_file()
91+
PY
7492
- uses: ./.github/actions/upload-artifact
7593
with:
7694
name: pdm-cli-${{ matrix.os }}
77-
path: |
78-
target/debug/socket-patch
79-
target/debug/socket-patch.exe
95+
path: target/pdm-e2e/
8096
if-no-files-found: error
8197
retention-days: 7
8298

@@ -86,8 +102,10 @@ jobs:
86102
fail-fast: false
87103
matrix:
88104
# Every stable PDM major family (0.x, 1.x, 2.x) and each 2.x lock-format
89-
# boundary, on Linux and Windows; macOS samples the ends of the range.
90-
os: [ubuntu-latest, windows-latest]
105+
# boundary on Linux; macOS samples the ends of the range. No Windows:
106+
# the harness bootstraps PDM through a POSIX venv layout (bin/pdm), so
107+
# every Windows cell skipped; backtest-pdm.py now fails such a cell.
108+
os: [ubuntu-latest]
91109
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']
92110
include:
93111
- { os: macos-latest, pdm: '0.12.3' }
@@ -152,25 +170,37 @@ jobs:
152170
# The hermetic Rust capstone (wiremock Socket API that also serves the
153171
# hosted wheel) over every PDM release the backtest covers: real hosted +
154172
# vendored flows ending in the manifest-less VEX matrix; refused lock
155-
# formats (3.1, 4.0-4.2) must attest nothing.
173+
# formats (3.1, 4.0-4.2) must attest nothing. The cells ci.yml's `e2e`
174+
# job runs on every PR and main push are excluded here
175+
# (scripts/tests/test_ci_e2e_tiers.py keeps the two lists in step).
156176
capstone:
177+
needs: build
157178
strategy:
158179
fail-fast: false
159180
matrix:
160181
os: [ubuntu-latest, macos-latest]
161182
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']
183+
exclude:
184+
- {os: ubuntu-latest, pdm: '1.4.5'}
185+
- {os: ubuntu-latest, pdm: '1.15.5'}
186+
- {os: ubuntu-latest, pdm: '2.7.4'}
187+
- {os: ubuntu-latest, pdm: '2.8.2'}
188+
- {os: ubuntu-latest, pdm: '2.25.9'}
189+
- {os: ubuntu-latest, pdm: '2.29.2'}
190+
- {os: macos-latest, pdm: '2.29.2'}
162191
runs-on: ${{ matrix.os }}
163192
timeout-minutes: 30
164193
steps:
194+
# The binaries resolve fixtures through the build job's checkout path,
195+
# which is the same on every runner of one OS.
165196
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
166197
with:
167198
persist-credentials: false
168-
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
199+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
169200
with:
170-
key: pdm-vex-capstone
171-
# Only main writes the cache: 30 PR matrix cells saving would churn
172-
# the repo's 10 GiB budget (ci.yml's rust-cache note).
173-
save-if: ${{ github.ref == 'refs/heads/main' }}
201+
pattern: pdm-cli-${{ matrix.os }}*
202+
merge-multiple: true
203+
path: target/pdm-e2e
174204
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
175205
with:
176206
python-version: '3.12'
@@ -179,4 +209,11 @@ jobs:
179209
env:
180210
SOCKET_PATCH_PDM_E2E_REQUIRED: '1'
181211
SOCKET_PATCH_PDM_E2E_VERSION: ${{ matrix.pdm }}
182-
run: cargo test --locked -p socket-patch-cli --test e2e_vex_build -- 'pdm::' --ignored
212+
run: |
213+
set -euo pipefail
214+
chmod +x target/pdm-e2e/*
215+
mkdir -p target/debug target/tmp
216+
cp target/pdm-e2e/socket-patch target/debug/socket-patch
217+
cd crates/socket-patch-cli
218+
export CARGO_MANIFEST_DIR="$PWD"
219+
../../target/pdm-e2e/e2e_vex_build 'pdm::' --ignored

‎.github/workflows/pnpm-compatibility.yml‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,26 @@
11
name: pnpm hosted compatibility
22

33
on:
4+
# PRs: any crate source, but only the test files these capstones
5+
# compile (a later `!` pattern excludes, a later plain one re-includes).
6+
# Main pushes stay unfiltered.
47
pull_request:
8+
paths:
9+
- '.github/actions/upload-artifact/**'
10+
- 'Cargo.lock'
11+
- 'Cargo.toml'
12+
- 'rust-toolchain.toml'
13+
- '.cargo/config.toml'
14+
- '.github/workflows/pnpm-compatibility.yml'
15+
- 'crates/**'
16+
- '!crates/**/*.md'
17+
- '!crates/socket-patch-node/**'
18+
- '!crates/socket-patch-core/tests/**'
19+
- '!crates/socket-patch-cli/tests/**'
20+
- 'crates/socket-patch-cli/tests/vex_e2e_common/**'
21+
- 'crates/socket-patch-cli/tests/e2e_redirect_pnpm_build.rs'
22+
- 'crates/socket-patch-cli/tests/e2e_vendor_pnpm_build.rs'
23+
- 'crates/socket-patch-cli/tests/common/cache_env.rs'
524
push:
625
branches: [main]
726
workflow_dispatch:

‎.github/workflows/vlt-compatibility.yml‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ on:
5353
- 'scripts/install-vlt.sh'
5454
- 'scripts/vlt-historical-integrity.json'
5555
- 'scripts/gen-vlt-collation-golden.mjs'
56+
- 'scripts/ci-vlt-proof-suites.py'
57+
- '.github/workflows/ci.yml'
58+
- 'scripts/tests/test_ci_vlt_rows.py'
5659
push:
5760
branches: [main]
5861
paths:
@@ -89,6 +92,9 @@ on:
8992
- 'scripts/install-vlt.sh'
9093
- 'scripts/vlt-historical-integrity.json'
9194
- 'scripts/gen-vlt-collation-golden.mjs'
95+
- 'scripts/ci-vlt-proof-suites.py'
96+
- '.github/workflows/ci.yml'
97+
- 'scripts/tests/test_ci_vlt_rows.py'
9298
schedule:
9399
# Nightly: vlt releases and the production service drift with no PR open.
94100
- cron: '17 4 * * *'
@@ -311,6 +317,8 @@ jobs:
311317
SOCKET_PATCH_VLT_E2E_STORE_LINKER: ${{ matrix.linker }}
312318
SOCKET_PATCH_VLT_E2E_CACHE_ROOT: ${{ matrix.cache_root }}
313319
VLT_SUITES: ${{ matrix.suites || 'e2e_redirect_vlt_build e2e_vendor_vlt_build mode_migration_vlt e2e_safety_vlt e2e_vlt' }}
320+
MATRIX_OS: ${{ matrix.os }}
321+
NODE_PIN: ${{ matrix.node }}
314322
run: |
315323
set -uo pipefail
316324
exe=''
@@ -326,6 +334,17 @@ jobs:
326334
mkdir -p "$SOCKET_PATCH_VLT_E2E_CACHE_ROOT"
327335
fi
328336
py=$(command -v python3 || command -v python)
337+
# Cells ci.yml's e2e rows run identically (every PR, main push and
338+
# nightly) are left to them; a dispatch runs every cell.
339+
if [ "$GITHUB_EVENT_NAME" != workflow_dispatch ]; then
340+
# shellcheck disable=SC2086 # VLT_SUITES is a word list
341+
VLT_SUITES=$("$py" scripts/ci-vlt-proof-suites.py --os "$MATRIX_OS" --vlt "$SOCKET_PATCH_VLT_E2E_VERSION" \
342+
--node "$NODE_PIN" --linker "${SOCKET_PATCH_VLT_E2E_STORE_LINKER:-}" \
343+
--cache-root "${SOCKET_PATCH_VLT_E2E_CACHE_ROOT:-}" $VLT_SUITES | tr -d '\r') || exit 1
344+
fi
345+
if [ -z "$VLT_SUITES" ]; then
346+
echo "::notice::every capstone of this cell runs in ci.yml's e2e rows; nothing left to run here"
347+
fi
329348
status=0
330349
for suite in $VLT_SUITES; do
331350
echo "::group::$suite"

‎.github/workflows/vlt-serve-watchdog.yml‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@ name: vlt serve watchdog
1212
# Like installer-drift.yml it checks a deployed service, not the diff. It is
1313
# `continue-on-error` until the serve fix (`Cache-Control: no-transform`) is
1414
# verified in production; removing that line arms it (DESIGN §8.4, the depscan
15-
# rollout's last step).
15+
# rollout's last step). Until then it cannot alert, so it runs once a day to
16+
# record the probe; go back to every 6 hours when arming it.
1617
on:
1718
schedule:
18-
- cron: '23 */6 * * *'
19+
- cron: '23 4 * * *'
1920
workflow_dispatch:
2021

2122
permissions:

‎crates/socket-patch-cli/tests/e2e_maven.rs‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//!
1111
//! # Running
1212
//! ```sh
13-
//! cargo test -p socket-patch-cli --test e2e_maven -- --ignored
13+
//! cargo test -p socket-patch-cli --test e2e_maven
1414
//! ```
1515
1616
use std::path::{Path, PathBuf};
@@ -99,7 +99,6 @@ async fn assert_proxy_served_scans(server: &MockServer, scans: usize) {
9999

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

227226
/// Verify that `socket-patch scan` discovers Gradle project artifacts.
228227
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
229-
#[ignore = "opt-in maven crawl e2e; run with --ignored"]
230228
async fn scan_discovers_gradle_project_artifacts() {
231229
let server = start_proxy().await;
232230
let proxy_url = server.uri();

‎crates/socket-patch-cli/tests/e2e_nuget.rs‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//!
1111
//! # Running
1212
//! ```sh
13-
//! cargo test -p socket-patch-cli --test e2e_nuget -- --ignored
13+
//! cargo test -p socket-patch-cli --test e2e_nuget
1414
//! ```
1515
1616
use std::path::{Path, PathBuf};
@@ -179,7 +179,6 @@ async fn assert_proxy_served_scans(server: &MockServer, scans: usize) {
179179

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

248247
/// Verify that `socket-patch scan` discovers packages in a fake legacy packages/ layout.
249248
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
250-
#[ignore = "opt-in nuget crawl e2e; run with --ignored"]
251249
async fn scan_discovers_legacy_packages() {
252250
let server = start_proxy().await;
253251
let proxy_url = server.uri();

‎docs/testing/pdm-compatibility.md‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,11 @@ the patched `urllib3/response.py` (git-blob SHA-256 matches the ledger
105105
`afterHash`), ordinary `pdm install` keeps the lock stable, a tampered hash is
106106
rejected, a relock-then-rescan keeps rollback invertible, and rollback restores
107107
the lock and `pyproject.toml` byte for byte. `.github/workflows/pdm-compatibility.yml`
108-
runs it on Linux, Windows and macOS across every PDM major family. The matrix
109-
needs no Socket API token (the `urllib3@1.26.18` patch is a free tier).
108+
runs it on Linux and macOS across every PDM major family. It does not run on
109+
Windows: the harness bootstraps PDM through a POSIX venv layout (`bin/pdm`), so
110+
every Windows cell used to skip, and a run whose cells all skip or whose PDM
111+
bootstrap fails is now an error. The matrix needs no Socket API token (the
112+
`urllib3@1.26.18` patch is a free tier).
110113

111114
> **Note (v5.0):** the "refused vendored scan still writes a `.socket/manifest.json`
112115
> record" observation in the notes column below describes the 4.0.0 binary the run

‎docs/testing/vlt-compatibility.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ asserted and each named test or row exists.
7373
`install-proof` (every capstone on 31 Linux, 11 macOS and 15 Windows
7474
releases, the Node floors 22.22.0 / 22.13.0 / 22.7.0 / 22.0.0 with the
7575
collation golden, and the store linkers auto / hardlink / copy / unpack / a `/dev/shm`
76-
cache root); `native` (the backtest against production, artifacts
76+
cache root; a cell `ci.yml`'s `e2e` rows run identically is left to them,
77+
see `scripts/ci-vlt-proof-suites.py`, except on dispatch); `native` (the backtest against production, artifacts
7778
`vlt-results-<os>-<vlt>` in depscan's capture `result.json` shape);
7879
`lock-diff` (the same cell's `vlt-lock.json` must be byte-identical on Linux,
7980
macOS and Windows); `matrix-coverage` (every era × suite × OS).

0 commit comments

Comments
 (0)