diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 84f14a5..62fe17e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,6 +8,9 @@ on: permissions: contents: write +env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" + jobs: # Phase 1: Build in parallel and output artifacts build: @@ -306,7 +309,7 @@ jobs: fi BEFORE_BYTES=$(wc -c <"$APP_BIN" | tr -d '[:space:]') echo "🗜️ 正在使用 UPX 压缩 macOS 可执行文件: $APP_BIN ..." - upx --best --lzma --force "$APP_BIN" + upx --best --lzma --force --force-macos "$APP_BIN" upx -t "$APP_BIN" AFTER_BYTES=$(wc -c <"$APP_BIN" | tr -d '[:space:]') if [ "$AFTER_BYTES" -lt "$BEFORE_BYTES" ]; then @@ -361,21 +364,35 @@ jobs: exit 1 } - $upxCmd = Get-Command upx -ErrorAction SilentlyContinue - if ($null -eq $upxCmd) { - Write-Error "❌ 未找到 upx,无法保证 Windows 产物经过压缩" - exit 1 - } - $beforeBytes = (Get-Item -LiteralPath $finalExe).Length - Write-Host "🗜️ 使用 UPX 压缩 $finalExe ..." - & upx --best --lzma --force $finalExe | Out-Host - & upx -t $finalExe | Out-Host - $afterBytes = (Get-Item -LiteralPath $finalExe).Length - if ($afterBytes -lt $beforeBytes) { - $savedBytes = $beforeBytes - $afterBytes - Write-Host ("✅ UPX 压缩完成:{0:N2}MB -> {1:N2}MB,减少 {2:N2}MB" -f ($beforeBytes / 1MB), ($afterBytes / 1MB), ($savedBytes / 1MB)) + $isArm64Target = "${{ matrix.arch_name }}".ToLowerInvariant() -eq "arm64" + if ($isArm64Target) { + Write-Warning "⚠️ UPX 当前不支持 win64/arm64,跳过压缩并保留原始 EXE。" + $LASTEXITCODE = 0 } else { - Write-Host ("ℹ️ UPX 压缩完成:{0:N2}MB -> {1:N2}MB" -f ($beforeBytes / 1MB), ($afterBytes / 1MB)) + $upxCmd = Get-Command upx -ErrorAction SilentlyContinue + if ($null -eq $upxCmd) { + Write-Error "❌ 未找到 upx,无法保证 Windows 产物经过压缩" + exit 1 + } + $beforeBytes = (Get-Item -LiteralPath $finalExe).Length + Write-Host "🗜️ 使用 UPX 压缩 $finalExe ..." + & upx --best --lzma --force $finalExe | Out-Host + if ($LASTEXITCODE -ne 0) { + Write-Error "❌ UPX 压缩失败($LASTEXITCODE)" + exit 1 + } + & upx -t $finalExe | Out-Host + if ($LASTEXITCODE -ne 0) { + Write-Error "❌ UPX 校验失败($LASTEXITCODE)" + exit 1 + } + $afterBytes = (Get-Item -LiteralPath $finalExe).Length + if ($afterBytes -lt $beforeBytes) { + $savedBytes = $beforeBytes - $afterBytes + Write-Host ("✅ UPX 压缩完成:{0:N2}MB -> {1:N2}MB,减少 {2:N2}MB" -f ($beforeBytes / 1MB), ($afterBytes / 1MB), ($savedBytes / 1MB)) + } else { + Write-Host ("ℹ️ UPX 压缩完成:{0:N2}MB -> {1:N2}MB" -f ($beforeBytes / 1MB), ($afterBytes / 1MB)) + } } Write-Host "📦 输出 Windows 可执行文件 $finalExeName..." diff --git a/.github/workflows/test-build-all-platforms.yml b/.github/workflows/test-build-all-platforms.yml index 6646ece..d978dfe 100644 --- a/.github/workflows/test-build-all-platforms.yml +++ b/.github/workflows/test-build-all-platforms.yml @@ -11,6 +11,9 @@ on: permissions: contents: read +env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" + concurrency: group: test-build-${{ github.ref }} cancel-in-progress: false @@ -270,7 +273,7 @@ jobs: fi BEFORE_BYTES=$(wc -c <"$APP_BIN" | tr -d '[:space:]') echo "🗜️ 使用 UPX 压缩 macOS 可执行文件: $APP_BIN ..." - upx --best --lzma --force "$APP_BIN" + upx --best --lzma --force --force-macos "$APP_BIN" upx -t "$APP_BIN" AFTER_BYTES=$(wc -c <"$APP_BIN" | tr -d '[:space:]') if [ "$AFTER_BYTES" -lt "$BEFORE_BYTES" ]; then @@ -316,21 +319,35 @@ jobs: Write-Error "未找到构建产物 '$target'" exit 1 } - $upxCmd = Get-Command upx -ErrorAction SilentlyContinue - if ($null -eq $upxCmd) { - Write-Error "❌ 未找到 upx,无法保证 Windows 测试产物经过压缩" - exit 1 - } - $beforeBytes = (Get-Item -LiteralPath $finalExe).Length - Write-Host "🗜️ 使用 UPX 压缩 $finalExe ..." - & upx --best --lzma --force $finalExe | Out-Host - & upx -t $finalExe | Out-Host - $afterBytes = (Get-Item -LiteralPath $finalExe).Length - if ($afterBytes -lt $beforeBytes) { - $savedBytes = $beforeBytes - $afterBytes - Write-Host ("✅ UPX 压缩完成:{0:N2}MB -> {1:N2}MB,减少 {2:N2}MB" -f ($beforeBytes / 1MB), ($afterBytes / 1MB), ($savedBytes / 1MB)) + $isArm64Target = "${{ matrix.arch_name }}".ToLowerInvariant() -eq "arm64" + if ($isArm64Target) { + Write-Warning "⚠️ UPX 当前不支持 win64/arm64,跳过压缩并保留原始 EXE。" + $LASTEXITCODE = 0 } else { - Write-Host ("ℹ️ UPX 压缩完成:{0:N2}MB -> {1:N2}MB" -f ($beforeBytes / 1MB), ($afterBytes / 1MB)) + $upxCmd = Get-Command upx -ErrorAction SilentlyContinue + if ($null -eq $upxCmd) { + Write-Error "❌ 未找到 upx,无法保证 Windows 测试产物经过压缩" + exit 1 + } + $beforeBytes = (Get-Item -LiteralPath $finalExe).Length + Write-Host "🗜️ 使用 UPX 压缩 $finalExe ..." + & upx --best --lzma --force $finalExe | Out-Host + if ($LASTEXITCODE -ne 0) { + Write-Error "❌ UPX 压缩失败($LASTEXITCODE)" + exit 1 + } + & upx -t $finalExe | Out-Host + if ($LASTEXITCODE -ne 0) { + Write-Error "❌ UPX 校验失败($LASTEXITCODE)" + exit 1 + } + $afterBytes = (Get-Item -LiteralPath $finalExe).Length + if ($afterBytes -lt $beforeBytes) { + $savedBytes = $beforeBytes - $afterBytes + Write-Host ("✅ UPX 压缩完成:{0:N2}MB -> {1:N2}MB,减少 {2:N2}MB" -f ($beforeBytes / 1MB), ($afterBytes / 1MB), ($savedBytes / 1MB)) + } else { + Write-Host ("ℹ️ UPX 压缩完成:{0:N2}MB -> {1:N2}MB" -f ($beforeBytes / 1MB), ($afterBytes / 1MB)) + } } New-Item -ItemType Directory -Force -Path ..\..\artifacts | Out-Null Copy-Item -LiteralPath $finalExe -Destination "..\..\artifacts\$finalExeName" -Force diff --git a/.github/workflows/test-macos-build.yml b/.github/workflows/test-macos-build.yml index 1dd01af..d022e91 100644 --- a/.github/workflows/test-macos-build.yml +++ b/.github/workflows/test-macos-build.yml @@ -16,6 +16,9 @@ on: permissions: contents: read +env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" + jobs: build-macos: name: Build macOS ${{ matrix.arch }} diff --git a/build-release.sh b/build-release.sh index 22fe7c8..8e4a4a7 100755 --- a/build-release.sh +++ b/build-release.sh @@ -45,6 +45,7 @@ format_size_mb() { try_compress_binary_with_upx() { local exe_path="$1" local label="$2" + local is_macos_binary="${3:-false}" if [ ! -f "$exe_path" ]; then echo -e "${RED} ❌ 未找到 ${label} 文件:$exe_path${NC}" exit 1 @@ -63,10 +64,21 @@ try_compress_binary_with_upx() { exit 1 fi + local upx_cmd=(upx --best --lzma --force) + if [ "$is_macos_binary" = "true" ]; then + if upx --help 2>&1 | grep -q -- "--force-macos"; then + upx_cmd+=(--force-macos) + else + echo -e "${RED} ❌ 当前 upx 不支持 --force-macos,无法压缩 ${label}。${NC}" + echo " 请升级 upx 到支持 macOS 压缩的版本(UPX 5+)。" + exit 1 + fi + fi + local before_bytes after_bytes before_bytes=$(get_file_size_bytes "$exe_path") echo " 🗜️ 正在使用 UPX 压缩 ${label}..." - if upx --best --lzma --force "$exe_path" >/dev/null 2>&1; then + if "${upx_cmd[@]}" "$exe_path" >/dev/null 2>&1; then if ! upx -t "$exe_path" >/dev/null 2>&1; then echo -e "${RED} ❌ UPX 校验失败:${label}${NC}" exit 1 @@ -108,7 +120,7 @@ if [ $? -eq 0 ]; then APP_BIN_PATH=$(find "$DIST_DIR/$APP_DEST_NAME/Contents/MacOS" -maxdepth 1 -type f -print -quit) if [ -n "$APP_BIN_PATH" ] && [ -f "$APP_BIN_PATH" ]; then - try_compress_binary_with_upx "$APP_BIN_PATH" "macOS arm64 应用主程序" + try_compress_binary_with_upx "$APP_BIN_PATH" "macOS arm64 应用主程序" "true" else echo -e "${RED} ❌ 未找到 macOS arm64 主程序文件,无法执行 UPX 压缩。${NC}" exit 1 @@ -215,7 +227,7 @@ if [ $? -eq 0 ]; then APP_BIN_PATH=$(find "$DIST_DIR/$APP_DEST_NAME/Contents/MacOS" -maxdepth 1 -type f -print -quit) if [ -n "$APP_BIN_PATH" ] && [ -f "$APP_BIN_PATH" ]; then - try_compress_binary_with_upx "$APP_BIN_PATH" "macOS amd64 应用主程序" + try_compress_binary_with_upx "$APP_BIN_PATH" "macOS amd64 应用主程序" "true" else echo -e "${RED} ❌ 未找到 macOS amd64 主程序文件,无法执行 UPX 压缩。${NC}" exit 1 @@ -327,7 +339,7 @@ if command -v aarch64-w64-mingw32-gcc &> /dev/null; then if [ $? -eq 0 ]; then TARGET_EXE="$DIST_DIR/${APP_NAME}-${VERSION}-windows-arm64.exe" mv "$BUILD_BIN_DIR/${DEFAULT_BINARY_NAME}.exe" "$TARGET_EXE" - try_compress_binary_with_upx "$TARGET_EXE" "Windows arm64 可执行文件" + echo -e "${YELLOW} ⚠️ 当前 UPX 不支持 win64/arm64,跳过 Windows arm64 压缩。${NC}" echo " ✅ 已生成 ${APP_NAME}-${VERSION}-windows-arm64.exe" else echo -e "${RED} ❌ Windows arm64 构建失败。${NC}"