From 482a7fce2ecb68f768bb348956aa3aed8e37ed52 Mon Sep 17 00:00:00 2001 From: Syngnat Date: Thu, 12 Mar 2026 17:30:16 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20fix(release/sidebar):=20?= =?UTF-8?q?=E7=BB=9F=E4=B8=80=E8=B7=A8=E5=B9=B3=E5=8F=B0UPX=E5=8E=8B?= =?UTF-8?q?=E7=BC=A9=E5=B9=B6=E4=BF=AE=E5=A4=8DPG=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E6=9F=A5=E8=AF=A2=E5=85=BC=E5=AE=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 构建脚本新增通用 UPX 压缩函数,覆盖 macOS、Linux、Windows 产物 - 本地打包改为强制压缩策略:未安装 upx、压缩失败或校验失败直接终止 - macOS 打包在签名前压缩 .app 主程序并执行 upx -t 校验 - Linux 打包在生成 tar.gz 前压缩可执行文件并执行 upx -t 校验 - GitHub Release 与测试构建流程补齐 macOS/Linux/Windows 的 upx 安装与压缩步骤 - PostgreSQL/PG-like 函数元数据查询增加多路兼容 SQL,修复函数列表不显示问题 - refs #221 - refs #222 --- .github/workflows/release.yml | 75 ++++++++++-- .../workflows/test-build-all-platforms.yml | 67 ++++++++++- build-release.sh | 112 ++++++++++++++++-- frontend/src/components/Sidebar.tsx | 15 ++- 4 files changed, 248 insertions(+), 21 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7dd9b87..84f14a5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -88,6 +88,24 @@ jobs: with: node-version: '20' + - name: Install UPX (macOS) + if: contains(matrix.platform, 'darwin') + run: | + brew install upx + upx --version + + - name: Install UPX (Windows) + if: contains(matrix.platform, 'windows') + shell: pwsh + run: | + choco install upx --no-progress -y + $upxCmd = Get-Command upx -ErrorAction SilentlyContinue + if ($null -eq $upxCmd) { + Write-Error "❌ 未检测到 upx,无法保证 Windows 产物经过压缩" + exit 1 + } + & upx --version + # Linux Dependencies (GTK3, WebKit2GTK required by Wails) - name: Install Linux Dependencies if: contains(matrix.platform, 'linux') @@ -102,6 +120,9 @@ jobs: sudo apt-get install -y libwebkit2gtk-4.0-dev fi + sudo apt-get install -y upx-ucl || sudo apt-get install -y upx + upx --version + # AppImage 运行/打包可能需要 FUSE2。不同发行版/版本包名不同,做兼容兜底。 sudo apt-get install -y libfuse2 || sudo apt-get install -y libfuse2t64 || true @@ -277,6 +298,23 @@ jobs: exit 1 fi APP_NAME=$(basename "$APP_PATH") + + APP_BIN=$(find "$APP_PATH/Contents/MacOS" -maxdepth 1 -type f | head -n 1) + if [ -z "$APP_BIN" ]; then + echo "❌ 未找到 macOS 应用主程序,无法进行 UPX 压缩!" + exit 1 + fi + BEFORE_BYTES=$(wc -c <"$APP_BIN" | tr -d '[:space:]') + echo "🗜️ 正在使用 UPX 压缩 macOS 可执行文件: $APP_BIN ..." + upx --best --lzma --force "$APP_BIN" + upx -t "$APP_BIN" + AFTER_BYTES=$(wc -c <"$APP_BIN" | tr -d '[:space:]') + if [ "$AFTER_BYTES" -lt "$BEFORE_BYTES" ]; then + SAVED_BYTES=$((BEFORE_BYTES - AFTER_BYTES)) + awk -v b="$BEFORE_BYTES" -v a="$AFTER_BYTES" -v s="$SAVED_BYTES" 'BEGIN { printf "✅ macOS UPX 压缩完成:%.2fMB -> %.2fMB,减少 %.2fMB\n", b/1024/1024, a/1024/1024, s/1024/1024 }' + else + awk -v b="$BEFORE_BYTES" -v a="$AFTER_BYTES" 'BEGIN { printf "ℹ️ macOS UPX 压缩完成:%.2fMB -> %.2fMB\n", b/1024/1024, a/1024/1024 }' + fi echo "🔏 正在进行 Ad-hoc 签名..." # 注意:Ad-hoc + hardened runtime(--options runtime)在未配置 entitlements 时, @@ -301,7 +339,7 @@ jobs: mv "$DMG_NAME" "../../$FINAL_NAME" # Windows Packaging - - name: Package Windows Portable Zip + - name: Package Windows EXE if: contains(matrix.platform, 'windows') shell: pwsh run: | @@ -312,7 +350,6 @@ jobs: } $target = "${{ matrix.build_name }}" $finalExeName = "GoNavi-$version-${{ matrix.os_name }}-${{ matrix.arch_name }}${{ matrix.artifact_suffix }}.exe" - $finalZipName = "GoNavi-$version-${{ matrix.os_name }}-${{ matrix.arch_name }}${{ matrix.artifact_suffix }}.zip" if (Test-Path "$target.exe") { $finalExe = "$target.exe" @@ -324,11 +361,25 @@ jobs: exit 1 } - Write-Host "📦 生成 Windows 可执行文件 $finalExeName..." - Copy-Item -LiteralPath $finalExe -Destination "..\\..\\$finalExeName" -Force + $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)) + } else { + Write-Host ("ℹ️ UPX 压缩完成:{0:N2}MB -> {1:N2}MB" -f ($beforeBytes / 1MB), ($afterBytes / 1MB)) + } - Write-Host "📦 生成 Windows 压缩包 $finalZipName..." - Compress-Archive -LiteralPath $finalExe -DestinationPath "..\\..\\$finalZipName" -Force + Write-Host "📦 输出 Windows 可执行文件 $finalExeName..." + Copy-Item -LiteralPath $finalExe -Destination "..\\..\\$finalExeName" -Force # Linux Packaging (tar.gz and AppImage) - name: Package Linux @@ -347,6 +398,17 @@ jobs: fi chmod +x "$TARGET" + BEFORE_BYTES=$(wc -c <"$TARGET" | tr -d '[:space:]') + echo "🗜️ 正在使用 UPX 压缩 Linux 可执行文件: $TARGET ..." + upx --best --lzma --force "$TARGET" + upx -t "$TARGET" + AFTER_BYTES=$(wc -c <"$TARGET" | tr -d '[:space:]') + if [ "$AFTER_BYTES" -lt "$BEFORE_BYTES" ]; then + SAVED_BYTES=$((BEFORE_BYTES - AFTER_BYTES)) + awk -v b="$BEFORE_BYTES" -v a="$AFTER_BYTES" -v s="$SAVED_BYTES" 'BEGIN { printf "✅ Linux UPX 压缩完成:%.2fMB -> %.2fMB,减少 %.2fMB\n", b/1024/1024, a/1024/1024, s/1024/1024 }' + else + awk -v b="$BEFORE_BYTES" -v a="$AFTER_BYTES" 'BEGIN { printf "ℹ️ Linux UPX 压缩完成:%.2fMB -> %.2fMB\n", b/1024/1024, a/1024/1024 }' + fi # 1. Create tar.gz echo "📦 正在打包 $TAR_NAME..." @@ -419,7 +481,6 @@ jobs: path: | GoNavi-*.dmg GoNavi-*.exe - GoNavi-*.zip GoNavi-*.tar.gz GoNavi-*.AppImage drivers/** diff --git a/.github/workflows/test-build-all-platforms.yml b/.github/workflows/test-build-all-platforms.yml index 29ffe9d..6646ece 100644 --- a/.github/workflows/test-build-all-platforms.yml +++ b/.github/workflows/test-build-all-platforms.yml @@ -93,6 +93,24 @@ jobs: with: node-version: '20' + - name: Install UPX (macOS) + if: contains(matrix.platform, 'darwin') + run: | + brew install upx + upx --version + + - name: Install UPX (Windows) + if: contains(matrix.platform, 'windows') + shell: pwsh + run: | + choco install upx --no-progress -y + $upxCmd = Get-Command upx -ErrorAction SilentlyContinue + if ($null -eq $upxCmd) { + Write-Error "❌ 未检测到 upx,无法保证 Windows 测试产物经过压缩" + exit 1 + } + & upx --version + - name: Install Linux Dependencies if: contains(matrix.platform, 'linux') run: | @@ -105,6 +123,9 @@ jobs: sudo apt-get install -y libwebkit2gtk-4.0-dev fi + sudo apt-get install -y upx-ucl || sudo apt-get install -y upx + upx --version + sudo apt-get install -y libfuse2 || sudo apt-get install -y libfuse2t64 || true LINUXDEPLOY_URL="https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage" @@ -242,6 +263,22 @@ jobs: exit 1 fi APP_NAME=$(basename "$APP_PATH") + APP_BIN=$(find "$APP_PATH/Contents/MacOS" -maxdepth 1 -type f | head -n 1) + if [ -z "$APP_BIN" ]; then + echo "未找到 macOS 应用主程序,无法进行 UPX 压缩" + exit 1 + fi + BEFORE_BYTES=$(wc -c <"$APP_BIN" | tr -d '[:space:]') + echo "🗜️ 使用 UPX 压缩 macOS 可执行文件: $APP_BIN ..." + upx --best --lzma --force "$APP_BIN" + upx -t "$APP_BIN" + AFTER_BYTES=$(wc -c <"$APP_BIN" | tr -d '[:space:]') + if [ "$AFTER_BYTES" -lt "$BEFORE_BYTES" ]; then + SAVED_BYTES=$((BEFORE_BYTES - AFTER_BYTES)) + awk -v b="$BEFORE_BYTES" -v a="$AFTER_BYTES" -v s="$SAVED_BYTES" 'BEGIN { printf "✅ macOS UPX 压缩完成:%.2fMB -> %.2fMB,减少 %.2fMB\n", b/1024/1024, a/1024/1024, s/1024/1024 }' + else + awk -v b="$BEFORE_BYTES" -v a="$AFTER_BYTES" 'BEGIN { printf "ℹ️ macOS UPX 压缩完成:%.2fMB -> %.2fMB\n", b/1024/1024, a/1024/1024 }' + fi codesign --force --deep --sign - "$APP_NAME" ZIP_NAME="GoNavi-${LABEL}-${{ matrix.os_name }}-${{ matrix.arch_name }}-run${GITHUB_RUN_NUMBER}.zip" DMG_NAME="GoNavi-${LABEL}-${{ matrix.os_name }}-${{ matrix.arch_name }}-run${GITHUB_RUN_NUMBER}.dmg" @@ -270,7 +307,6 @@ jobs: Set-Location build/bin $target = "${{ matrix.build_name }}" $finalExeName = "GoNavi-$label-${{ matrix.os_name }}-${{ matrix.arch_name }}-run$env:GITHUB_RUN_NUMBER.exe" - $finalZipName = "GoNavi-$label-${{ matrix.os_name }}-${{ matrix.arch_name }}-run$env:GITHUB_RUN_NUMBER.zip" if (Test-Path "$target.exe") { $finalExe = "$target.exe" } elseif (Test-Path "$target") { @@ -280,11 +316,25 @@ 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)) + } 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 - Compress-Archive -LiteralPath $finalExe -DestinationPath "..\..\artifacts\$finalZipName" -Force Get-FileHash "..\..\artifacts\$finalExeName" -Algorithm SHA256 | ForEach-Object { "{0} *{1}" -f $_.Hash.ToLower(), (Split-Path $_.Path -Leaf) } | Out-File "..\..\artifacts\$finalExeName.sha256" -Encoding ascii - Get-FileHash "..\..\artifacts\$finalZipName" -Algorithm SHA256 | ForEach-Object { "{0} *{1}" -f $_.Hash.ToLower(), (Split-Path $_.Path -Leaf) } | Out-File "..\..\artifacts\$finalZipName.sha256" -Encoding ascii - name: Package Linux if: contains(matrix.platform, 'linux') @@ -306,6 +356,17 @@ jobs: exit 1 fi chmod +x "$TARGET" + BEFORE_BYTES=$(wc -c <"$TARGET" | tr -d '[:space:]') + echo "🗜️ 使用 UPX 压缩 Linux 可执行文件: $TARGET ..." + upx --best --lzma --force "$TARGET" + upx -t "$TARGET" + AFTER_BYTES=$(wc -c <"$TARGET" | tr -d '[:space:]') + if [ "$AFTER_BYTES" -lt "$BEFORE_BYTES" ]; then + SAVED_BYTES=$((BEFORE_BYTES - AFTER_BYTES)) + awk -v b="$BEFORE_BYTES" -v a="$AFTER_BYTES" -v s="$SAVED_BYTES" 'BEGIN { printf "✅ Linux UPX 压缩完成:%.2fMB -> %.2fMB,减少 %.2fMB\n", b/1024/1024, a/1024/1024, s/1024/1024 }' + else + awk -v b="$BEFORE_BYTES" -v a="$AFTER_BYTES" 'BEGIN { printf "ℹ️ Linux UPX 压缩完成:%.2fMB -> %.2fMB\n", b/1024/1024, a/1024/1024 }' + fi tar -czvf "../../artifacts/$TAR_NAME" "$TARGET" sha256sum "../../artifacts/$TAR_NAME" > "../../artifacts/$TAR_NAME.sha256" diff --git a/build-release.sh b/build-release.sh index a36f835..22fe7c8 100755 --- a/build-release.sh +++ b/build-release.sh @@ -20,6 +20,70 @@ RED='\033[0;31m' YELLOW='\033[1;33m' NC='\033[0m' +get_file_size_bytes() { + local target="$1" + if [ ! -f "$target" ]; then + echo 0 + return + fi + if stat -f%z "$target" >/dev/null 2>&1; then + stat -f%z "$target" + return + fi + if stat -c%s "$target" >/dev/null 2>&1; then + stat -c%s "$target" + return + fi + wc -c <"$target" | tr -d '[:space:]' +} + +format_size_mb() { + local bytes="${1:-0}" + awk -v b="$bytes" 'BEGIN { printf "%.2fMB", b / 1024 / 1024 }' +} + +try_compress_binary_with_upx() { + local exe_path="$1" + local label="$2" + if [ ! -f "$exe_path" ]; then + echo -e "${RED} ❌ 未找到 ${label} 文件:$exe_path${NC}" + exit 1 + fi + + if ! command -v upx >/dev/null 2>&1; then + echo -e "${RED} ❌ 未找到 upx,${label} 必须进行压缩后才能继续打包。${NC}" + case "$(uname -s)" in + Darwin) + echo " 安装命令: brew install upx" + ;; + Linux) + echo " 安装命令: sudo apt-get install -y upx-ucl (或对应发行版包管理器)" + ;; + esac + exit 1 + 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 -t "$exe_path" >/dev/null 2>&1; then + echo -e "${RED} ❌ UPX 校验失败:${label}${NC}" + exit 1 + fi + after_bytes=$(get_file_size_bytes "$exe_path") + if [ "$after_bytes" -lt "$before_bytes" ]; then + local saved_bytes=$((before_bytes - after_bytes)) + echo " ✅ UPX 压缩完成: $(format_size_mb "$before_bytes") -> $(format_size_mb "$after_bytes"),减少 $(format_size_mb "$saved_bytes")" + else + echo " ℹ️ UPX 压缩完成: $(format_size_mb "$before_bytes") -> $(format_size_mb "$after_bytes")" + fi + else + echo -e "${RED} ❌ UPX 压缩失败:${label}${NC}" + exit 1 + fi +} + MAC_VOLICON_PATH="build/darwin/icon.icns" if [ ! -f "$MAC_VOLICON_PATH" ]; then MAC_VOLICON_PATH="" @@ -41,6 +105,14 @@ if [ $? -eq 0 ]; then # 移动 .app 到 dist mv "$APP_SRC" "$DIST_DIR/$APP_DEST_NAME" + + 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 应用主程序" + else + echo -e "${RED} ❌ 未找到 macOS arm64 主程序文件,无法执行 UPX 压缩。${NC}" + exit 1 + fi # Ad-hoc 代码签名(无 Apple Developer 账号时防止 Gatekeeper 报已损坏) echo " 🔏 正在对 .app 进行 ad-hoc 签名 (arm64)..." @@ -140,6 +212,14 @@ if [ $? -eq 0 ]; then DMG_NAME="${APP_NAME}-${VERSION}-mac-amd64.dmg" mv "$APP_SRC" "$DIST_DIR/$APP_DEST_NAME" + + 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 应用主程序" + else + echo -e "${RED} ❌ 未找到 macOS amd64 主程序文件,无法执行 UPX 压缩。${NC}" + exit 1 + fi # Ad-hoc 代码签名 echo " 🔏 正在对 .app 进行 ad-hoc 签名 (amd64)..." @@ -229,7 +309,9 @@ echo -e "${GREEN}🪟 正在构建 Windows (amd64)...${NC}" if command -v x86_64-w64-mingw32-gcc &> /dev/null; then wails build -platform windows/amd64 -clean -ldflags "$LDFLAGS" if [ $? -eq 0 ]; then - mv "$BUILD_BIN_DIR/${DEFAULT_BINARY_NAME}.exe" "$DIST_DIR/${APP_NAME}-${VERSION}-windows-amd64.exe" + TARGET_EXE="$DIST_DIR/${APP_NAME}-${VERSION}-windows-amd64.exe" + mv "$BUILD_BIN_DIR/${DEFAULT_BINARY_NAME}.exe" "$TARGET_EXE" + try_compress_binary_with_upx "$TARGET_EXE" "Windows amd64 可执行文件" echo " ✅ 已生成 ${APP_NAME}-${VERSION}-windows-amd64.exe" else echo -e "${RED} ❌ Windows amd64 构建失败。${NC}" @@ -243,7 +325,9 @@ echo -e "${GREEN}🪟 正在构建 Windows (arm64)...${NC}" if command -v aarch64-w64-mingw32-gcc &> /dev/null; then wails build -platform windows/arm64 -clean -ldflags "$LDFLAGS" if [ $? -eq 0 ]; then - mv "$BUILD_BIN_DIR/${DEFAULT_BINARY_NAME}.exe" "$DIST_DIR/${APP_NAME}-${VERSION}-windows-arm64.exe" + 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 " ✅ 已生成 ${APP_NAME}-${VERSION}-windows-arm64.exe" else echo -e "${RED} ❌ Windows arm64 构建失败。${NC}" @@ -263,8 +347,10 @@ if [ "$CURRENT_OS" = "Linux" ] && [ "$CURRENT_ARCH" = "x86_64" ]; then # 本机 Linux amd64,直接构建 wails build -platform linux/amd64 -clean -ldflags "$LDFLAGS" if [ $? -eq 0 ]; then - mv "$BUILD_BIN_DIR/${DEFAULT_BINARY_NAME}" "$DIST_DIR/${APP_NAME}-${VERSION}-linux-amd64" - chmod +x "$DIST_DIR/${APP_NAME}-${VERSION}-linux-amd64" + TARGET_LINUX_BIN="$DIST_DIR/${APP_NAME}-${VERSION}-linux-amd64" + mv "$BUILD_BIN_DIR/${DEFAULT_BINARY_NAME}" "$TARGET_LINUX_BIN" + chmod +x "$TARGET_LINUX_BIN" + try_compress_binary_with_upx "$TARGET_LINUX_BIN" "Linux amd64 可执行文件" # 打包为 tar.gz cd "$DIST_DIR" tar -czvf "${APP_NAME}-${VERSION}-linux-amd64.tar.gz" "${APP_NAME}-${VERSION}-linux-amd64" @@ -281,8 +367,10 @@ elif command -v x86_64-linux-gnu-gcc &> /dev/null; then export CGO_ENABLED=1 wails build -platform linux/amd64 -clean -ldflags "$LDFLAGS" if [ $? -eq 0 ]; then - mv "$BUILD_BIN_DIR/${DEFAULT_BINARY_NAME}" "$DIST_DIR/${APP_NAME}-${VERSION}-linux-amd64" - chmod +x "$DIST_DIR/${APP_NAME}-${VERSION}-linux-amd64" + TARGET_LINUX_BIN="$DIST_DIR/${APP_NAME}-${VERSION}-linux-amd64" + mv "$BUILD_BIN_DIR/${DEFAULT_BINARY_NAME}" "$TARGET_LINUX_BIN" + chmod +x "$TARGET_LINUX_BIN" + try_compress_binary_with_upx "$TARGET_LINUX_BIN" "Linux amd64 可执行文件" cd "$DIST_DIR" tar -czvf "${APP_NAME}-${VERSION}-linux-amd64.tar.gz" "${APP_NAME}-${VERSION}-linux-amd64" rm "${APP_NAME}-${VERSION}-linux-amd64" @@ -303,8 +391,10 @@ if [ "$CURRENT_OS" = "Linux" ] && [ "$CURRENT_ARCH" = "aarch64" ]; then # 本机 Linux arm64,直接构建 wails build -platform linux/arm64 -clean -ldflags "$LDFLAGS" if [ $? -eq 0 ]; then - mv "$BUILD_BIN_DIR/${DEFAULT_BINARY_NAME}" "$DIST_DIR/${APP_NAME}-${VERSION}-linux-arm64" - chmod +x "$DIST_DIR/${APP_NAME}-${VERSION}-linux-arm64" + TARGET_LINUX_BIN="$DIST_DIR/${APP_NAME}-${VERSION}-linux-arm64" + mv "$BUILD_BIN_DIR/${DEFAULT_BINARY_NAME}" "$TARGET_LINUX_BIN" + chmod +x "$TARGET_LINUX_BIN" + try_compress_binary_with_upx "$TARGET_LINUX_BIN" "Linux arm64 可执行文件" cd "$DIST_DIR" tar -czvf "${APP_NAME}-${VERSION}-linux-arm64.tar.gz" "${APP_NAME}-${VERSION}-linux-arm64" rm "${APP_NAME}-${VERSION}-linux-arm64" @@ -320,8 +410,10 @@ elif command -v aarch64-linux-gnu-gcc &> /dev/null; then export CGO_ENABLED=1 wails build -platform linux/arm64 -clean -ldflags "$LDFLAGS" if [ $? -eq 0 ]; then - mv "$BUILD_BIN_DIR/${DEFAULT_BINARY_NAME}" "$DIST_DIR/${APP_NAME}-${VERSION}-linux-arm64" - chmod +x "$DIST_DIR/${APP_NAME}-${VERSION}-linux-arm64" + TARGET_LINUX_BIN="$DIST_DIR/${APP_NAME}-${VERSION}-linux-arm64" + mv "$BUILD_BIN_DIR/${DEFAULT_BINARY_NAME}" "$TARGET_LINUX_BIN" + chmod +x "$TARGET_LINUX_BIN" + try_compress_binary_with_upx "$TARGET_LINUX_BIN" "Linux arm64 可执行文件" cd "$DIST_DIR" tar -czvf "${APP_NAME}-${VERSION}-linux-arm64.tar.gz" "${APP_NAME}-${VERSION}-linux-arm64" rm "${APP_NAME}-${VERSION}-linux-arm64" diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index 3a31be4..9fc732b 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -792,7 +792,20 @@ const Sidebar: React.FC<{ onEditConnection?: (conn: SavedConnection) => void }> case 'kingbase': case 'highgo': case 'vastbase': - return [{ sql: `SELECT n.nspname AS schema_name, p.proname AS routine_name, CASE WHEN p.prokind = 'p' THEN 'PROCEDURE' ELSE 'FUNCTION' END AS routine_type FROM pg_proc p JOIN pg_namespace n ON p.pronamespace = n.oid WHERE n.nspname NOT IN ('pg_catalog', 'information_schema') AND n.nspname NOT LIKE 'pg_%' ORDER BY n.nspname, routine_type, p.proname` }]; + return normalizeMetadataQuerySpecs([ + { + // PostgreSQL 11+ / 部分 PG-like:通过 prokind 区分 FUNCTION/PROCEDURE + sql: `SELECT n.nspname AS schema_name, p.proname AS routine_name, CASE WHEN p.prokind = 'p' THEN 'PROCEDURE' ELSE 'FUNCTION' END AS routine_type FROM pg_proc p JOIN pg_namespace n ON p.pronamespace = n.oid WHERE n.nspname NOT IN ('pg_catalog', 'information_schema') AND n.nspname NOT LIKE 'pg_%' ORDER BY n.nspname, routine_type, p.proname`, + }, + { + // PostgreSQL 10 / 不支持 prokind 的兼容路径 + sql: `SELECT r.routine_schema AS schema_name, r.routine_name AS routine_name, COALESCE(NULLIF(UPPER(r.routine_type), ''), 'FUNCTION') AS routine_type FROM information_schema.routines r WHERE r.routine_schema NOT IN ('pg_catalog', 'information_schema') AND r.routine_schema NOT LIKE 'pg_%' ORDER BY r.routine_schema, routine_type, r.routine_name`, + }, + { + // 最后兜底:仅函数列表,确保 prokind/routines 视图异常时仍可展示 + sql: `SELECT n.nspname AS schema_name, p.proname AS routine_name, 'FUNCTION' AS routine_type FROM pg_proc p JOIN pg_namespace n ON p.pronamespace = n.oid WHERE n.nspname NOT IN ('pg_catalog', 'information_schema') AND n.nspname NOT LIKE 'pg_%' ORDER BY n.nspname, p.proname`, + }, + ]); case 'sqlserver': { const safeDb = quoteSqlServerIdentifier(dbName || 'master'); return [{ sql: `SELECT s.name AS schema_name, o.name AS routine_name, CASE o.type WHEN 'P' THEN 'PROCEDURE' WHEN 'FN' THEN 'FUNCTION' WHEN 'IF' THEN 'FUNCTION' WHEN 'TF' THEN 'FUNCTION' END AS routine_type FROM ${safeDb}.sys.objects o JOIN ${safeDb}.sys.schemas s ON o.schema_id = s.schema_id WHERE o.type IN ('P','FN','IF','TF') ORDER BY o.type, s.name, o.name` }];