Skip to content

Commit e1ed552

Browse files
committed
feat: implement @socketbin binary distribution system
- Add package generator script for creating @socketbin/* packages - Create dispatcher script that selects correct platform binary - Add GitHub Actions workflow for building and publishing with provenance - Update socket package to use optionalDependencies instead of postinstall - Remove install.js in favor of npm's built-in optional dependency handling This new approach eliminates postinstall failures and simplifies distribution
1 parent 456f623 commit e1ed552

File tree

4 files changed

+616
-5
lines changed

4 files changed

+616
-5
lines changed
Lines changed: 299 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,299 @@
1+
name: Publish @socketbin Packages
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: 'Version to publish (without v prefix)'
8+
required: true
9+
type: string
10+
dry-run:
11+
description: 'Dry run (build but do not publish)'
12+
required: false
13+
type: boolean
14+
default: false
15+
release:
16+
types: [published]
17+
18+
jobs:
19+
build-binaries:
20+
name: Build ${{ matrix.platform }}-${{ matrix.arch }}
21+
runs-on: ${{ matrix.os }}
22+
strategy:
23+
fail-fast: false
24+
matrix:
25+
include:
26+
# Linux builds
27+
- os: ubuntu-latest
28+
platform: linux
29+
arch: x64
30+
- os: ubuntu-latest
31+
platform: linux
32+
arch: arm64
33+
34+
# macOS builds
35+
- os: macos-latest
36+
platform: darwin
37+
arch: x64
38+
- os: macos-latest
39+
platform: darwin
40+
arch: arm64
41+
42+
# Windows builds
43+
- os: windows-latest
44+
platform: win32
45+
arch: x64
46+
- os: windows-latest
47+
platform: win32
48+
arch: arm64
49+
50+
steps:
51+
- name: Checkout
52+
uses: actions/checkout@v4
53+
54+
- name: Setup Node.js
55+
uses: actions/setup-node@v4
56+
with:
57+
node-version: 22
58+
registry-url: 'https://registry.npmjs.org'
59+
60+
- name: Setup pnpm
61+
uses: pnpm/action-setup@v3
62+
with:
63+
version: 8
64+
65+
- name: Install dependencies
66+
run: pnpm install --frozen-lockfile
67+
68+
- name: Build stub
69+
run: pnpm run build:sea:stub
70+
71+
- name: Build binary
72+
run: |
73+
pnpm run build:sea -- \
74+
--platform=${{ matrix.platform }} \
75+
--arch=${{ matrix.arch }}
76+
77+
- name: Verify binary
78+
run: |
79+
ls -la dist/sea/socket-*
80+
file dist/sea/socket-* || true
81+
82+
- name: Upload binary artifact
83+
uses: actions/upload-artifact@v4
84+
with:
85+
name: binary-${{ matrix.platform }}-${{ matrix.arch }}
86+
path: dist/sea/socket-*
87+
retention-days: 1
88+
89+
publish-packages:
90+
name: Publish to npm
91+
needs: build-binaries
92+
runs-on: ubuntu-latest
93+
permissions:
94+
contents: read
95+
id-token: write # For provenance
96+
97+
steps:
98+
- name: Checkout
99+
uses: actions/checkout@v4
100+
101+
- name: Setup Node.js
102+
uses: actions/setup-node@v4
103+
with:
104+
node-version: 22
105+
registry-url: 'https://registry.npmjs.org'
106+
107+
- name: Determine version
108+
id: version
109+
run: |
110+
if [[ "${{ github.event_name }}" == "release" ]]; then
111+
VERSION="${{ github.event.release.tag_name }}"
112+
else
113+
VERSION="${{ inputs.version }}"
114+
fi
115+
# Remove 'v' prefix if present
116+
VERSION="${VERSION#v}"
117+
echo "version=${VERSION}" >> $GITHUB_OUTPUT
118+
119+
- name: Download all binaries
120+
uses: actions/download-artifact@v4
121+
with:
122+
path: dist/sea
123+
pattern: binary-*
124+
125+
- name: Organize binaries
126+
run: |
127+
# Flatten directory structure from artifacts
128+
for dir in dist/sea/binary-*; do
129+
if [ -d "$dir" ]; then
130+
mv "$dir"/* dist/sea/
131+
rmdir "$dir"
132+
fi
133+
done
134+
135+
# List all binaries
136+
echo "Downloaded binaries:"
137+
ls -la dist/sea/
138+
139+
- name: Generate and publish Linux x64
140+
if: ${{ !inputs.dry-run }}
141+
run: |
142+
node scripts/generate-binary-package.mjs \
143+
--platform=linux --arch=x64 \
144+
--version=${{ steps.version.outputs.version }}
145+
146+
cd packages/binaries/cli-linux-x64
147+
npm publish --provenance --access public
148+
env:
149+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
150+
151+
- name: Generate and publish Linux ARM64
152+
if: ${{ !inputs.dry-run }}
153+
run: |
154+
node scripts/generate-binary-package.mjs \
155+
--platform=linux --arch=arm64 \
156+
--version=${{ steps.version.outputs.version }}
157+
158+
cd packages/binaries/cli-linux-arm64
159+
npm publish --provenance --access public
160+
env:
161+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
162+
163+
- name: Generate and publish macOS x64
164+
if: ${{ !inputs.dry-run }}
165+
run: |
166+
node scripts/generate-binary-package.mjs \
167+
--platform=darwin --arch=x64 \
168+
--version=${{ steps.version.outputs.version }}
169+
170+
cd packages/binaries/cli-darwin-x64
171+
npm publish --provenance --access public
172+
env:
173+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
174+
175+
- name: Generate and publish macOS ARM64
176+
if: ${{ !inputs.dry-run }}
177+
run: |
178+
node scripts/generate-binary-package.mjs \
179+
--platform=darwin --arch=arm64 \
180+
--version=${{ steps.version.outputs.version }}
181+
182+
cd packages/binaries/cli-darwin-arm64
183+
npm publish --provenance --access public
184+
env:
185+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
186+
187+
- name: Generate and publish Windows x64
188+
if: ${{ !inputs.dry-run }}
189+
run: |
190+
node scripts/generate-binary-package.mjs \
191+
--platform=win32 --arch=x64 \
192+
--version=${{ steps.version.outputs.version }}
193+
194+
cd packages/binaries/cli-win32-x64
195+
npm publish --provenance --access public
196+
env:
197+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
198+
199+
- name: Generate and publish Windows ARM64
200+
if: ${{ !inputs.dry-run }}
201+
run: |
202+
node scripts/generate-binary-package.mjs \
203+
--platform=win32 --arch=arm64 \
204+
--version=${{ steps.version.outputs.version }}
205+
206+
cd packages/binaries/cli-win32-arm64
207+
npm publish --provenance --access public
208+
env:
209+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
210+
211+
- name: Dry run summary
212+
if: ${{ inputs.dry-run }}
213+
run: |
214+
echo "🚫 Dry run mode - packages were NOT published"
215+
echo ""
216+
echo "Generated packages:"
217+
find packages/binaries -name package.json -exec echo {} \; -exec jq -r '.name + "@" + .version' {} \;
218+
219+
publish-main:
220+
name: Publish main socket package
221+
needs: publish-packages
222+
runs-on: ubuntu-latest
223+
permissions:
224+
contents: read
225+
id-token: write
226+
227+
steps:
228+
- name: Checkout
229+
uses: actions/checkout@v4
230+
231+
- name: Setup Node.js
232+
uses: actions/setup-node@v4
233+
with:
234+
node-version: 22
235+
registry-url: 'https://registry.npmjs.org'
236+
237+
- name: Determine version
238+
id: version
239+
run: |
240+
if [[ "${{ github.event_name }}" == "release" ]]; then
241+
VERSION="${{ github.event.release.tag_name }}"
242+
else
243+
VERSION="${{ inputs.version }}"
244+
fi
245+
VERSION="${VERSION#v}"
246+
echo "version=${VERSION}" >> $GITHUB_OUTPUT
247+
248+
- name: Update package.json for @socketbin
249+
run: |
250+
cd src/sea/npm-package
251+
252+
# Update version
253+
npm version ${{ steps.version.outputs.version }} --no-git-tag-version
254+
255+
# Update package.json to use optionalDependencies
256+
node -e "
257+
const fs = require('fs');
258+
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
259+
260+
// Remove old postinstall script
261+
delete pkg.scripts?.postinstall;
262+
263+
// Add dispatcher script to bin
264+
pkg.bin = { socket: 'bin/socket.js' };
265+
266+
// Add optionalDependencies
267+
pkg.optionalDependencies = {
268+
'@socketbin/cli-darwin-arm64': '${{ steps.version.outputs.version }}',
269+
'@socketbin/cli-darwin-x64': '${{ steps.version.outputs.version }}',
270+
'@socketbin/cli-linux-arm64': '${{ steps.version.outputs.version }}',
271+
'@socketbin/cli-linux-x64': '${{ steps.version.outputs.version }}',
272+
'@socketbin/cli-win32-arm64': '${{ steps.version.outputs.version }}',
273+
'@socketbin/cli-win32-x64': '${{ steps.version.outputs.version }}'
274+
};
275+
276+
// Update files list
277+
pkg.files = ['bin', 'README.md'];
278+
279+
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
280+
"
281+
282+
# Show the updated package.json
283+
cat package.json
284+
285+
- name: Publish main package
286+
if: ${{ !inputs.dry-run }}
287+
working-directory: src/sea/npm-package
288+
run: npm publish --provenance --access public
289+
env:
290+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
291+
292+
- name: Dry run summary
293+
if: ${{ inputs.dry-run }}
294+
run: |
295+
echo "🚫 Dry run mode - main package was NOT published"
296+
echo ""
297+
echo "Would have published:"
298+
cd src/sea/npm-package
299+
echo "socket@$(jq -r .version package.json)"

0 commit comments

Comments
 (0)