Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
d8cd74e
feat(scan): add --apply + structured updates for auto-update bot work…
mikolalysenko May 20, 2026
9b02f02
feat(scan)!: garbage-collect on scan + hide gc subcommand (v3.0)
mikolalysenko May 20, 2026
9acc3f3
test(scan): add e2e_scan test suite + CI matrix entry
mikolalysenko May 20, 2026
a15573c
docs(scan): document v3.0 GC behavior + repair deprecation
mikolalysenko May 20, 2026
0d36e2b
fix(scan): auto-select in JSON --apply when multiple free patches exist
mikolalysenko May 20, 2026
b2869ad
fix(scan): run apply-mode GC even when no packages have patches
mikolalysenko May 20, 2026
745a968
feat(scan): pivot GC to opt-in via --prune + add --sync and --dry-run
mikolalysenko May 20, 2026
8351f99
revert(repair): restore gc as a documented subcommand
mikolalysenko May 20, 2026
a900519
test(scan): update parser + e2e tests for opt-in GC
mikolalysenko May 20, 2026
2cca02e
docs(scan): document --prune/--sync/--dry-run + un-deprecate gc
mikolalysenko May 20, 2026
db8ebd2
chore(hardening): pin toolchain, deps, actions, and install bootstrap
mikolalysenko May 21, 2026
704bea5
feat(cli)!: non-mutating apply + unified JSON envelope (v3.0)
mikolalysenko May 21, 2026
c4ddf1b
test: comprehensive in-process + subprocess test suite
mikolalysenko May 21, 2026
5f71a94
ci: add coverage job, language version pins, and e2e-docker matrix
mikolalysenko May 21, 2026
0bcd28c
test(docker-e2e): infrastructure + npm full install→apply chain
mikolalysenko May 21, 2026
cfa28e5
test(e2e): full install→apply chain for pypi in Docker (+ global)
mikolalysenko May 21, 2026
dd0853c
test(e2e): full install→apply chain for gem in Docker (+ global)
mikolalysenko May 21, 2026
81f0558
test(e2e): full install→apply chain for cargo in Docker
mikolalysenko May 21, 2026
88883df
test(e2e): full install→apply chain for golang in Docker
mikolalysenko May 21, 2026
3f5f62d
test(e2e): full install→apply chain for maven in Docker
mikolalysenko May 21, 2026
52f1c39
test(e2e): full install→apply chain for composer in Docker
mikolalysenko May 21, 2026
3fdfb53
test(e2e): full install→apply chain for nuget in Docker
mikolalysenko May 21, 2026
ba05410
test(e2e): add npm global install variant in Docker
mikolalysenko May 21, 2026
f98e89e
test(e2e): add composer/maven/nuget Dockerfiles
mikolalysenko May 21, 2026
8015834
ci(coverage): include docker-e2e in the coverage map
mikolalysenko May 21, 2026
25aa3b8
ci: remove cargo cache from docker-image-building jobs
mikolalysenko May 21, 2026
643c47c
ci: provide explicit toolchain input to dtolnay/rust-toolchain
mikolalysenko May 21, 2026
54bfb0a
ci: drop dtolnay/rust-toolchain in favor of inline rustup
mikolalysenko May 21, 2026
c04f68c
refactor(cli): unify CLI args + env-var bindings across every subcommand
mikolalysenko May 22, 2026
704936a
docs(changelog): add CHANGELOG.md + CI guard blocking publish without…
mikolalysenko May 22, 2026
a2e193b
ci(test): unbreak test/coverage/e2e-docker matrix on feat/scan-apply-…
mikolalysenko May 22, 2026
8666684
ci(coverage-docker): pin to ubuntu-22.04 for glibc compatibility
mikolalysenko May 22, 2026
b1f5bb3
test(npm): connect via 127.0.0.1 in infrastructure smoke (Windows fix)
mikolalysenko May 22, 2026
8f7df98
test(pypi): skip in_process_pypi_apply on Windows (Unix venv layout)
mikolalysenko May 22, 2026
c1a154f
test(pypi): make in_process_pypi_apply helpers platform-aware (Windows)
mikolalysenko May 22, 2026
6d52330
test(rollback): use Windows venv layout when cfg!(windows)
mikolalysenko May 22, 2026
db0f5fc
feat(json): enrich added/updated patch records with description, seve…
mikolalysenko May 22, 2026
ed04403
test(e2e): walk the v3.0 envelope for `list --json` output
mikolalysenko May 22, 2026
833e80e
ci(e2e_gem): bump pinned ruby from 3.2.11 to 3.2.10
mikolalysenko May 22, 2026
d96f110
refactor(cli): drop -d/-m short aliases; loosen version pins
mikolalysenko May 22, 2026
8333162
feat(apply): preserve mode + ownership across patches
mikolalysenko May 22, 2026
c624c32
ci(e2e_gem): revert ruby-version to exact 3.2.10
mikolalysenko May 22, 2026
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
373 changes: 354 additions & 19 deletions .github/workflows/ci.yml

Large diffs are not rendered by default.

52 changes: 52 additions & 0 deletions .github/workflows/pin-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Pin check

# Fail-closed lint that prevents unpinned action references from sneaking back
# into CI. Every `uses:` entry must reference a 40-character commit SHA (not a
# tag, branch, or @latest). The repo's hardening policy is to consume third-
# party actions only by immutable digest.

on:
pull_request:
paths:
- '.github/workflows/**'
- '.github/actions/**'
push:
branches:
- main
paths:
- '.github/workflows/**'
- '.github/actions/**'

permissions: {}

jobs:
check:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: Verify all `uses:` references are SHA-pinned
run: |
set -eu
# Match any `uses:` line that does NOT reference @<40-char-hex>.
# Allowlist:
# - local actions referenced by `uses: ./.github/actions/foo`
# - `uses: docker://image@sha256:<digest>`
violations="$(
grep -rEn '^\s*uses:\s*' .github/workflows .github/actions 2>/dev/null \
| grep -vE 'uses:\s*\./' \
| grep -vE 'uses:\s*docker://[^[:space:]]+@sha256:[0-9a-f]{64}' \
| grep -vE 'uses:\s*[^@[:space:]]+@[0-9a-f]{40}([[:space:]]|$|#)' \
|| true
)"
if [ -n "$violations" ]; then
echo "::error::Unpinned action references found. Pin to a 40-char commit SHA."
echo "$violations"
exit 1
fi
echo "All action references are SHA-pinned."
34 changes: 28 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,21 @@ jobs:
exit 1
fi

- name: Check CHANGELOG.md has entry for version
run: |
VERSION="${{ steps.read.outputs.VERSION }}"
if [ ! -f CHANGELOG.md ]; then
echo "::error::CHANGELOG.md does not exist at the repository root."
exit 1
fi
# Accept either `## [X.Y.Z]` or `## X.Y.Z` headings, with an
# optional trailing space (followed by `— DATE`) or end-of-line.
if ! grep -qE "^## \[?${VERSION}\]?( |$)" CHANGELOG.md; then
echo "::error::CHANGELOG.md is missing an entry for version ${VERSION}."
echo "::error::Add a heading like \`## [${VERSION}] — $(date +%Y-%m-%d)\` describing the release before re-running."
exit 1
fi

tag:
needs: version
if: ${{ !inputs.dry-run }}
Expand Down Expand Up @@ -126,12 +141,12 @@ jobs:
- name: Install Rust
uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9 # stable
with:
toolchain: stable
# toolchain version is read from rust-toolchain.toml (exact-pinned).
targets: ${{ matrix.target }}

- name: Install cross
if: matrix.build-tool == 'cross'
run: cargo install cross --git https://github.com/cross-rs/cross
run: cargo install --locked --version =0.2.5 cross

- name: Build (cargo)
if: matrix.build-tool == 'cargo'
Expand Down Expand Up @@ -181,6 +196,14 @@ jobs:
path: artifacts
merge-multiple: true

- name: Generate SHA256SUMS
run: |
cd artifacts
# Hash every release artifact (tar.gz + zip) so install.sh can verify
# the binary before extraction. Sorted output keeps the file stable.
sha256sum *.tar.gz *.zip 2>/dev/null | sort > SHA256SUMS
cat SHA256SUMS

- name: Create GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand All @@ -206,8 +229,7 @@ jobs:

- name: Install Rust
uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9 # stable
with:
toolchain: stable
# toolchain version is read from rust-toolchain.toml (exact-pinned).

- name: Authenticate with crates.io
id: crates-io-auth
Expand Down Expand Up @@ -258,7 +280,7 @@ jobs:
registry-url: 'https://registry.npmjs.org'

- name: Update npm for trusted publishing
run: npm install -g npm@latest
run: npm install -g npm@11.15.0

- name: Stage binaries into platform packages
run: |
Expand Down Expand Up @@ -341,7 +363,7 @@ jobs:
- name: Setup Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: '3.12'
python-version: '3.12.13'

- name: Copy README for PyPI package
run: cp README.md pypi/socket-patch/README.md
Expand Down
165 changes: 165 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# Changelog

All notable changes to socket-patch are documented here.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

Pre-v3.0 entries are concise summaries derived from each tag's commit
history. For full per-release detail, see the
[GitHub releases page](https://github.com/SocketDev/socket-patch/releases).

The `Release` workflow refuses to publish a version that does not appear
in this file — see `.github/workflows/release.yml` (`version` job).

## [Unreleased]

## [3.0.0] — 2026-05-22

### Breaking

- **`--offline` semantics unified** to strict airgap on every subcommand.
Previously meant three different things across `apply` (strict airgap),
`repair` (skip downloads / cleanup-only), and `rollback` (fail when blobs
missing). All three now mean the same thing: never contact the network,
fail loudly when a required local source is missing.
- **`repair --download-mode` default** changed from `file` to `diff` to
match every other subcommand. Users who need the legacy per-file blob
behavior must now opt in with `--download-mode file`.
- **`repair --offline` is mutually exclusive with `--download-only`** —
passing both exits with code 2.
- **Env vars renamed.** The three remaining `SOCKET_PATCH_*` env vars now
use the `SOCKET_*` prefix:
- `SOCKET_PATCH_PROXY_URL` → `SOCKET_PROXY_URL`
- `SOCKET_PATCH_DEBUG` → `SOCKET_DEBUG`
- `SOCKET_PATCH_TELEMETRY_DISABLED` → `SOCKET_TELEMETRY_DISABLED`

The legacy names are still honored at runtime but emit a one-shot
deprecation warning to stderr (the warning fires even under `--silent`
and `--json` because the transition signal must reach scripts and CI
logs). Legacy names will be removed in v4.

### Added

- Shared `GlobalArgs` clap struct `#[command(flatten)]`-ed into every
subcommand. Every flag is now accepted on every subcommand (silently
no-op'd where the subcommand doesn't consume it). Every flag has a
matching `SOCKET_*` env-var binding with precedence
`CLI arg > env var > default`. See `CLI_CONTRACT.md` for the full
global-arguments table.
- `apply` and `repair` accept `--api-url`, `--api-token`, `--org` via the
global flatten (previously env-var only — telemetry would silently fall
back to the public proxy when the CLI was the only way to set these).
- New global flags `--debug` and `--no-telemetry`, promoted from env-only
toggles.
- `--proxy-url` (env: `SOCKET_PROXY_URL`) as an explicit CLI knob for the
public patch proxy.
- New CI guard in the `Release` workflow: the workflow fails before tag
creation if `CHANGELOG.md` lacks an entry for the version in
`Cargo.toml`. Blocks every downstream publish (cargo, npm, pypi).

### Changed

- Garbage collection moved out of `apply`. Use `scan --prune`,
`scan --sync`, or `repair` / `gc` instead. `apply` is now strictly
non-mutating against `.socket/`: when blobs need to be fetched they go
to a temp overlay; the persistent cache is never written to.
- Unified JSON envelope (`command` / `status` / `events` / `summary`) for
`apply`, `list`, `remove`, `repair`. Other subcommands keep their
pre-v3 ad-hoc shapes for now; see `CLI_CONTRACT.md` for migration status.

## [2.1.4] — 2026-04-09

- Release workflow tolerates already-published npm packages so a partial
publish can be retried without re-tagging.

## [2.1.3] — 2026-04-08

- Pin Node `22.22.1` in the release workflow to dodge a broken
upstream npm.

## [2.1.2] — 2026-04-08

- Harden core error handling, blob verification, and `--force` reporting.
- Surface `find_by_purls` errors instead of silently swallowing them.
- Add diagnostics to `apply` for silent no-op failures in CI.
- Add explicit Node typings for TypeScript 6 compatibility in the npm
wrapper.

## [2.1.1] — 2026-04-02

- Simplify release to `workflow_dispatch` only (no bot commits).
- Split release into PR-based version prep + auto-publish on dispatch.
- Prioritize `pnpm-workspace.yaml` detection and restrict `setup` to root
`package.json` for pnpm monorepos.
- Harden GitHub Actions workflows per `zizmor` audit.
- Unflag Ruby gem (`gem`) support and add e2e bundler tests.
- Use `npx @socketsecurity/socket-patch` for the generated postinstall
command.

## [2.1.0] — 2026-03-10

- Full glibc/musl support across all Linux architectures (16 platform
combinations now published per release).

## [2.0.0] — 2026-03-06

- Interactive prompts and smart patch selection when multiple patches
match a query.

## [1.7.1] — 2026-03-06

- Ensure the binary has execute permission in the PyPI wrapper.
- Restore `bin` and `optionalDependencies` to the npm wrapper
`package.json`.

## [1.7.0] — 2026-03-06

- Expand ecosystem support: rough-in for composer, go, maven, nuget, ruby.
- Add a TypeScript schema library to the npm wrapper.
- Treat empty `SOCKET_API_TOKEN` as unset.

## [1.6.3] — 2026-03-05

- Maintenance release.

## [1.6.2] — 2026-03-05

- Maintenance release (version sync).

## [1.6.1] — 2026-03-05

- Switch to per-platform `optionalDependencies` for the npm package.
- Add macOS global-package crawling fallbacks and pyenv support.

## [1.6.0] — 2026-03-04

- Add support for more platforms; fix pypi and npm publish flows.

## [1.5.0] — 2026-03-04

- Fix trusted publishing setup for npm and PyPI.

## [1.4.0] — 2026-03-04

- Update PyPI publish action and add npm provenance permissions.

## [1.3.1] — 2026-03-04

- Fix action image references in the publish workflow.

## [1.3.0] — 2026-03-04

- Add `apply --force`; rename `--no-apply` to `--save-only` (the old name
remains as a hidden alias).
- Cargo/Rust crate patching support behind a feature flag.
- Auto-resolve org slug from API token when `SOCKET_ORG_SLUG` is unset.

## [1.2.0] — 2026-01-10

- Fix publish workflow to checkout the bumped version.

## [1.1.0] — 2026-01-10

- Pin GitHub Actions to full commit SHAs and wire up version-bump
support in the publish workflow.
Loading
Loading