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
119 changes: 10 additions & 109 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,24 +55,6 @@ jobs:

- name: Run clippy
run: cargo clippy --workspace --all-features -- -D warnings
# Moved-module aliases (patch::vendor → vendor, patch::go_mod_edit →
# vendor::go_mod_edit, patch::go_redirect → patch::redirect::golang_local)
# exist only for external consumers of the published core crate.
# #[deprecated] on a `pub use` re-export emits no warnings
# (rust-lang/rust#30827), so the compiler cannot pressure internal code
# off the old paths — this grep is the guard instead.
- name: Reject internal uses of moved-module alias paths
run: |
if grep -rn --include='*.rs' \
-e 'patch::vendor' -e 'patch::go_mod_edit' \
-e 'patch::go_redirect' -e 'patch::bun_lock_text' \
-e 'utils::telemetry' -e 'utils::cleanup_blobs' \
-e 'utils::date' -e 'utils::fuzzy_match' \
-e 'gem_setup::' -e 'composer_setup::' -e 'pth_hook::' \
crates; then
echo '::error::use the canonical module paths (crate::vendor, patch::redirect::golang_local, crate::telemetry, manifest::cleanup_blobs, api::date, crawlers::fuzzy_match); the old-path aliases exist only for external consumers'
exit 1
fi

# The napi addon is only ever loaded by Node, so cargo's own tests never
# exercise its JS loader or the engine/provider boundary.
Expand Down Expand Up @@ -107,7 +89,7 @@ jobs:
run: node --test crates/socket-patch-node/npm/test/smoke.mjs

# Lint the out-of-workspace packaging artifacts: the RubyGems CLI launcher
# gem + the Bundler plugin gem (Ruby), and the curl|sh installer. Ruby is
# gem (Ruby), and the curl|sh installer. Ruby is
# pre-installed on the ubuntu-latest runner.
lint-ecosystems:
runs-on: ubuntu-latest
Expand All @@ -118,13 +100,9 @@ jobs:
with:
persist-credentials: false

- name: Ruby — syntax-check + build the launcher gem and Bundler plugin
- name: Ruby — syntax-check + build the launcher gem
run: |
( cd gem/socket-patch && ruby -c lib/socket_patch/launcher.rb && ruby -c exe/socket-patch && gem build socket-patch.gemspec )
( cd gem/socket-patch-bundler && ruby -c plugins.rb && gem build socket-patch-bundler.gemspec )
# The generated-plugin templates are pure Ruby — keep them parseable.
ruby -c crates/socket-patch-core/src/setup/gem/templates/plugins.rb.tmpl
ruby -c crates/socket-patch-core/src/setup/gem/templates/gemspec.tmpl

- name: Python — test native installer harnesses
run: python3 -B -m unittest discover -s scripts/tests -v
Expand Down Expand Up @@ -311,13 +289,13 @@ jobs:
echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"

- name: Run tests
# `--all-features` would also RUN the docker-e2e / setup-e2e suites,
# `--all-features` would also RUN the docker-e2e suites,
# which soft-skip as "ok" in this job (no images are built here, and
# macOS/Windows have no Docker at all) — dozens of fake greens per OS
# that would hide a broken skip-guard behind a passing checkmark.
# Build them with --all-features (compile rot is real coverage), but
# run only the default-feature suites; the dedicated e2e-docker and
# setup-matrix jobs run the gated suites for real.
# run only the default-feature suites; the dedicated e2e-docker
# job runs the gated suites for real.
#
# `--no-fail-fast`: without it cargo stops at the first failing test
# BINARY, so one bad file hides every later binary's result on that
Expand Down Expand Up @@ -368,7 +346,7 @@ jobs:
# profile's comment in Cargo.toml). Same opt-level/debug-assertion
# semantics this job exists to validate; ~23m of LTO relinking gone.
# Build/run split for the same reason as the `test` job: the gated
# docker-e2e / setup-e2e suites only soft-skip here — compile them,
# docker-e2e suites only soft-skip here — compile them,
# don't count their skips as passes.
run: |
set -euo pipefail
Expand Down Expand Up @@ -681,10 +659,10 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
suite: e2e_cargo
- os: ubuntu-latest
suite: e2e_golang
# (No e2e_cargo / e2e_golang rows: neither suite has an
# `#[ignore]`-gated test or needs a real toolchain, so the
# unfiltered `test` job already runs all of them and the rows'
# `--ignored` legs selected zero tests.)
- os: ubuntu-latest
suite: e2e_maven
- os: ubuntu-latest
Expand Down Expand Up @@ -717,9 +695,6 @@ jobs:
- {os: ubuntu-latest, suite: e2e_redirect_composer_build, composer: '2'}
- {os: ubuntu-latest, suite: e2e_redirect_composer_build, composer: '2.2'}
- {os: ubuntu-latest, suite: e2e_redirect_composer_build, composer: '1'}
# setup-e2e host guards run in no other job (test job = default
# features; setup-matrix job = shell script).
- {os: ubuntu-latest, suite: setup_matrix_composer, test_filter: host_guard}
# Real-bundler gem capstones, one leg per bundler era. Boundaries:
# 1.17/2.1 merged GEM section, 2.2 separate sections, 2.5 last
# pre-CHECKSUMS, 2.6 CHECKSUMS, 4.0.15/4.0.21 before/after the
Expand All @@ -741,8 +716,6 @@ jobs:
- {os: ubuntu-latest, suite: e2e_vendor_gem_build, ruby: '3.3', bundler: '2.7.2'}
- {os: ubuntu-latest, suite: e2e_vendor_gem_build, ruby: '3.4', bundler: '4.0.15'}
- {os: ubuntu-latest, suite: e2e_vendor_gem_build, ruby: '3.4', bundler: '4.0.21'}
# not #[ignore]-gated -> --include-ignored is mandatory
- {os: ubuntu-latest, suite: setup_matrix_gem, ruby: '3.3', bundler: '2.7.2', test_filter: --include-ignored}
# The live-API smoke suites (e2e_npm, e2e_pypi, e2e_gem,
# e2e_scan) are intentionally NOT in the PR matrix — their
# `#[ignore]`-gated tests hit the real public proxy at
Expand Down Expand Up @@ -1615,78 +1588,6 @@ jobs:
set -euo pipefail
cargo test -p socket-patch-cli --test e2e_vendor_cargo_build -- old_toolchain --nocapture

# ----------------------------------------------------------------------
# Experimental `setup`-flow matrix (NON-BLOCKING).
#
# For each ecosystem/package manager, drives the full intended flow —
# prepare deps + a committed patch set, run `socket-patch setup`, run
# the native install, check whether the patch was applied — plus the
# negative controls (no setup, empty/wrong/alt patch sets). See
# tests/setup_matrix/ and scripts/setup-matrix.sh.
#
# This is EXPERIMENTAL and intentionally not required to pass yet:
# `setup` configures install hooks for npm, PyPI, Bundler and Composer
# only, so the other ecosystems' `baseline_with_setup` cases are
# EXPECTED to fail (a baseline of what `setup` must eventually support). `continue-on-error: true`
# means this job never blocks a PR — it must ALSO be left OUT of the
# repo's required status checks (configured in the branch-protection
# UI, not in this file). The orchestrator exits non-zero only on a
# *regression* vs the recorded baseline; the full per-case result set
# is uploaded as a JSON artifact for inspection.
# ----------------------------------------------------------------------
setup-matrix:
runs-on: ubuntu-latest
timeout-minutes: 45
continue-on-error: true
permissions:
contents: read
strategy:
fail-fast: false
matrix:
ecosystem: [npm, pypi, cargo, gem, golang, maven, composer, nuget, deno]
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: Set up Docker Buildx
# `driver: docker` — the per-ecosystem image's `FROM
# socket-patch-test-base:latest` only resolves when buildx talks
# directly to the host docker daemon (see e2e-docker above).
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
with:
driver: docker

- name: Install Rust
run: rustup show

- name: Build base image
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
context: .
file: tests/docker/Dockerfile.base
tags: socket-patch-test-base:latest
load: true

- name: Build ${{ matrix.ecosystem }} image
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
context: .
file: tests/docker/Dockerfile.${{ matrix.ecosystem }}
tags: socket-patch-test-${{ matrix.ecosystem }}:latest
load: true

- name: Run ${{ matrix.ecosystem }} setup-matrix
run: scripts/setup-matrix.sh run --ecosystem ${{ matrix.ecosystem }} --out "report-${{ matrix.ecosystem }}.json"

- name: Upload ${{ matrix.ecosystem }} setup-matrix report
if: always()
uses: ./.github/actions/upload-artifact
with:
name: setup-matrix-${{ matrix.ecosystem }}
path: report-${{ matrix.ecosystem }}.json

# ----------------------------------------------------------------------
# Hosted-mode production e2e — REQUIRED status check, with a kill switch.
#
Expand Down
24 changes: 5 additions & 19 deletions .github/workflows/publish-pypi.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
name: Publish PyPI
run-name: "Publish PyPI ${{ inputs.version }}${{ inputs.distinct-id != '' && format(' [{0}]', inputs.distinct-id) || '' }}"

# Publishes socket-patch (platform wheels) + socket-patch-hook (pure-python
# .pth carrier) to PyPI for an existing v<version> release. Dispatched two
# Publishes socket-patch (platform wheels) to PyPI for an existing
# v<version> release. (The socket-patch-hook .pth wheel is no longer
# published: `setup` was removed in v5.) Dispatched two
# ways, both as a plain workflow_dispatch run:
# - by release.yml (scripts/dispatch-publish.sh), as one leg of the
# single-dispatch release fan-out — distinct-id carries the release
Expand Down Expand Up @@ -137,29 +138,14 @@ jobs:
- name: Copy README for PyPI package
run: cp README.md pypi/socket-patch/README.md

- name: Build wheels (platform socket-patch + pure-python socket-patch-hook)
- name: Build wheels (platform socket-patch)
env:
VERSION: ${{ inputs.version }}
run: |
# Builds the platform-tagged socket-patch wheels AND the pure-python
# socket-patch-hook wheel (the .pth carrier behind `socket-patch[hook]`).
python scripts/build-pypi-wheels.py --version "$VERSION" --artifacts artifacts --dist dist
# socket-patch and socket-patch-hook are two distinct PyPI projects.
# Publish each from its own dir so trusted publishing mints an OIDC
# token scoped to the right project (one upload spanning both projects
# can be rejected). Each needs its own trusted publisher on PyPI.
mkdir -p dist-hook
mv dist/socket_patch_hook-*.whl dist-hook/
run: python scripts/build-pypi-wheels.py --version "$VERSION" --artifacts artifacts --dist dist

- name: Publish socket-patch to PyPI
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
with:
packages-dir: dist/
# Idempotent for re-runs: already-uploaded files skip.
skip-existing: true

- name: Publish socket-patch-hook to PyPI
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
with:
packages-dir: dist-hook/
skip-existing: true
53 changes: 6 additions & 47 deletions .github/workflows/publish-rubygems.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
name: Publish RubyGems
run-name: "Publish RubyGems ${{ inputs.version }}${{ inputs.distinct-id != '' && format(' [{0}]', inputs.distinct-id) || '' }}"

# Publishes BOTH gems via one OIDC trusted-publishing exchange:
# - gem/socket-patch — the CLI launcher gem (downloads the
# prebuilt binary from the GitHub release at its own version, so this
# workflow only needs the GitHub release + SHA256SUMS to exist).
# - gem/socket-patch-bundler — Phase 2 scaffolding, non-blocking (see the
# step comment below).
# Publishes the CLI launcher gem (gem/socket-patch) via OIDC trusted
# publishing. The gem downloads the prebuilt binary from the GitHub release
# at its own version, so this workflow only needs the GitHub release +
# SHA256SUMS to exist. (The socket-patch-bundler plugin gem is no longer
# published: `setup` was removed in v5.)
#
# Dispatched two ways, both as a plain workflow_dispatch run:
# - by release.yml (scripts/dispatch-publish.sh), as one leg of the
Expand All @@ -26,8 +25,7 @@ run-name: "Publish RubyGems ${{ inputs.version }}${{ inputs.distinct-id != '' &&
# `rubygems`. Because this workflow only ever runs as its own top-level
# workflow_dispatch run (never as a called reusable workflow), the OIDC
# token's workflow_ref and job_workflow_ref claims both name this file — one
# publisher registration per gem covers every path, and one exchange
# satisfies both gems' publishers.
# publisher registration covers every path.

on:
workflow_dispatch:
Expand Down Expand Up @@ -107,24 +105,7 @@ jobs:
exit 1
fi

- name: Lint + version-check the bundler-plugin gem
working-directory: gem/socket-patch-bundler
env:
EXPECTED_VERSION: ${{ inputs.version }}
run: |
ruby -c plugins.rb
# The gemspec version is baked at the tag by scripts/version-sync.sh.
gemver="$(ruby -e 'print Gem::Specification.load("socket-patch-bundler.gemspec").version')"
if [ "$gemver" != "$EXPECTED_VERSION" ]; then
echo "::error::gemspec version $gemver != release $EXPECTED_VERSION (run scripts/version-sync.sh before tagging)"
exit 1
fi

- name: Configure RubyGems credentials (OIDC trusted publishing)
# One OIDC exchange covers both gems: a trusted publisher keyed on
# this repo + workflow (+ the `rubygems` environment) can be
# registered on multiple gems on rubygems.org, and the exchanged
# token pushes any gem whose publisher matches.
uses: rubygems/configure-rubygems-credentials@dc5a8d8553e6ee01fc26761a49e99e733d17954a # v2.1.0

- name: Publish socket-patch to RubyGems
Expand All @@ -141,25 +122,3 @@ jobs:
exit 0
fi
gem push "socket-patch-${VERSION}.gem"

# Phase 2 scaffolding (CLI_CONTRACT "gem" support matrix): publish the
# `socket-patch-bundler` gem — the published form of the Bundler plugin
# that `socket-patch setup` currently wires through an in-tree
# `plugin ..., path:` directive. This gem is NOT yet the active mechanism (setup::gem still
# emits the in-tree plugin), so the push is **non-blocking**
# (`continue-on-error`). A follow-up switches the generated Gemfile
# directive to `plugin "socket-patch-bundler"` and drops
# continue-on-error.
- name: Publish socket-patch-bundler to RubyGems
continue-on-error: true
working-directory: gem/socket-patch-bundler
env:
VERSION: ${{ inputs.version }}
run: |
gem build socket-patch-bundler.gemspec
# Same precise-list-element match as the launcher gem above.
if gem list --remote --exact --all socket-patch-bundler 2>/dev/null | grep -qE "[ (]${VERSION}[,)]"; then
echo "socket-patch-bundler ${VERSION} already on RubyGems; skipping."
exit 0
fi
gem push "socket-patch-bundler-${VERSION}.gem"
5 changes: 2 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,8 @@ name: Release
# - npm: OIDC via `npm stage publish`; staged versions require
# manual 2FA approval (see the npm run's step summary).
# - PyPI: OIDC trusted publishing; environment `pypi`.
# - RubyGems: OIDC trusted publishing; environment `rubygems`. One
# repo+workflow publisher per gem (`socket-patch` and
# `socket-patch-bundler`), both satisfied by one exchange.
# - RubyGems: OIDC trusted publishing; environment `rubygems`
# (the `socket-patch` launcher gem).
# Every registry's trusted publisher is keyed on the repo + the publish
# workflow's own filename (see each publish-*.yml header), NOT release.yml.

Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/vlt-compatibility.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ on:
- 'crates/socket-patch-cli/src/commands/apply.rs'
- 'crates/socket-patch-cli/src/commands/rollback.rs'
- 'crates/socket-patch-cli/src/commands/remove.rs'
- 'crates/socket-patch-cli/src/commands/setup.rs'
- 'crates/socket-patch-cli/src/commands/vendor.rs'
- 'crates/socket-patch-cli/src/commands/vendored_backend/**'
- 'crates/socket-patch-cli/src/commands/get.rs'
Expand Down Expand Up @@ -72,7 +71,6 @@ on:
- 'crates/socket-patch-cli/src/commands/apply.rs'
- 'crates/socket-patch-cli/src/commands/rollback.rs'
- 'crates/socket-patch-cli/src/commands/remove.rs'
- 'crates/socket-patch-cli/src/commands/setup.rs'
- 'crates/socket-patch-cli/src/commands/vendor.rs'
- 'crates/socket-patch-cli/src/commands/vendored_backend/**'
- 'crates/socket-patch-cli/src/commands/get.rs'
Expand Down
Loading
Loading