From e26a456eaece355ec0922a7e85292a689581a831 Mon Sep 17 00:00:00 2001 From: Syngnat Date: Thu, 12 Mar 2026 17:54:09 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20fix(release/ci):=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E8=B7=A8=E5=B9=B3=E5=8F=B0UPX=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E5=B9=B6=E5=A4=84=E7=90=86Windows=20ARM64=E6=89=93=E5=8C=85?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CI 工作流统一启用 Node24 JavaScript 运行时,消除 Node20 退役告警干扰 - macOS 打包阶段为 UPX 增加 --force-macos,修复 Mach-O 压缩失败 - Windows 打包按架构分流:arm64 跳过 UPX 并保留原始 EXE,amd64 继续强制压缩 - Windows 压缩流程新增 $LASTEXITCODE 显式校验,避免命令失败被误判为成功 - 本地 build-release.sh 同步 macOS/Windows 的 UPX 兼容策略与错误处理逻辑 --- .github/workflows/release.yml | 47 +++++++++++++------ .../workflows/test-build-all-platforms.yml | 47 +++++++++++++------ .github/workflows/test-macos-build.yml | 3 ++ build-release.sh | 20 ++++++-- 4 files changed, 83 insertions(+), 34 deletions(-) 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}"