|
| 1 | +name: 'Setup' |
| 2 | +description: 'Setup Node.js, pnpm, and Socket firewall shims' |
| 3 | + |
| 4 | +# Dependencies: |
| 5 | +# - actions/setup-node@v6.3.0 |
| 6 | + |
| 7 | +inputs: |
| 8 | + node-version: |
| 9 | + description: 'Node.js version' |
| 10 | + required: false |
| 11 | + default: '25.9.0' |
| 12 | + socket-api-key: |
| 13 | + description: 'Socket API key — when provided, uses sfw-enterprise instead of sfw-free' |
| 14 | + required: false |
| 15 | + default: '' |
| 16 | + |
| 17 | +runs: |
| 18 | + using: 'composite' |
| 19 | + steps: |
| 20 | + - name: Install pnpm |
| 21 | + shell: bash |
| 22 | + run: | # zizmor: ignore[github-env] |
| 23 | + PNPM_VERSION="10.33.0" |
| 24 | + PNPM_DIR="${RUNNER_TEMP:-/tmp}/pnpm-bin" |
| 25 | + KERNEL="$(uname -s | cut -d- -f1)" |
| 26 | + ARCH="$(uname -m)" |
| 27 | + case "${KERNEL}-${ARCH}" in |
| 28 | + Linux-x86_64) ASSET="pnpm-linux-x64" ; EXPECTED_SHA256="8d4e8f7d778e8ac482022e2577011706a872542f6f6f233e795a4d9f978ea8b5" ;; |
| 29 | + Linux-aarch64) ASSET="pnpm-linux-arm64" ; EXPECTED_SHA256="06755ad2817548b84317d857d5c8003dc6e9e28416a3ea7467256c49ab400d48" ;; |
| 30 | + Darwin-x86_64) ASSET="pnpm-macos-x64" ; EXPECTED_SHA256="c31e29554b0e3f4e03f4617195c949595e4dca36085922003de4896c3ca4057d" ;; |
| 31 | + Darwin-arm64) ASSET="pnpm-macos-arm64" ; EXPECTED_SHA256="ed8a1f140f4de457b01ebe0be3ae28e9a7e28863315dcd53d22ff1e5a32d63ae" ;; |
| 32 | + MINGW64_NT-x86_64|MSYS_NT-x86_64) ASSET="pnpm-win-x64.exe" ; EXPECTED_SHA256="afc96009dc39fe23a835d65192049e6a995f342496b175585dc2beda7d42d33f" ;; |
| 33 | + *) echo "Unsupported platform: ${KERNEL}-${ARCH}" >&2; exit 1 ;; |
| 34 | + esac |
| 35 | + PNPM_BIN="$PNPM_DIR/$ASSET" |
| 36 | + if [ ! -x "$PNPM_BIN" ]; then |
| 37 | + mkdir -p "$PNPM_DIR" |
| 38 | + curl -fsSL -o "$PNPM_BIN" "https://github.com/pnpm/pnpm/releases/download/v${PNPM_VERSION}/${ASSET}" |
| 39 | + ACTUAL_SHA256="$( (sha256sum "$PNPM_BIN" 2>/dev/null || shasum -a 256 "$PNPM_BIN") | cut -d' ' -f1 | tr -d '\\')" |
| 40 | + if [ "$ACTUAL_SHA256" != "$EXPECTED_SHA256" ]; then |
| 41 | + echo "Checksum mismatch for ${ASSET}!" >&2 |
| 42 | + echo " Expected: ${EXPECTED_SHA256}" >&2 |
| 43 | + echo " Actual: ${ACTUAL_SHA256}" >&2 |
| 44 | + rm -f "$PNPM_BIN" |
| 45 | + exit 1 |
| 46 | + fi |
| 47 | + chmod +x "$PNPM_BIN" |
| 48 | + # Create pnpm alias. Windows needs a .exe copy; Unix uses a symlink. |
| 49 | + if [[ "$ASSET" == *.exe ]]; then |
| 50 | + cp "$PNPM_BIN" "$PNPM_DIR/pnpm.exe" |
| 51 | + else |
| 52 | + ln -sf "$PNPM_BIN" "$PNPM_DIR/pnpm" |
| 53 | + fi |
| 54 | + fi |
| 55 | + echo "$PNPM_DIR" >> "${GITHUB_PATH:-/dev/null}" |
| 56 | +
|
| 57 | + - name: Setup Node.js |
| 58 | + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 |
| 59 | + with: |
| 60 | + node-version: ${{ inputs.node-version }} |
| 61 | + |
| 62 | + - name: Download sfw |
| 63 | + shell: bash |
| 64 | + env: |
| 65 | + GH_TOKEN: ${{ github.token }} |
| 66 | + SOCKET_API_KEY: ${{ inputs.socket-api-key }} |
| 67 | + run: | # zizmor: ignore[github-env] |
| 68 | + SFW_DIR="${RUNNER_TEMP:-/tmp}/sfw-bin" |
| 69 | + KERNEL="$(uname -s | cut -d- -f1)" |
| 70 | + ARCH="$(uname -m)" |
| 71 | + USE_ENTERPRISE=false |
| 72 | + if [ -n "$SOCKET_API_KEY" ]; then |
| 73 | + USE_ENTERPRISE=true |
| 74 | + fi |
| 75 | + if $USE_ENTERPRISE; then |
| 76 | + REPO="SocketDev/firewall-release" |
| 77 | + case "${KERNEL}-${ARCH}" in |
| 78 | + Linux-x86_64) ASSET="sfw-linux-x86_64" ; SFW_BIN="$SFW_DIR/sfw" ; EXPECTED_SHA256="9115b4ca8021eb173eb9e9c3627deb7f1066f8debd48c5c9d9f3caabb2a26a4b" ;; |
| 79 | + Linux-aarch64) ASSET="sfw-linux-arm64" ; SFW_BIN="$SFW_DIR/sfw" ; EXPECTED_SHA256="671270231617142404a1564e52672f79b806f9df3f232fcc7606329c0246da55" ;; |
| 80 | + Darwin-x86_64) ASSET="sfw-macos-x86_64" ; SFW_BIN="$SFW_DIR/sfw" ; EXPECTED_SHA256="01d64d40effda35c31f8d8ee1fed1388aac0a11aba40d47fba8a36024b77500c" ;; |
| 81 | + Darwin-arm64) ASSET="sfw-macos-arm64" ; SFW_BIN="$SFW_DIR/sfw" ; EXPECTED_SHA256="acad0b517601bb7408e2e611c9226f47dcccbd83333d7fc5157f1d32ed2b953d" ;; |
| 82 | + MINGW64_NT-x86_64|MSYS_NT-x86_64) ASSET="sfw-windows-x86_64.exe" ; SFW_BIN="$SFW_DIR/sfw.exe" ; EXPECTED_SHA256="9a50e1ddaf038138c3f85418dc5df0113bbe6fc884f5abe158beaa9aea18d70a" ;; |
| 83 | + *) echo "Unsupported platform: ${KERNEL}-${ARCH}" >&2; exit 1 ;; |
| 84 | + esac |
| 85 | + else |
| 86 | + REPO="SocketDev/sfw-free" |
| 87 | + case "${KERNEL}-${ARCH}" in |
| 88 | + Linux-x86_64) ASSET="sfw-free-linux-x86_64" ; SFW_BIN="$SFW_DIR/sfw" ; EXPECTED_SHA256="4a1e8b65e90fce7d5fd066cf0af6c93d512065fa4222a475c8d959a6bc14b9ff" ;; |
| 89 | + Linux-aarch64) ASSET="sfw-free-linux-arm64" ; SFW_BIN="$SFW_DIR/sfw" ; EXPECTED_SHA256="df2eedb2daf2572eee047adb8bfd81c9069edcb200fc7d3710fca98ec3ca81a1" ;; |
| 90 | + Darwin-x86_64) ASSET="sfw-free-macos-x86_64" ; SFW_BIN="$SFW_DIR/sfw" ; EXPECTED_SHA256="724ccea19d847b79db8cc8e38f5f18ce2dd32336007f42b11bed7d2e5f4a2566" ;; |
| 91 | + Darwin-arm64) ASSET="sfw-free-macos-arm64" ; SFW_BIN="$SFW_DIR/sfw" ; EXPECTED_SHA256="bf1616fc44ac49f1cb2067fedfa127a3ae65d6ec6d634efbb3098cfa355e5555" ;; |
| 92 | + MINGW64_NT-x86_64|MSYS_NT-x86_64) ASSET="sfw-free-windows-x86_64.exe" ; SFW_BIN="$SFW_DIR/sfw.exe" ; EXPECTED_SHA256="c953e62ad7928d4d8f2302f5737884ea1a757babc26bed6a42b9b6b68a5d54af" ;; |
| 93 | + *) echo "Unsupported platform: ${KERNEL}-${ARCH}" >&2; exit 1 ;; |
| 94 | + esac |
| 95 | + fi |
| 96 | + if [ ! -x "$SFW_BIN" ]; then |
| 97 | + mkdir -p "$SFW_DIR" |
| 98 | + DOWNLOAD_URL="$(gh api "repos/${REPO}/releases/latest" \ |
| 99 | + --jq ".assets[] | select(.name == \"$ASSET\") | .browser_download_url")" |
| 100 | + curl -fsSL -o "$SFW_BIN" "$DOWNLOAD_URL" |
| 101 | + ACTUAL_SHA256="$( (sha256sum "$SFW_BIN" 2>/dev/null || shasum -a 256 "$SFW_BIN") | cut -d' ' -f1 | tr -d '\\')" |
| 102 | + if [ "$ACTUAL_SHA256" != "$EXPECTED_SHA256" ]; then |
| 103 | + echo "Checksum mismatch for ${ASSET}!" >&2 |
| 104 | + echo " Expected: ${EXPECTED_SHA256}" >&2 |
| 105 | + echo " Actual: ${ACTUAL_SHA256}" >&2 |
| 106 | + rm -f "$SFW_BIN" |
| 107 | + exit 1 |
| 108 | + fi |
| 109 | + chmod +x "$SFW_BIN" |
| 110 | + fi |
| 111 | + echo "SFW_BIN=$SFW_BIN" >> "${GITHUB_ENV:-/dev/null}" |
| 112 | + echo "SFW_IS_ENTERPRISE=$USE_ENTERPRISE" >> "${GITHUB_ENV:-/dev/null}" |
| 113 | + if $USE_ENTERPRISE; then |
| 114 | + echo "SOCKET_API_KEY=$SOCKET_API_KEY" >> "${GITHUB_ENV:-/dev/null}" |
| 115 | + fi |
| 116 | +
|
| 117 | + - name: Create sfw shims |
| 118 | + shell: bash |
| 119 | + run: | # zizmor: ignore[github-env] |
| 120 | + # Shim supported package managers so their commands route through sfw. |
| 121 | + # |
| 122 | + # Wrapper mode ecosystems (sfw-free): |
| 123 | + # JavaScript/TypeScript: npm, yarn, pnpm |
| 124 | + # Python: pip, uv |
| 125 | + # Rust: cargo |
| 126 | + # https://github.com/SocketDev/sfw-free?tab=readme-ov-file#supported-package-managers |
| 127 | + # |
| 128 | + # Additional wrapper mode ecosystems (sfw-enterprise): |
| 129 | + # Ruby: gem, bundler |
| 130 | + # .NET: nuget |
| 131 | + # Go: go (Linux only) |
| 132 | + # https://github.com/SocketDev/firewall-release/wiki#support-matrix |
| 133 | + SHIM_DIR="${RUNNER_TEMP:-/tmp}/sfw-shim" |
| 134 | + rm -rf "$SHIM_DIR" |
| 135 | + mkdir -p "$SHIM_DIR" |
| 136 | + IS_WINDOWS=false |
| 137 | + [[ "$OSTYPE" == msys* || "$OSTYPE" == cygwin* ]] && IS_WINDOWS=true |
| 138 | + msys_to_win_path() { |
| 139 | + if $IS_WINDOWS && [[ "$1" =~ ^/([a-zA-Z])/(.*) ]]; then |
| 140 | + echo "${BASH_REMATCH[1]^^}:\\${BASH_REMATCH[2]//\//\\}" |
| 141 | + else |
| 142 | + echo "$1" |
| 143 | + fi |
| 144 | + } |
| 145 | + strip_shim_dir() { echo "$PATH" | tr ':' '\n' | grep -vxF "$SHIM_DIR" | paste -sd: -; } |
| 146 | + CLEAN_PATH="$(strip_shim_dir)" |
| 147 | + SSL_WORKAROUND="" |
| 148 | + SHIM_CMDS="npm yarn pnpm pip uv cargo" |
| 149 | + if [ "$SFW_IS_ENTERPRISE" = "true" ]; then |
| 150 | + SHIM_CMDS="npm yarn pnpm pip uv cargo gem bundler nuget" |
| 151 | + # Go wrapper mode is only supported on Linux. |
| 152 | + [[ "$OSTYPE" == linux* ]] && SHIM_CMDS="$SHIM_CMDS go" |
| 153 | + else |
| 154 | + SSL_WORKAROUND='export GIT_SSL_NO_VERIFY=true # Workaround: sfw-free does not yet set GIT_SSL_CAINFO.' |
| 155 | + fi |
| 156 | + for CMD in $SHIM_CMDS; do |
| 157 | + REAL="$(PATH="$CLEAN_PATH" command -v "$CMD" 2>/dev/null || true)" |
| 158 | + [ -z "$REAL" ] && continue |
| 159 | + REAL="$(msys_to_win_path "$REAL")" |
| 160 | + SHIM_LINES=('#!/bin/bash' "export PATH=\"\$(echo \"\$PATH\" | tr ':' '\n' | grep -vxF '${SHIM_DIR}' | paste -sd: -)\"") |
| 161 | + [ -n "$SSL_WORKAROUND" ] && SHIM_LINES+=("$SSL_WORKAROUND") |
| 162 | + SHIM_LINES+=("exec \"${SFW_BIN}\" \"${REAL}\" \"\$@\"") |
| 163 | + printf '%s\n' "${SHIM_LINES[@]}" > "$SHIM_DIR/$CMD" |
| 164 | + chmod +x "$SHIM_DIR/$CMD" |
| 165 | + if $IS_WINDOWS; then |
| 166 | + printf '@echo off\r\nset "PATH=;%%PATH%%;"\r\nset "PATH=%%PATH:;%s;=;%%"\r\nset "PATH=%%PATH:~1,-1%%"\r\n"%s" "%s" %%*\r\n' \ |
| 167 | + "$SHIM_DIR" "$SFW_BIN" "$REAL" > "$SHIM_DIR/$CMD.cmd" |
| 168 | + fi |
| 169 | + done |
| 170 | + echo "$SHIM_DIR" >> "${GITHUB_PATH:-/dev/null}" |
| 171 | + echo "SFW_SHIM_DIR=$SHIM_DIR" >> "${GITHUB_ENV:-/dev/null}" |
0 commit comments