Skip to content

📦 npm publish

📦 npm publish #4

Workflow file for this run

name: Publish to npm registry
# Release process for the v1.x line — three packages from one source
# (socket, @socketsecurity/cli, @socketsecurity/cli-with-sentry):
#
# 1. Between releases the tree carries the next-version hint
# (`X.Y.Z-prerelease` in package.json) and user-facing notes accrue
# under the CHANGELOG's `## [Unreleased]` section.
# 2. The release bump strips the hint to X.Y.Z and promotes [Unreleased]
# to the `## [X.Y.Z]` heading — never a hand-coded version.
# 3. Dispatch this workflow with dry-run=true (the default): builds all
# three variants, uploads nothing, marks nothing.
# 4. Dispatch with dry-run=false + a NON-latest dist-tag (the guard below
# refuses `latest` off the default branch): cuts the v<X.Y.Z> tag + the
# immutable GitHub release — both belong to the `socket` package,
# exactly one of each per run — then STAGES all three packages.
# 5. A human promotes each staged upload (`pnpm stage approve` with web
# 2FA, or the npm web UI); nothing is public until then.
# 6. A stage rejected after the markers BURNS the version: the next
# release is a patch bump, and the burned number is never re-published.
on:
workflow_dispatch:
inputs:
dist-tag:
description: 'npm dist-tag (latest, next, beta, canary, backport, etc.)'
required: false
default: 'latest'
type: string
dry-run:
description: 'Build everything but do NOT publish, tag, or cut a release. Defaults to true so an accidental dispatch never reaches the registry — set to false for a real release.'
required: false
default: true
type: boolean
debug:
description: 'Enable debug output'
required: false
default: '0'
type: string
permissions:
contents: read
# Serialize publishes per dist-tag. Two concurrent dispatches with the same
# tag would race on `npm publish` (one wins, the other 409s). Don't cancel an
# in-flight publish — a half-published release is worse than a queued one.
concurrency:
group: publish-${{ inputs.dist-tag }}
cancel-in-progress: false
jobs:
build:
name: Build and Publish
runs-on: ubuntu-latest
# npm's trusted-publisher config pins this GitHub environment name (npm TP
# is PER-PACKAGE, not per-branch: the socket / @socketsecurity/cli /
# @socketsecurity/cli-with-sentry entries point at npm-publish.yml + the
# npm-publish environment). The OIDC token exchange 404s if this job runs
# outside it — so v1.x publishes from the same workflow filename + env as main.
environment: npm-publish
permissions:
# `contents: write` needed to create the v<version> tag via gh api
# at the end of this job. Token is scoped to the dedicated tag step
# via GH_TOKEN env; never persisted in `.git/config` (checkout keeps
# persist-credentials: false so build/install steps can't reach it).
contents: write
id-token: write # NPM trusted publishing via OIDC
steps:
# npm trusted publishing authorizes on repository + workflow filename +
# GitHub environment. It does NOT pin a branch. The `npm-publish`
# environment's deployment-branch policy (main + v1.x) is the outer
# gate; this guard is the in-repo half: `latest` may only be published
# from the default branch, so a v1.x dispatch must pick an explicit
# non-latest dist-tag (next, beta, canary, backport, ...). Dry runs
# pass regardless of dist-tag — they upload nothing, and a
# default-input dry run (dist-tag defaults to latest) must stay green.
- name: Guard the latest dist-tag to the default branch
if: ${{ inputs.dry-run == false && inputs.dist-tag == 'latest' }}
env:
REF: ${{ github.ref }}
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
run: |
if [ "$REF" != "refs/heads/$DEFAULT_BRANCH" ]; then
echo "Refusing to publish dist-tag 'latest' from $REF." >&2
echo "Only refs/heads/$DEFAULT_BRANCH may publish 'latest'." >&2
echo "Re-dispatch from the default branch, or pick a non-latest dist-tag." >&2
exit 1
fi
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 (2026-05-20)
with:
persist-credentials: false
# A version carrying a prerelease suffix is the committed NEXT-version
# hint (X.Y.Z-prerelease — the release tooling consumes it), not a
# releasable artifact: the bump that strips the hint and promotes the
# CHANGELOG's [Unreleased] section must land first. Fail closed so a
# dispatch on a hint-carrying tree can never reach the registry.
- name: Refuse a real publish on a prerelease-hint version
if: ${{ inputs.dry-run == false }}
run: |
VERSION=$(node -p "require('./package.json').version")
case "$VERSION" in
*-*)
echo "package.json version is '$VERSION' — a prerelease-hint version, not a releasable one." >&2
echo "Wanted: a bare X.Y.Z (run the release bump: strip the hint, promote [Unreleased])." >&2
exit 1
;;
esac
echo "Version $VERSION is release-shaped."
- name: Install pnpm
shell: bash
run: | # zizmor: ignore[github-env]
# pnpm 11 is required for `pnpm stage publish` (the staged upload
# the per-package trusted-publisher grants allow) and ships tar.gz
# release assets (a `pnpm` binary + its dist/ tree). The job only
# runs ubuntu-latest, so only the Linux assets are pinned.
PNPM_VERSION="11.17.0"
PNPM_DIR="${RUNNER_TEMP:-/tmp}/pnpm-bin"
KERNEL="$(uname -s | cut -d- -f1)"
ARCH="$(uname -m)"
case "${KERNEL}-${ARCH}" in
Linux-x86_64) ASSET="pnpm-linux-x64.tar.gz" ; EXPECTED_SHA256="bdb1db01bf0f757495405a59a09c5c287f315889dc98d3b14bc374b9fe43a0bf" ;;
Linux-aarch64) ASSET="pnpm-linux-arm64.tar.gz" ; EXPECTED_SHA256="730d17de742a3efbb020ba91d7acfc0456c6ba6ad1cd8eb49f4c229fe9f504d3" ;;
*) echo "Unsupported platform: ${KERNEL}-${ARCH}" >&2; exit 1 ;;
esac
PNPM_BIN="$PNPM_DIR/pnpm"
if [ ! -x "$PNPM_BIN" ]; then
mkdir -p "$PNPM_DIR"
curl -fsSL -o "$PNPM_DIR/$ASSET" "https://github.com/pnpm/pnpm/releases/download/v${PNPM_VERSION}/${ASSET}"
ACTUAL_SHA256="$( (sha256sum "$PNPM_DIR/$ASSET" 2>/dev/null || shasum -a 256 "$PNPM_DIR/$ASSET") | cut -d' ' -f1)"
if [ "$ACTUAL_SHA256" != "$EXPECTED_SHA256" ]; then
echo "Checksum mismatch for ${ASSET}!" >&2
echo " Expected: ${EXPECTED_SHA256}" >&2
echo " Actual: ${ACTUAL_SHA256}" >&2
rm -f "$PNPM_DIR/$ASSET"
exit 1
fi
tar -xzf "$PNPM_DIR/$ASSET" -C "$PNPM_DIR"
chmod +x "$PNPM_BIN"
fi
echo "$PNPM_DIR" >> "${GITHUB_PATH:-/dev/null}"
# Prove the pinned pnpm owns `stage` BEFORE anything else runs — from a
# neutral cwd so the packageManager delegation cannot swap it out. Runs
# on dry runs too, so the weekly validation catches a broken stage
# toolchain without burning a version.
- name: Verify the stage command resolves
working-directory: ${{ runner.temp }}
run: |
pnpm --version
pnpm stage --help > /dev/null
echo "pnpm stage resolves."
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 25.9.0
cache: pnpm
registry-url: https://registry.npmjs.org
scope: '@socketsecurity'
- name: Download sfw
shell: bash
env:
GH_TOKEN: ${{ github.token }}
SOCKET_API_KEY: ${{ secrets.SOCKET_API_KEY }} # zizmor: ignore[secrets-outside-env]
run: | # zizmor: ignore[github-env]
# Pinned version + per-platform checksum pairs. Bumping a tool
# requires updating the matching version AND every platform's
# SHA256 in the same commit, otherwise the download / verify
# steps will diverge.
SFW_FREE_VERSION="1.7.2"
SFW_ENTERPRISE_VERSION="1.7.2"
SFW_DIR="${RUNNER_TEMP:-/tmp}/sfw-bin"
KERNEL="$(uname -s | cut -d- -f1)"
ARCH="$(uname -m)"
USE_ENTERPRISE=false
[ -n "$SOCKET_API_KEY" ] && USE_ENTERPRISE=true
if [ "$USE_ENTERPRISE" = "true" ]; then
REPO="SocketDev/firewall-release"
SFW_VERSION="$SFW_ENTERPRISE_VERSION"
case "${KERNEL}-${ARCH}" in
Linux-x86_64) ASSET="sfw-linux-x86_64" ; SFW_BIN="$SFW_DIR/sfw" ; EXPECTED_SHA256="4482b52e6367bd4610519bfd57a104d5907ec87d5399142ed3bb3d222de1f33d" ;;
Linux-aarch64) ASSET="sfw-linux-arm64" ; SFW_BIN="$SFW_DIR/sfw" ; EXPECTED_SHA256="c24a79c27e1a01a59b7a160c165930ae029816c72b141fcfcdb2f73e0774898a" ;;
Darwin-x86_64) ASSET="sfw-macos-x86_64" ; SFW_BIN="$SFW_DIR/sfw" ; EXPECTED_SHA256="da252d2a9a5d0edb271bb771e0d01b9cd6fa1635b6d765f61efd61edb6739f12" ;;
Darwin-arm64) ASSET="sfw-macos-arm64" ; SFW_BIN="$SFW_DIR/sfw" ; EXPECTED_SHA256="b1cdc3bdbd2a3161247bd5cc215eb3c44a90b87fe0b800a33889a14f61bb0d6d" ;;
MINGW64_NT-x86_64|MSYS_NT-x86_64) ASSET="sfw-windows-x86_64.exe" ; SFW_BIN="$SFW_DIR/sfw.exe" ; EXPECTED_SHA256="e52ad806a1c41b440f04098eb1c7e407845f03f5740a6a79006ba6fd172056ec" ;;
*) echo "Unsupported platform: ${KERNEL}-${ARCH}" >&2; exit 1 ;;
esac
else
REPO="SocketDev/sfw-free"
SFW_VERSION="$SFW_FREE_VERSION"
case "${KERNEL}-${ARCH}" in
Linux-x86_64) ASSET="sfw-free-linux-x86_64" ; SFW_BIN="$SFW_DIR/sfw" ; EXPECTED_SHA256="93e2d9dfa244b82a74e014dc26b1c6af18b4adec20f35254378943db5fe91411" ;;
Linux-aarch64) ASSET="sfw-free-linux-arm64" ; SFW_BIN="$SFW_DIR/sfw" ; EXPECTED_SHA256="84a045e4e1bb320cc5c0d3929f02e53f199398b5be0637e8846d02d9ef0027b1" ;;
Darwin-x86_64) ASSET="sfw-free-macos-x86_64" ; SFW_BIN="$SFW_DIR/sfw" ; EXPECTED_SHA256="a5427d479d440f08e3789fa191ba57599be64997196daf42e67d964fec0382b4" ;;
Darwin-arm64) ASSET="sfw-free-macos-arm64" ; SFW_BIN="$SFW_DIR/sfw" ; EXPECTED_SHA256="248fb588e1e1a27e7192f7b079f739fc29a9de61f0bad7e90928363022dc5643" ;;
MINGW64_NT-x86_64|MSYS_NT-x86_64) ASSET="sfw-free-windows-x86_64.exe" ; SFW_BIN="$SFW_DIR/sfw.exe" ; EXPECTED_SHA256="6d333b4cac9d7c5712e2e99677ca634ac8a3020d550c6308312c60bea97f0a28" ;;
*) echo "Unsupported platform: ${KERNEL}-${ARCH}" >&2; exit 1 ;;
esac
fi
if [ ! -x "$SFW_BIN" ]; then
mkdir -p "$SFW_DIR"
DOWNLOAD_URL="$(gh api "repos/${REPO}/releases/tags/v${SFW_VERSION}" \
--jq ".assets[] | select(.name == \"$ASSET\") | .browser_download_url")"
if [ -z "$DOWNLOAD_URL" ]; then
echo "Asset ${ASSET} not found in ${REPO}@v${SFW_VERSION}" >&2
exit 1
fi
curl -fsSL -o "$SFW_BIN" "$DOWNLOAD_URL"
# shellcheck disable=SC1003 # `tr -d '\\'` strips the leading backslash GNU coreutils prepends to a checksum line when the path has a backslash (Windows RUNNER_TEMP).
ACTUAL_SHA256="$( (sha256sum "$SFW_BIN" 2>/dev/null || shasum -a 256 "$SFW_BIN") | cut -d' ' -f1 | tr -d '\\')"
if [ "$ACTUAL_SHA256" != "$EXPECTED_SHA256" ]; then
echo "Checksum mismatch for ${ASSET} (${REPO}@v${SFW_VERSION})!" >&2
echo " Expected: ${EXPECTED_SHA256}" >&2
echo " Actual: ${ACTUAL_SHA256}" >&2
rm -f "$SFW_BIN"
exit 1
fi
chmod +x "$SFW_BIN"
fi
echo "SFW_BIN=$SFW_BIN" >> "${GITHUB_ENV:-/dev/null}"
echo "SFW_IS_ENTERPRISE=$USE_ENTERPRISE" >> "${GITHUB_ENV:-/dev/null}"
if [ "$USE_ENTERPRISE" = "true" ]; then
echo "SOCKET_API_KEY=$SOCKET_API_KEY" >> "${GITHUB_ENV:-/dev/null}"
fi
- name: Create sfw shims
shell: bash
run: | # zizmor: ignore[github-env]
SHIM_DIR="${RUNNER_TEMP:-/tmp}/sfw-shim"
rm -rf "$SHIM_DIR"
mkdir -p "$SHIM_DIR"
IS_WINDOWS=false
[[ "$OSTYPE" == msys* || "$OSTYPE" == cygwin* ]] && IS_WINDOWS=true
msys_to_win_path() {
if $IS_WINDOWS && [[ "$1" =~ ^/([a-zA-Z])/(.*) ]]; then
echo "${BASH_REMATCH[1]^^}:\\${BASH_REMATCH[2]//\//\\}"
else
echo "$1"
fi
}
strip_shim_dir() { echo "$PATH" | tr ':' '\n' | grep -vxF "$SHIM_DIR" | paste -sd: -; }
CLEAN_PATH="$(strip_shim_dir)"
# Wrapper mode ecosystems (sfw-free):
# JavaScript/TypeScript: npm, yarn, pnpm
# Python: pip, uv
# Rust: cargo
# https://github.com/SocketDev/sfw-free?tab=readme-ov-file#supported-package-managers
#
# Additional wrapper mode ecosystems (sfw-enterprise):
# Ruby: gem, bundler
# .NET: nuget
# Go: go (Linux only)
# https://github.com/SocketDev/firewall-release/wiki#support-matrix
SSL_WORKAROUND=""
SHIM_CMDS="npm yarn pnpm pip uv cargo"
if [ "$SFW_IS_ENTERPRISE" = "true" ]; then
SHIM_CMDS="npm yarn pnpm pip uv cargo gem bundler nuget"
# Go wrapper mode is only supported on Linux.
[[ "$OSTYPE" == linux* ]] && SHIM_CMDS="$SHIM_CMDS go"
else
SSL_WORKAROUND='export GIT_SSL_NO_VERIFY=true # Workaround: sfw-free does not yet set GIT_SSL_CAINFO.'
fi
for CMD in $SHIM_CMDS; do
REAL="$(PATH="$CLEAN_PATH" command -v "$CMD" 2>/dev/null || true)"
[ -z "$REAL" ] && continue
REAL="$(msys_to_win_path "$REAL")"
SHIM_LINES=('#!/bin/bash' "export PATH=\"\$(echo \"\$PATH\" | tr ':' '\n' | grep -vxF '${SHIM_DIR}' | paste -sd: -)\"")
[ -n "$SSL_WORKAROUND" ] && SHIM_LINES+=("$SSL_WORKAROUND")
SHIM_LINES+=("exec \"${SFW_BIN}\" \"${REAL}\" \"\$@\"")
printf '%s\n' "${SHIM_LINES[@]}" > "$SHIM_DIR/$CMD"
chmod +x "$SHIM_DIR/$CMD"
if $IS_WINDOWS; then
printf '@echo off\r\nset "PATH=;%%PATH%%;"\r\nset "PATH=%%PATH:;%s;=;%%"\r\nset "PATH=%%PATH:~1,-1%%"\r\n"%s" "%s" %%*\r\n' \
"$SHIM_DIR" "$SFW_BIN" "$REAL" > "$SHIM_DIR/$CMD.cmd"
fi
done
echo "$SHIM_DIR" >> "${GITHUB_PATH:-/dev/null}"
echo "SFW_SHIM_DIR=$SHIM_DIR" >> "${GITHUB_ENV:-/dev/null}"
- name: Install dependencies
run: pnpm install --loglevel error
# Compile the Maven manifest extension jar so the dist build bundles it
# into dist/manifest-scripts (the jar is never committed; it ships only in
# the published package). Invoke build-jar.sh directly, NOT via `pnpm run`:
# Socket Firewall wraps the package managers (npm/pnpm/...) it shims, so a
# `pnpm run` would route the Maven wrapper's download through sfw, which
# fails on the non-package fetch. Running bash directly keeps the Maven
# download outside the shimmed process tree. The org action allowlist forbids
# actions/setup-java, so use a JDK pre-installed on the runner image
# (JAVA_HOME_17_X64), falling back to the runner's default `java`.
- name: Build Maven manifest extension jar
run: |
if [ -n "${JAVA_HOME_17_X64:-}" ]; then
export JAVA_HOME="$JAVA_HOME_17_X64"
fi
bash src/commands/manifest/scripts/maven-extension/build-jar.sh
# All three uploads are STAGED (`pnpm stage publish`): the tarball +
# provenance land in npm's staging area and NOTHING goes public until a
# human promotes each stage (`pnpm stage approve` with web 2FA, or the
# npm web UI). The per-package trusted publishers for `socket`,
# `@socketsecurity/cli`, and `@socketsecurity/cli-with-sentry` allow
# "stage publish" ONLY — a direct `npm publish` dies at the OIDC token
# exchange. Each package pins SocketDev/socket-cli + this workflow file
# (npm-publish.yml) + the npm-publish environment.
#
# ORDER RULE (markers first): the v<version> tag + immutable GitHub
# release are cut BEFORE the staged uploads so the uploads' provenance
# binds markers that exist. Exactly ONE tag + ONE release per run, and
# they belong to the `socket` package — the tag step reads the version
# from the socket-built manifest right after the socket build, and the
# two variants ride the same version without a tag or release of their
# own. The trade is deliberate and is the burn
# rule: a stage rejected after the markers BURNS the version — the next
# release is a patch bump, never a re-publish of the burned number (the
# tag step's different-SHA hard-fail enforces exactly that; a same-SHA
# re-run is a no-op tag + a fresh stage attempt).
#
# The tag / release / stage steps all skip on a dry run (inputs.dry-run
# defaults to true), so an accidental dispatch builds but never marks or
# uploads anything.
- run: INLINED_SOCKET_CLI_PUBLISHED_BUILD=1 pnpm run build:dist
# Create the v<version> git tag at this commit, idempotently, BEFORE any
# upload (ORDER RULE above). GitHub Release Immutability ("Disallow
# assets and tags from being modified once a release is published")
# freezes tags once bound to a Release, so:
# - existing tag at same SHA → no-op
# - existing tag at different SHA → hard-fail (the burn ratchet: a
# burned version number can never be re-tagged from new content)
#
# Uses gh api (not `git push`) so the token only lives in this step's
# env, never written to `.git/config` by an earlier `actions/checkout`
# with persist-credentials: true (which would leak it to every later
# step including `pnpm install` postinstall scripts).
- name: Tag release (idempotent)
id: tag
if: ${{ inputs.dry-run == false }}
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
run: |
PUBLISHED_SHA=$(git rev-parse HEAD)
PUBLISHED_VERSION=$(node -p "require('./package.json').version")
TAG="v$PUBLISHED_VERSION"
# Emit the tag before any early exit so the release step below can
# consume it on every non-error path (fresh tag AND the same-SHA
# no-op).
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
# Look up any existing tag ref. gh api exits non-zero on 404 (tag
# absent) and writes the error body to stdout, so branch on the
# exit code — never on whether stdout is empty. EXISTING_JSON is
# only valid JSON when the call succeeded.
if EXISTING_JSON=$(gh api "repos/$REPO/git/ref/tags/$TAG" 2>/dev/null); then
# The ref's object is either a commit (lightweight tag) or a tag
# object (annotated/signed tag, e.g. the hand-created `git tag -s`
# tags). For an annotated tag, object.sha is the tag-object SHA,
# not the commit — dereference it via git/tags to get the commit
# the tag actually points at before comparing.
REF_TYPE=$(echo "$EXISTING_JSON" | node -p "JSON.parse(require('fs').readFileSync(0,'utf8')).object.type")
REF_OBJECT_SHA=$(echo "$EXISTING_JSON" | node -p "JSON.parse(require('fs').readFileSync(0,'utf8')).object.sha")
if [ "$REF_TYPE" = "tag" ]; then
EXISTING_SHA=$(gh api "repos/$REPO/git/tags/$REF_OBJECT_SHA" --jq '.object.sha')
else
EXISTING_SHA="$REF_OBJECT_SHA"
fi
if [ "$EXISTING_SHA" = "$PUBLISHED_SHA" ]; then
echo "Tag $TAG already exists at $PUBLISHED_SHA — no-op."
exit 0
fi
echo "::error::Tag $TAG exists at $EXISTING_SHA but publish SHA is $PUBLISHED_SHA."
echo "::error::Release immutability is enabled; this requires manual recovery:"
echo "::error:: 1. Delete any GitHub Release tied to $TAG"
echo "::error:: 2. Delete the tag via the API"
echo "::error:: 3. Re-run this workflow"
exit 1
fi
gh api "repos/$REPO/git/refs" \
-X POST \
-f "ref=refs/tags/$TAG" \
-f "sha=$PUBLISHED_SHA"
echo "Created tag $TAG at $PUBLISHED_SHA"
# Cut the immutable GitHub Release for the tag, idempotently, BEFORE
# the staged uploads (ORDER RULE above). Uses gh release (gh api under
# the hood) so GH_TOKEN only lives in this step's env, never written to
# `.git/config`. Create-as-draft then publish: immutable releases attest
# the locked asset set at publish time, so the release goes live in a
# separate `--draft=false` flip (3-step pattern; no assets ride this
# release, notes only). The flip carries `--latest=false`: v1.x is the
# maintenance line, so its releases never take the repo's Latest badge
# from the 2.x line on main. Re-runs skip a published release and flip
# a stranded draft live.
- name: Cut GitHub release (idempotent)
if: ${{ inputs.dry-run == false }}
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
TAG: ${{ steps.tag.outputs.tag }}
run: |
IS_DRAFT=$(gh release view "$TAG" --repo "$REPO" --json isDraft --jq '.isDraft' 2>/dev/null || echo "absent")
if [ "$IS_DRAFT" = "false" ]; then
echo "Release $TAG already exists — no-op."
exit 0
fi
if [ "$IS_DRAFT" = "absent" ]; then
# --verify-tag: refuse to create if the tag ref is somehow missing
# (the tag step above creates it; this guards against a race).
# --generate-notes: auto-populate notes from commits since the
# last release.
gh release create "$TAG" \
--repo "$REPO" \
--title "$TAG" \
--verify-tag \
--generate-notes \
--draft
fi
gh release edit "$TAG" --repo "$REPO" --draft=false --latest=false
echo "Published GitHub release $TAG"
# --no-git-checks: the INLINED_* builds rewrite package.json + dist/ in
# the checkout, so pnpm's clean-tree publish check would always refuse;
# the tree state is machine-built on a pinned SHA, not hand-edited.
# --ignore-scripts: each variant's dist is built explicitly above, so no
# lifecycle script may run (or mutate anything) at pack/upload time.
# The stage steps run from runner.temp with the checkout passed as the
# directory argument: pnpm self-delegates to the packageManager pin
# (pnpm@10.33.0, which has no `stage` command) whenever its cwd sits
# under a package.json, and no env or npmrc knob disables that in
# pnpm 11 — a neutral cwd keeps the workflow-pinned pnpm 11 in charge
# (the v1.1.148 and v1.1.149 burns). Install/build steps keep the
# delegate on purpose: they match v1.x CI exactly.
# Both flags mirror the fleet staged-publish runner
# (scripts/fleet/publish-infra/npm/staged.mts on main).
- name: Stage socket
if: ${{ inputs.dry-run == false }}
working-directory: ${{ runner.temp }}
run: pnpm stage publish "$GITHUB_WORKSPACE" --provenance --access public --tag "${NPM_DIST_TAG}" --no-git-checks --ignore-scripts
env:
NPM_DIST_TAG: ${{ inputs.dist-tag }}
SOCKET_CLI_DEBUG: ${{ inputs.debug }}
- run: INLINED_SOCKET_CLI_PUBLISHED_BUILD=1 INLINED_SOCKET_CLI_LEGACY_BUILD=1 pnpm run build:dist
env:
SOCKET_CLI_DEBUG: ${{ inputs.debug }}
- name: Stage @socketsecurity/cli (legacy)
if: ${{ inputs.dry-run == false }}
working-directory: ${{ runner.temp }}
run: pnpm stage publish "$GITHUB_WORKSPACE" --provenance --access public --tag "${NPM_DIST_TAG}" --no-git-checks --ignore-scripts
env:
NPM_DIST_TAG: ${{ inputs.dist-tag }}
SOCKET_CLI_DEBUG: ${{ inputs.debug }}
- run: INLINED_SOCKET_CLI_PUBLISHED_BUILD=1 INLINED_SOCKET_CLI_SENTRY_BUILD=1 pnpm run build:dist
env:
SOCKET_CLI_DEBUG: ${{ inputs.debug }}
- name: Stage @socketsecurity/cli-with-sentry
if: ${{ inputs.dry-run == false }}
working-directory: ${{ runner.temp }}
run: pnpm stage publish "$GITHUB_WORKSPACE" --provenance --access public --tag "${NPM_DIST_TAG}" --no-git-checks --ignore-scripts
env:
NPM_DIST_TAG: ${{ inputs.dist-tag }}
SOCKET_CLI_DEBUG: ${{ inputs.debug }}