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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Windows main threads get a 1 MiB stack reserve by default (Unix mains get
# 8 MiB). The CLI's async command futures poll deeply nested state machines
# — scan → download → in-process apply, or scan --vendor → the vendor engine
# — scan → download → in-process apply, or a vendored scan → the vendor engine
# — and in debug builds (no stack-slot reuse) the summed poll frames exceed
# 1 MiB, aborting with "thread 'main' has overflowed its stack" on Windows
# only. Raise the PE stack reserve to the Unix default; spawned threads are
Expand Down
11 changes: 11 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ crates/socket-patch-core/tests/fixtures/redirect/** -text

crates/socket-patch-core/tests/fixtures/pdm-native/*.lock -text

# Poetry and Pipenv locks are real `poetry lock` / `pipenv lock` output: the
# upstream restore and VEX tests round-trip them byte for byte and derive
# their CRLF variants from the LF bytes themselves.
crates/socket-patch-core/tests/fixtures/poetry/** -text
crates/socket-patch-core/tests/fixtures/pipenv/** -text
crates/socket-patch-core/tests/fixtures/pipenv-shapes/** -text

# The captured pnpm 1-12 locks are byte-real: the hosted/vendored rewriters
# refuse CRLF by design (vendor_lockfile_crlf_unsupported), and the tests
# derive their CRLF variants from the LF bytes themselves.
Expand All @@ -22,3 +29,7 @@ crates/socket-patch-core/tests/fixtures/vendor/** -text
# compares the result byte for byte, so a CRLF checkout would change both
# the replayed wiring files and the expected revert.
crates/socket-patch-cli/tests/fixtures/legacy-ledgers/** -text

# The owned Gradle settings script is embedded with include_str! and
# written into user repos byte for byte; a CRLF checkout would change it.
crates/socket-patch-core/src/vendor/jvm/socket-patch.settings.gradle -text
42 changes: 42 additions & 0 deletions .github/actions/pin-socket-hosts/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Pin Socket patch hosts
description: >-
On macOS runners, resolve the production patch hosts once (system resolver,
then DNS-over-HTTPS by IP literal), TLS-verify every address for its host,
and pin them in /etc/hosts for the rest of the job
inputs:
hosts:
description: Space-separated hostnames to pin
default: patch.socket.dev patches-api.socket.dev
runs:
using: composite
steps:
# GitHub's hosted macOS runners intermittently answer patch.socket.dev
# with EAI_NONAME ("[Errno 8] nodename nor servname provided", bun's
# `FailedToOpenSocket`) for minutes at a time — at job start or mid-job —
# while the service is up: the ubuntu / windows legs of the same run pass
# and the same macOS cells pass before and after the window. A pre-flight
# wait cannot cover a mid-job window and the failing processes are the
# real package managers, not the CLI, so the job takes the runner's
# resolver out of the path instead. Every request still goes to the
# production service over TLS verified for the hostname.
# scripts/pin-socket-hosts.py documents the resolution and verification.
- name: Pin hosts
if: runner.os == 'macOS'
shell: bash
env:
PIN_HOSTS: ${{ inputs.hosts }}
run: |
set -euo pipefail
# shellcheck disable=SC2086 # PIN_HOSTS is a space-separated list
lines=$(python3 "$GITHUB_WORKSPACE/scripts/pin-socket-hosts.py" $PIN_HOSTS)
printf '%s\n' "$lines"
printf '\n# pinned by .github/actions/pin-socket-hosts\n%s\n' "$lines" | sudo tee -a /etc/hosts >/dev/null
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder || true
for host in $PIN_HOSTS; do
got=$(python3 -c 'import socket, sys; print(" ".join(sorted({i[4][0] for i in socket.getaddrinfo(sys.argv[1], 443)})))' "$host" || true)
echo "$host now resolves to: ${got:-nothing}"
if [ -z "$got" ] || ! grep -qE "^(${got// /|}) $host\$" <<<"$lines"; then
echo "::warning::$host does not resolve to its pinned address after pinning (got: ${got:-nothing})"
fi
done
21 changes: 15 additions & 6 deletions .github/workflows/bun-compatibility.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ on:
pull_request:
paths:
- '.github/actions/upload-artifact/**'
- '.github/actions/pin-socket-hosts/**'
- 'scripts/pin-socket-hosts.py'
- '.github/workflows/bun-compatibility.yml'
- 'scripts/backtest-bun*.py'
- 'scripts/probe-bun-historical-linux.py'
Expand All @@ -43,20 +45,22 @@ on:
- 'crates/socket-patch-cli/src/commands/scan/**'
- 'crates/socket-patch-cli/src/commands/rollback.rs'
- 'crates/socket-patch-cli/src/commands/vendor.rs'
- 'crates/socket-patch-cli/src/commands/repair_vendor.rs'
- 'crates/socket-patch-cli/src/commands/vendored_backend/**'
- 'crates/socket-patch-cli/src/commands/remove.rs'
# Main runs are the only rust-cache writers (save-if below), so a
# path-filtered push trigger is what seeds the cache the PR builds restore
# (rust-cache keys on Cargo.lock, so Cargo.lock belongs here) and re-runs
# the matrix post-merge on the code paths it exercises: the vendored engine
# (`vendor/**` — bun_lock.rs, bun_lock_text.rs's shared version gate,
# npm_flavor.rs, lock_inventory.rs), the hosted rewriter + unwinds, and the
# npm_flavor.rs, lock_inventory/), the hosted rewriter + unwinds, and the
# CLI drivers (`scan/**` — hosted.rs, vendor_flow.rs, mod.rs — plus the
# vendor / repair / remove commands the matrix runs).
push:
branches: [main]
paths:
- '.github/workflows/bun-compatibility.yml'
- '.github/actions/pin-socket-hosts/**'
- 'scripts/pin-socket-hosts.py'
- 'scripts/backtest-bun*.py'
- 'scripts/probe-bun-historical-linux.py'
- 'scripts/bun-historical-shas.json'
Expand All @@ -75,7 +79,7 @@ on:
- 'crates/socket-patch-cli/src/commands/scan/**'
- 'crates/socket-patch-cli/src/commands/rollback.rs'
- 'crates/socket-patch-cli/src/commands/vendor.rs'
- 'crates/socket-patch-cli/src/commands/repair_vendor.rs'
- 'crates/socket-patch-cli/src/commands/vendored_backend/**'
- 'crates/socket-patch-cli/src/commands/remove.rs'
workflow_dispatch:
inputs:
Expand All @@ -95,11 +99,11 @@ on:
permissions:
contents: read

# Supersede stale PR runs. The `main` guard is load-bearing: main runs are the
# ONLY rust-cache writers (save-if), so they must never be cancelled mid-save.
# Supersede stale PR runs only: main runs are the ONLY rust-cache writers
# (save-if), so push, dispatch and schedule runs are never cancelled mid-save.
concurrency:
group: bun-patch-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

env:
CARGO_PROFILE_DEV_DEBUG: '0'
Expand Down Expand Up @@ -187,6 +191,11 @@ jobs:
with:
python-version: '3.12'

- name: Pin the production patch hosts (macOS)
# The hosted macOS resolver intermittently loses patch.socket.dev for
# minutes (EAI_NONAME) while the service is up; see the action.
uses: ./.github/actions/pin-socket-hosts

- name: Download Bun ${{ matrix.bun }}
id: bun
# Pre-populate the exact directory layout the script's install_tool()
Expand Down
Loading
Loading