Skip to content

Commit 982c181

Browse files
committed
ci: cross-compile native binaries for releases via bun
Adds a matrix workflow that builds single-file native binaries for linux x64/arm64, darwin x64/arm64, and windows x64 on tag push and attaches them to the GitHub release. Stubs ink's devtools entry at build time so bun-compile doesn't fail on react-devtools-core, which production paths never load anyway. workflow_dispatch lets us backfill binaries onto an existing release without a version bump.
1 parent d4267b6 commit 982c181

1 file changed

Lines changed: 108 additions & 0 deletions

File tree

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
name: Build binaries
2+
3+
# Cross-compile single-file native binaries for the major desktop targets
4+
# and attach them to the GitHub release. Runs in parallel with release.yml;
5+
# softprops/action-gh-release@v2 is idempotent so the npm-publish workflow
6+
# creating the release and the binary jobs attaching assets coexist
7+
# without coordination.
8+
9+
on:
10+
push:
11+
tags:
12+
- "v2.*"
13+
# Manual trigger so we can backfill binaries onto an existing release
14+
# without bumping the version. Pass the tag name as input.
15+
workflow_dispatch:
16+
inputs:
17+
tag:
18+
description: "Tag to build (e.g. v2.0.0-pre.54)"
19+
required: true
20+
21+
permissions:
22+
contents: write
23+
24+
jobs:
25+
build:
26+
name: Build ${{ matrix.asset }}
27+
runs-on: ubuntu-latest
28+
strategy:
29+
fail-fast: false
30+
matrix:
31+
include:
32+
- target: bun-linux-x64-modern
33+
asset: codebase-linux-x64
34+
- target: bun-linux-arm64
35+
asset: codebase-linux-arm64
36+
- target: bun-darwin-x64
37+
asset: codebase-darwin-x64
38+
- target: bun-darwin-arm64
39+
asset: codebase-darwin-arm64
40+
- target: bun-windows-x64
41+
asset: codebase-windows-x64.exe
42+
steps:
43+
- uses: actions/checkout@v4
44+
with:
45+
# For workflow_dispatch runs, check out the tag passed as input
46+
# so the build matches that version. Falls back to GITHUB_REF
47+
# on tag-push triggers.
48+
ref: ${{ inputs.tag || github.ref }}
49+
50+
- uses: oven-sh/setup-bun@v2
51+
with:
52+
bun-version: "1.3.14"
53+
54+
- uses: actions/setup-node@v4
55+
with:
56+
node-version: "20"
57+
cache: npm
58+
59+
- name: Install
60+
run: npm ci
61+
62+
- name: Stub ink devtools
63+
# ink's devtools entry has a top-level `import 'react-devtools-core'`
64+
# behind a runtime gate, but bun's bundler eagerly resolves the
65+
# dynamic import. Replace the entry with an empty stub so the
66+
# compiled binary doesn't try to find react-devtools-core at
67+
# runtime. Production paths never load this anyway (DEV != 'true').
68+
run: |
69+
cat > node_modules/ink/build/devtools.js <<'EOF'
70+
export default { connectToDevTools() {} };
71+
EOF
72+
73+
- name: Compile ${{ matrix.target }}
74+
run: bun build --compile --target=${{ matrix.target }} src/cli.tsx --outfile=${{ matrix.asset }}
75+
76+
- name: Smoke-test binary
77+
# Only the linux-x64 binary can run on the linux runner. The
78+
# other targets are cross-compiled — we trust bun's compile output
79+
# for them and verify post-release.
80+
if: matrix.target == 'bun-linux-x64-modern'
81+
run: ./${{ matrix.asset }} --version || true
82+
83+
- name: Upload to GitHub release
84+
env:
85+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
86+
TAG: ${{ inputs.tag || github.ref_name }}
87+
# --clobber so a re-run replaces the file rather than failing.
88+
# The release itself is created by release.yml (or the first
89+
# uploader, whichever wins the race).
90+
run: |
91+
# Wait briefly for release.yml to create the release shell.
92+
for i in 1 2 3 4 5 6; do
93+
if gh release view "${TAG}" >/dev/null 2>&1; then
94+
break
95+
fi
96+
echo "Waiting for release ${TAG} (attempt $i)…"
97+
sleep 10
98+
done
99+
# If release.yml hasn't run yet (or failed), create the release ourselves.
100+
if ! gh release view "${TAG}" >/dev/null 2>&1; then
101+
PRERELEASE_FLAG=""
102+
if [[ "${TAG}" == *-* ]]; then PRERELEASE_FLAG="--prerelease"; fi
103+
gh release create "${TAG}" \
104+
--title "${TAG}" \
105+
--generate-notes \
106+
${PRERELEASE_FLAG}
107+
fi
108+
gh release upload "${TAG}" "${{ matrix.asset }}" --clobber

0 commit comments

Comments
 (0)