Skip to content

Commit 1fd99a4

Browse files
committed
feat(release): add Windows ARM64 and Linux musl prebuilt binary support
Add aarch64-pc-windows-msvc, x86_64-unknown-linux-musl, and aarch64-unknown-linux-musl as build targets in the release pipeline, NAPI config, and publish scripts. Add libc field to CLI platform packages for correct npm resolution on musl vs glibc systems. Add install test jobs for Windows ARM64, Linux musl x64 (Docker), and Linux musl arm64 (QEMU). Document supported platforms in the getting started guide.
1 parent dd10240 commit 1fd99a4

7 files changed

Lines changed: 226 additions & 21 deletions

File tree

.github/actions/build-upstream/action.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ runs:
6262
# Must run before vite-plus TypeScript builds which depend on the bindings
6363
- name: Build NAPI bindings (x86_64-linux)
6464
shell: bash
65-
if: steps.cache-restore.outputs.cache-hit != 'true' && inputs.target == 'x86_64-unknown-linux-gnu'
65+
if: steps.cache-restore.outputs.cache-hit != 'true' && startsWith(inputs.target, 'x86_64-unknown-linux')
6666
run: |
6767
pnpm --filter=vite-plus build-native --target ${{ inputs.target }} --use-napi-cross
6868
env:
@@ -71,7 +71,7 @@ runs:
7171

7272
- name: Build NAPI bindings (aarch64-linux)
7373
shell: bash
74-
if: steps.cache-restore.outputs.cache-hit != 'true' && inputs.target == 'aarch64-unknown-linux-gnu'
74+
if: steps.cache-restore.outputs.cache-hit != 'true' && startsWith(inputs.target, 'aarch64-unknown-linux')
7575
run: |
7676
pnpm --filter=vite-plus build-native --target ${{ inputs.target }} --use-napi-cross
7777
env:
@@ -88,7 +88,7 @@ runs:
8888
DEBUG: napi:*
8989

9090
- name: Build Rust CLI binary (x86_64-linux)
91-
if: steps.cache-restore.outputs.cache-hit != 'true' && inputs.target == 'x86_64-unknown-linux-gnu'
91+
if: steps.cache-restore.outputs.cache-hit != 'true' && startsWith(inputs.target, 'x86_64-unknown-linux')
9292
shell: bash
9393
run: |
9494
pnpm exec napi build --use-napi-cross --target ${{ inputs.target }} --release -p vite_global_cli
@@ -97,7 +97,7 @@ runs:
9797
DEBUG: napi:*
9898

9999
- name: Build Rust CLI binary (aarch64-linux)
100-
if: steps.cache-restore.outputs.cache-hit != 'true' && inputs.target == 'aarch64-unknown-linux-gnu'
100+
if: steps.cache-restore.outputs.cache-hit != 'true' && startsWith(inputs.target, 'aarch64-unknown-linux')
101101
shell: bash
102102
run: |
103103
pnpm exec napi build --use-napi-cross --target ${{ inputs.target }} --release -p vite_global_cli

.github/workflows/release.yml

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,14 @@ jobs:
5050
os: ubuntu-latest
5151
- target: x86_64-unknown-linux-gnu
5252
os: ubuntu-latest
53+
- target: x86_64-unknown-linux-musl
54+
os: ubuntu-latest
55+
- target: aarch64-unknown-linux-musl
56+
os: ubuntu-latest
5357
- target: x86_64-pc-windows-msvc
5458
os: windows-latest
59+
- target: aarch64-pc-windows-msvc
60+
os: windows-latest
5561
steps:
5662
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
5763
- uses: ./.github/actions/clone
@@ -64,14 +70,6 @@ jobs:
6470
- name: Rustup Adds Target
6571
run: rustup target add ${{ matrix.settings.target }}
6672

67-
- name: Add musl target (x86_64)
68-
if: ${{ matrix.settings.target == 'x86_64-unknown-linux-gnu' }}
69-
run: rustup target add x86_64-unknown-linux-musl
70-
71-
- name: Add musl target (aarch64)
72-
if: ${{ matrix.settings.target == 'aarch64-unknown-linux-gnu' }}
73-
run: rustup target add aarch64-unknown-linux-musl
74-
7573
- uses: oxc-project/setup-node@fdbf0dfd334c4e6d56ceeb77d91c76339c2a0885 # v1.0.4
7674

7775
- name: Set binding version

.github/workflows/test-standalone-install.yml

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,119 @@ jobs:
178178
# cd hello && vp run build
179179
"
180180
181+
test-install-sh-musl-x64:
182+
name: Test install.sh (Linux x64 musl via Docker)
183+
runs-on: ubuntu-latest
184+
permissions:
185+
contents: read
186+
steps:
187+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
188+
189+
- name: Run install.sh in Alpine container
190+
run: |
191+
docker run --rm --platform linux/amd64 \
192+
-v "${{ github.workspace }}:/workspace" \
193+
-e VITE_PLUS_VERSION=test \
194+
alpine:3.21 sh -c "
195+
apk add --no-cache curl bash ca-certificates
196+
cat /workspace/packages/cli/install.sh | bash
197+
if [ -f ~/.profile ]; then
198+
source ~/.profile
199+
elif [ -f ~/.bashrc ]; then
200+
source ~/.bashrc
201+
else
202+
export PATH=\"\$HOME/.vite-plus/bin:\$PATH\"
203+
fi
204+
205+
vp --version
206+
vp --help
207+
vp dlx print-current-version
208+
209+
# Verify bin setup
210+
BIN_PATH=\"\$HOME/.vite-plus/bin\"
211+
if [ ! -d \"\$BIN_PATH\" ]; then
212+
echo \"Error: Bin directory not found: \$BIN_PATH\"
213+
exit 1
214+
fi
215+
for shim in node npm npx; do
216+
if [ ! -f \"\$BIN_PATH/\$shim\" ]; then
217+
echo \"Error: Shim not found: \$BIN_PATH/\$shim\"
218+
exit 1
219+
fi
220+
echo \"Found shim: \$BIN_PATH/\$shim\"
221+
done
222+
vp env doctor
223+
224+
export VITE_LOG=trace
225+
vp env run --node 24 -- node -p \"process.versions\"
226+
227+
# Verify upgrade
228+
vp upgrade --check
229+
vp upgrade 0.0.0-f74442ad.20260222-0755
230+
vp --version
231+
vp upgrade --rollback
232+
vp --version
233+
"
234+
235+
test-install-sh-musl-arm64:
236+
name: Test install.sh (Linux ARM64 musl via QEMU)
237+
runs-on: ubuntu-latest
238+
permissions:
239+
contents: read
240+
steps:
241+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
242+
243+
- name: Set up QEMU
244+
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
245+
with:
246+
platforms: arm64
247+
248+
- name: Run install.sh in ARM64 Alpine container
249+
run: |
250+
docker run --rm --platform linux/arm64 \
251+
-v "${{ github.workspace }}:/workspace" \
252+
-e VITE_PLUS_VERSION=test \
253+
alpine:3.21 sh -c "
254+
apk add --no-cache curl bash ca-certificates
255+
cat /workspace/packages/cli/install.sh | bash
256+
if [ -f ~/.profile ]; then
257+
source ~/.profile
258+
elif [ -f ~/.bashrc ]; then
259+
source ~/.bashrc
260+
else
261+
export PATH=\"\$HOME/.vite-plus/bin:\$PATH\"
262+
fi
263+
264+
vp --version
265+
vp --help
266+
vp dlx print-current-version
267+
268+
# Verify bin setup
269+
BIN_PATH=\"\$HOME/.vite-plus/bin\"
270+
if [ ! -d \"\$BIN_PATH\" ]; then
271+
echo \"Error: Bin directory not found: \$BIN_PATH\"
272+
exit 1
273+
fi
274+
for shim in node npm npx; do
275+
if [ ! -f \"\$BIN_PATH/\$shim\" ]; then
276+
echo \"Error: Shim not found: \$BIN_PATH/\$shim\"
277+
exit 1
278+
fi
279+
echo \"Found shim: \$BIN_PATH/\$shim\"
280+
done
281+
vp env doctor
282+
283+
export VITE_LOG=trace
284+
vp env run --node 24 -- node -p \"process.versions\"
285+
286+
# Verify upgrade
287+
vp upgrade --check
288+
vp upgrade 0.0.0-f74442ad.20260222-0755
289+
vp --version
290+
vp upgrade --rollback
291+
vp --version
292+
"
293+
181294
test-install-ps1-v5:
182295
name: Test install.ps1 (Windows x64, PowerShell 5.1)
183296
runs-on: windows-latest
@@ -254,6 +367,73 @@ jobs:
254367
vp upgrade --rollback
255368
vp --version
256369
370+
test-install-ps1-arm64:
371+
name: Test install.ps1 (Windows ARM64)
372+
runs-on: windows-11-arm
373+
permissions:
374+
contents: read
375+
steps:
376+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
377+
378+
- name: Run install.ps1
379+
shell: pwsh
380+
run: |
381+
& ./packages/cli/install.ps1
382+
383+
- name: Set PATH
384+
shell: bash
385+
run: |
386+
echo "$USERPROFILE\.vite-plus\bin" >> $GITHUB_PATH
387+
388+
- name: Verify installation
389+
shell: pwsh
390+
working-directory: ${{ runner.temp }}
391+
run: |
392+
Write-Host "PATH: $env:Path"
393+
vp --version
394+
vp --help
395+
vp create vite --no-interactive --no-agent -- hello --no-interactive -t vanilla
396+
cd hello
397+
vp run build
398+
vp --version
399+
400+
- name: Verify bin setup
401+
shell: pwsh
402+
run: |
403+
$binPath = "$env:USERPROFILE\.vite-plus\bin"
404+
Get-ChildItem -Force $binPath
405+
if (-not (Test-Path $binPath)) {
406+
Write-Error "Bin directory not found: $binPath"
407+
exit 1
408+
}
409+
410+
$expectedShims = @("node.cmd", "npm.cmd", "npx.cmd")
411+
foreach ($shim in $expectedShims) {
412+
$shimFile = Join-Path $binPath $shim
413+
if (-not (Test-Path $shimFile)) {
414+
Write-Error "Shim not found: $shimFile"
415+
exit 1
416+
}
417+
Write-Host "Found shim: $shimFile"
418+
}
419+
where.exe node
420+
where.exe npm
421+
where.exe npx
422+
where.exe vp
423+
424+
$env:Path = "$env:USERPROFILE\.vite-plus\bin;$env:Path"
425+
vp env doctor
426+
vp env run --node 24 -- node -p "process.versions"
427+
428+
- name: Verify upgrade
429+
shell: pwsh
430+
run: |
431+
vp upgrade --check
432+
vp upgrade 0.0.0-f74442ad.20260222-0755
433+
vp --version
434+
vp upgrade --rollback
435+
vp --version
436+
257437
test-install-ps1:
258438
name: Test install.ps1 (Windows x64)
259439
runs-on: windows-latest

crates/vite_global_cli/src/commands/upgrade/registry.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ mod tests {
9999
"darwin-x64",
100100
"linux-arm64-gnu",
101101
"linux-x64-gnu",
102+
"linux-x64-musl",
103+
"linux-arm64-musl",
102104
"win32-arm64-msvc",
103105
"win32-x64-msvc",
104106
];
@@ -123,10 +125,6 @@ mod tests {
123125
for suffix in &detection_suffixes {
124126
let package_name =
125127
format!("{PLATFORM_PACKAGE_SCOPE}/{CLI_PACKAGE_NAME_PREFIX}-{suffix}");
126-
// musl variants are not published, so skip them
127-
if suffix.contains("musl") {
128-
continue;
129-
}
130128
assert!(
131129
published_packages.contains(&package_name),
132130
"Platform suffix '{suffix}' produces CLI package name '{package_name}' \

docs/vite/guide/index.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,25 @@ For Windows:
3232
irm https://staging.viteplus.dev/install.ps1 | iex
3333
```
3434

35+
::: details Supported platforms
36+
37+
Prebuilt binaries are distributed for the following platforms (grouped by [Node.js v24 platform support tier](https://github.com/nodejs/node/blob/v24.x/BUILDING.md#platform-list)):
38+
39+
- Tier 1
40+
- Linux x64 glibc (`x86_64-unknown-linux-gnu`)
41+
- Linux arm64 glibc (`aarch64-unknown-linux-gnu`)
42+
- Windows x64 (`x86_64-pc-windows-msvc`)
43+
- macOS x64 (`x86_64-apple-darwin`)
44+
- macOS arm64 (`aarch64-apple-darwin`)
45+
- Tier 2
46+
- Windows arm64 (`aarch64-pc-windows-msvc`)
47+
- Experimental
48+
- Linux x64 musl (`x86_64-unknown-linux-musl`)
49+
- Other
50+
- Linux arm64 musl (`aarch64-unknown-linux-musl`)
51+
52+
:::
53+
3554
## Node.js Version Manager
3655

3756
Vite+ includes a built-in Node.js version manager. During installation, you can opt-in to let Vite+ manage your Node.js versions.

packages/cli/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,10 @@
339339
"x86_64-apple-darwin",
340340
"aarch64-unknown-linux-gnu",
341341
"x86_64-unknown-linux-gnu",
342-
"x86_64-pc-windows-msvc"
342+
"x86_64-unknown-linux-musl",
343+
"aarch64-unknown-linux-musl",
344+
"x86_64-pc-windows-msvc",
345+
"aarch64-pc-windows-msvc"
343346
]
344347
},
345348
"engines": {

packages/cli/publish-native-addons.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ const RUST_TARGETS: Record<string, string> = {
4646
'darwin-x64': 'x86_64-apple-darwin',
4747
'linux-arm64-gnu': 'aarch64-unknown-linux-gnu',
4848
'linux-x64-gnu': 'x86_64-unknown-linux-gnu',
49+
'linux-x64-musl': 'x86_64-unknown-linux-musl',
50+
'linux-arm64-musl': 'aarch64-unknown-linux-musl',
4951
'win32-arm64-msvc': 'aarch64-pc-windows-msvc',
5052
'win32-x64-msvc': 'x86_64-pc-windows-msvc',
5153
};
@@ -63,11 +65,13 @@ for (const file of platformDirs) {
6365
}
6466

6567
// Platform metadata for CLI packages
66-
const PLATFORM_META: Record<string, { os: string; cpu: string }> = {
68+
const PLATFORM_META: Record<string, { os: string; cpu: string; libc?: string }> = {
6769
'darwin-arm64': { os: 'darwin', cpu: 'arm64' },
6870
'darwin-x64': { os: 'darwin', cpu: 'x64' },
69-
'linux-arm64-gnu': { os: 'linux', cpu: 'arm64' },
70-
'linux-x64-gnu': { os: 'linux', cpu: 'x64' },
71+
'linux-arm64-gnu': { os: 'linux', cpu: 'arm64', libc: 'glibc' },
72+
'linux-x64-gnu': { os: 'linux', cpu: 'x64', libc: 'glibc' },
73+
'linux-x64-musl': { os: 'linux', cpu: 'x64', libc: 'musl' },
74+
'linux-arm64-musl': { os: 'linux', cpu: 'arm64', libc: 'musl' },
7175
'win32-arm64-msvc': { os: 'win32', cpu: 'arm64' },
7276
'win32-x64-msvc': { os: 'win32', cpu: 'x64' },
7377
};
@@ -109,14 +113,17 @@ for (const [platform, rustTarget] of Object.entries(RUST_TARGETS)) {
109113
}
110114

111115
// Generate package.json
112-
const cliPackage = {
116+
const cliPackage: Record<string, unknown> = {
113117
name: `@voidzero-dev/vite-plus-cli-${platform}`,
114118
version: cliVersion,
115119
os: [meta.os],
116120
cpu: [meta.cpu],
117121
files: [binaryName],
118122
description: `Vite+ CLI binary for ${platform}`,
119123
};
124+
if (meta.libc) {
125+
cliPackage.libc = [meta.libc];
126+
}
120127
writeFileSync(join(platformCliDir, 'package.json'), JSON.stringify(cliPackage, null, 2) + '\n');
121128

122129
// Publish CLI package

0 commit comments

Comments
 (0)