🔧 fix(ci-release-duckdb): 修复 DuckDB 导致的多平台打包失败并统一发布命名与更新匹配

- DuckDB 驱动迁移至官方 duckdb-go/v2 并按平台条件编译
- 修复 Windows/arm64 与 macOS/arm64 的构建失败链路
- 修复 macOS 10.13 下窗口材质可用性告警导致的打包问题
- 统一发布包命名规则(去掉版本前缀 v,架构统一 Amd64/Arm64)
- Windows 同时产出 exe/zip,在线更新优先匹配 exe 并保留 zip 兼容
This commit is contained in:
Syngnat
2026-02-12 10:37:00 +08:00
parent 31f2a47d26
commit 8df9ea717c
9 changed files with 213 additions and 97 deletions

View File

@@ -324,7 +324,11 @@ func fetchLatestUpdateInfo() (UpdateInfo, error) {
return UpdateInfo{}, errors.New("无法解析最新版本号")
}
assetName, err := expectedAssetName(stdRuntime.GOOS, stdRuntime.GOARCH)
assetVersion := strings.TrimSpace(release.TagName)
if assetVersion == "" {
assetVersion = latestVersion
}
assetName, err := expectedAssetName(stdRuntime.GOOS, stdRuntime.GOARCH, assetVersion)
if err != nil {
return UpdateInfo{}, err
}
@@ -394,25 +398,32 @@ func fetchLatestRelease() (*githubRelease, error) {
return &release, nil
}
func expectedAssetName(goos, goarch string) (string, error) {
func expectedAssetName(goos, goarch, version string) (string, error) {
version = strings.TrimSpace(version)
version = strings.TrimPrefix(version, "v")
version = strings.TrimPrefix(version, "V")
if version == "" {
return "", errors.New("无法解析发布版本号")
}
switch goos {
case "windows":
if goarch == "amd64" {
return "GoNavi-windows-amd64.exe", nil
return fmt.Sprintf("GoNavi-%s-Windows-Amd64.exe", version), nil
}
if goarch == "arm64" {
return "GoNavi-windows-arm64.exe", nil
return fmt.Sprintf("GoNavi-%s-Windows-Arm64.exe", version), nil
}
case "darwin":
if goarch == "amd64" {
return "GoNavi-mac-amd64.dmg", nil
return fmt.Sprintf("GoNavi-%s-MacOS-Amd64.dmg", version), nil
}
if goarch == "arm64" {
return "GoNavi-mac-arm64.dmg", nil
return fmt.Sprintf("GoNavi-%s-MacOS-Arm64.dmg", version), nil
}
case "linux":
if goarch == "amd64" {
return "GoNavi-linux-amd64.tar.gz", nil
return fmt.Sprintf("GoNavi-%s-Linux-Amd64.tar.gz", version), nil
}
}
return "", fmt.Errorf("当前平台暂不支持在线更新:%s/%s", goos, goarch)
@@ -860,6 +871,38 @@ if not exist "%%SOURCE%%" (
exit /b 1
)
for %%I in ("%%TARGET%%") do set "TARGET_NAME=%%~nxI"
for %%I in ("%%SOURCE%%") do set "SOURCE_EXT=%%~xI"
set "SOURCE_EXE="
if /I "%%SOURCE_EXT%%"==".zip" (
set "EXTRACT_DIR=%%STAGED%%\_extract"
if exist "%%EXTRACT_DIR%%" (
rmdir /S /Q "%%EXTRACT_DIR%%" >> "%%LOG_FILE%%" 2>&1
)
mkdir "%%EXTRACT_DIR%%" >> "%%LOG_FILE%%" 2>&1
powershell -NoProfile -ExecutionPolicy Bypass -Command "$src=$env:SOURCE; $dst=$env:EXTRACT_DIR; Expand-Archive -LiteralPath $src -DestinationPath $dst -Force" >> "%%LOG_FILE%%" 2>&1
if %%ERRORLEVEL%% NEQ 0 (
call :log expand zip failed: %%SOURCE%%
exit /b 1
)
if exist "%%EXTRACT_DIR%%\%%TARGET_NAME%%" (
set "SOURCE_EXE=%%EXTRACT_DIR%%\%%TARGET_NAME%%"
) else (
for /R "%%EXTRACT_DIR%%" %%F in (*.exe) do (
if not defined SOURCE_EXE (
set "SOURCE_EXE=%%~fF"
)
)
)
if not defined SOURCE_EXE (
call :log no executable found in portable zip: %%SOURCE%%
exit /b 1
)
) else (
set "SOURCE_EXE=%%SOURCE%%"
)
:waitloop
tasklist /FI "PID eq %%PID%%" | find "%%PID%%" >nul
if %%ERRORLEVEL%%==0 (
@@ -870,10 +913,10 @@ call :log host process exited
set /a RETRY=0
:move_retry
move /Y "%%SOURCE%%" "%%TARGET%%" >> "%%LOG_FILE%%" 2>&1
move /Y "%%SOURCE_EXE%%" "%%TARGET%%" >> "%%LOG_FILE%%" 2>&1
if %%ERRORLEVEL%%==0 goto move_done
copy /Y "%%SOURCE%%" "%%TARGET%%" >> "%%LOG_FILE%%" 2>&1
copy /Y "%%SOURCE_EXE%%" "%%TARGET%%" >> "%%LOG_FILE%%" 2>&1
if %%ERRORLEVEL%%==0 goto move_done
set /a RETRY+=1

View File

@@ -44,7 +44,9 @@ static void gonaviTuneWindowTranslucency(NSWindow *window) {
[effectView release];
}
[effectView setMaterial:NSVisualEffectMaterialHUDWindow];
if (@available(macOS 10.14, *)) {
[effectView setMaterial:NSVisualEffectMaterialHUDWindow];
}
[effectView setBlendingMode:NSVisualEffectBlendingModeBehindWindow];
[effectView setState:NSVisualEffectStateActive];
// 默认 alpha=0不可见由前端根据用户外观设置动态启用

View File

@@ -0,0 +1,5 @@
//go:build cgo && (duckdb_use_lib || duckdb_use_static_lib || (darwin && (amd64 || arm64)) || (linux && (amd64 || arm64)) || (windows && amd64))
package db
import _ "github.com/duckdb/duckdb-go/v2"

View File

@@ -9,8 +9,6 @@ import (
"GoNavi-Wails/internal/connection"
"GoNavi-Wails/internal/utils"
_ "github.com/marcboeker/go-duckdb"
)
type DuckDB struct {
@@ -19,6 +17,10 @@ type DuckDB struct {
}
func (d *DuckDB) Connect(config connection.ConnectionConfig) error {
if supported, reason := duckDBBuildSupportStatus(); !supported {
return fmt.Errorf("DuckDB 驱动不可用:%s", reason)
}
dsn := strings.TrimSpace(config.Host)
if dsn == "" {
dsn = strings.TrimSpace(config.Database)
@@ -35,6 +37,8 @@ func (d *DuckDB) Connect(config connection.ConnectionConfig) error {
d.pingTimeout = getConnectTimeout(config)
if err := d.Ping(); err != nil {
_ = db.Close()
d.conn = nil
return fmt.Errorf("连接建立后验证失败:%w", err)
}
return nil

View File

@@ -0,0 +1,7 @@
//go:build cgo && (duckdb_use_lib || duckdb_use_static_lib || (darwin && (amd64 || arm64)) || (linux && (amd64 || arm64)) || (windows && amd64))
package db
func duckDBBuildSupportStatus() (bool, string) {
return true, ""
}

View File

@@ -0,0 +1,12 @@
//go:build !(cgo && (duckdb_use_lib || duckdb_use_static_lib || (darwin && (amd64 || arm64)) || (linux && (amd64 || arm64)) || (windows && amd64)))
package db
import (
"fmt"
"runtime"
)
func duckDBBuildSupportStatus() (bool, string) {
return false, fmt.Sprintf("当前构建不包含 DuckDB 驱动(平台=%s/%s。需要启用 CGO并使用受支持平台darwin/linux amd64|arm64、windows/amd64或通过 -tags duckdb_use_lib / duckdb_use_static_lib 提供自定义库", runtime.GOOS, runtime.GOARCH)
}