fix: Update references from Gitea to GitHub for versioning and self-update
Some checks failed
Build Multi-Platform Binaries / build-android-apk (push) Failing after 6s
Build Multi-Platform Binaries / build-frontend (push) Successful in 33s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 1m37s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 1m46s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 1m28s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 2m0s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 1m21s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 1m52s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Successful in 2m2s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 2m18s
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Successful in 1m21s
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Successful in 1m58s
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Successful in 1m33s

This commit is contained in:
2026-03-22 22:37:27 +08:00
parent cdc1dd60d1
commit 0a932211f1
3 changed files with 70 additions and 70 deletions

View File

@@ -59,7 +59,7 @@ pkg/
├── relay/ # Bidirectional data relay (32KB buffers) ├── relay/ # Bidirectional data relay (32KB buffers)
├── auth/ # JWT authentication ├── auth/ # JWT authentication
├── utils/ # Port availability checking ├── utils/ # Port availability checking
├── version/ # Version info and update checking (Gitea API) ├── version/ # Version info and update checking (GitHub Releases API)
└── update/ # Shared update logic (download, extract tar.gz/zip) └── update/ # Shared update logic (download, extract tar.gz/zip)
web/ # Vue 3 + TypeScript frontend (Vite + naive-ui) web/ # Vue 3 + TypeScript frontend (Vite + naive-ui)
scripts/ # Build scripts (build.sh, build.ps1) scripts/ # Build scripts (build.sh, build.ps1)
@@ -106,7 +106,7 @@ The server provides Swagger-documented REST APIs at `/api/`.
## Update System ## Update System
Both server and client support self-update from Gitea releases. Both server and client support self-update from GitHub releases.
- Release assets are compressed archives (`.tar.gz` for Linux/Mac, `.zip` for Windows) - Release assets are compressed archives (`.tar.gz` for Linux/Mac, `.zip` for Windows)
- The `pkg/update/` package handles download, extraction, and binary replacement - The `pkg/update/` package handles download, extraction, and binary replacement

View File

@@ -59,7 +59,7 @@ pkg/
├── relay/ # Bidirectional data relay (32KB buffers) ├── relay/ # Bidirectional data relay (32KB buffers)
├── auth/ # JWT authentication ├── auth/ # JWT authentication
├── utils/ # Port availability checking ├── utils/ # Port availability checking
├── version/ # Version info and update checking (Gitea API) ├── version/ # Version info and update checking (GitHub Releases API)
└── update/ # Shared update logic (download, extract tar.gz/zip) └── update/ # Shared update logic (download, extract tar.gz/zip)
web/ # Vue 3 + TypeScript frontend (Vite + naive-ui) web/ # Vue 3 + TypeScript frontend (Vite + naive-ui)
scripts/ # Build scripts (build.sh, build.ps1) scripts/ # Build scripts (build.sh, build.ps1)
@@ -106,7 +106,7 @@ The server provides Swagger-documented REST APIs at `/api/`.
## Update System ## Update System
Both server and client support self-update from Gitea releases. Both server and client support self-update from GitHub releases.
- Release assets are compressed archives (`.tar.gz` for Linux/Mac, `.zip` for Windows) - Release assets are compressed archives (`.tar.gz` for Linux/Mac, `.zip` for Windows)
- The `pkg/update/` package handles download, extraction, and binary replacement - The `pkg/update/` package handles download, extraction, and binary replacement

View File

@@ -11,37 +11,19 @@ import (
"time" "time"
) )
// 版本信息
var Version = "1.0.0" var Version = "1.0.0"
var GitCommit = "" var GitCommit = ""
var BuildTime = "" var BuildTime = ""
// SetVersion 设置版本号(由 main 包在初始化时调用)
func SetVersion(v string) {
if v != "" {
Version = v
}
}
// SetBuildInfo 设置构建信息(由 main 包在初始化时调用)
func SetBuildInfo(gitCommit, buildTime string) {
if gitCommit != "" {
GitCommit = gitCommit
}
if buildTime != "" {
BuildTime = buildTime
}
}
// 仓库信息
const ( const (
RepoURL = "https://git.92coco.cn/flik/GoTunnel" RepoURL = "https://github.com/Flikify/Gotunnel"
APIBaseURL = "https://git.92coco.cn/api/v1" APIBaseURL = "https://api.github.com"
RepoOwner = "flik" RepoOwner = "Flikify"
RepoName = "GoTunnel" RepoName = "Gotunnel"
GitHubAPIVersion = "2022-11-28"
GitHubUserAgent = "GoTunnel-Updater"
) )
// Info 版本详细信息
type Info struct { type Info struct {
Version string `json:"version"` Version string `json:"version"`
GitCommit string `json:"git_commit"` GitCommit string `json:"git_commit"`
@@ -51,7 +33,43 @@ type Info struct {
Arch string `json:"arch"` Arch string `json:"arch"`
} }
// GetInfo 获取版本信息 type ReleaseInfo struct {
TagName string `json:"tag_name"`
Name string `json:"name"`
Body string `json:"body"`
PublishedAt string `json:"published_at"`
Assets []ReleaseAsset `json:"assets"`
}
type ReleaseAsset struct {
Name string `json:"name"`
Size int64 `json:"size"`
BrowserDownloadURL string `json:"browser_download_url"`
}
type UpdateInfo struct {
Latest string `json:"latest"`
ReleaseNote string `json:"release_note"`
DownloadURL string `json:"download_url"`
AssetName string `json:"asset_name"`
AssetSize int64 `json:"asset_size"`
}
func SetVersion(v string) {
if v != "" {
Version = v
}
}
func SetBuildInfo(gitCommit, buildTime string) {
if gitCommit != "" {
GitCommit = gitCommit
}
if buildTime != "" {
BuildTime = buildTime
}
}
func GetInfo() Info { func GetInfo() Info {
return Info{ return Info{
Version: Version, Version: Version,
@@ -63,39 +81,27 @@ func GetInfo() Info {
} }
} }
// ReleaseInfo Release 信息 func newGitHubRequest(url string) (*http.Request, error) {
type ReleaseInfo struct { req, err := http.NewRequest(http.MethodGet, url, nil)
TagName string `json:"tag_name"` if err != nil {
Name string `json:"name"` return nil, err
Body string `json:"body"` }
PublishedAt string `json:"published_at"` req.Header.Set("Accept", "application/vnd.github+json")
Assets []ReleaseAsset `json:"assets"` req.Header.Set("X-GitHub-Api-Version", GitHubAPIVersion)
req.Header.Set("User-Agent", GitHubUserAgent)
return req, nil
} }
// ReleaseAsset Release 资产
type ReleaseAsset struct {
Name string `json:"name"`
Size int64 `json:"size"`
BrowserDownloadURL string `json:"browser_download_url"`
}
// UpdateInfo 更新信息
type UpdateInfo struct {
Latest string `json:"latest"`
ReleaseNote string `json:"release_note"`
DownloadURL string `json:"download_url"`
AssetName string `json:"asset_name"`
AssetSize int64 `json:"asset_size"`
}
// GetLatestRelease 获取最新 Release
// Gitea 兼容:先尝试 /releases/latest失败则尝试 /releases 取第一个
func GetLatestRelease() (*ReleaseInfo, error) { func GetLatestRelease() (*ReleaseInfo, error) {
client := &http.Client{Timeout: 30 * time.Second} client := &http.Client{Timeout: 30 * time.Second}
// 首先尝试 /releases/latest 端点GitHub 兼容)
latestURL := fmt.Sprintf("%s/repos/%s/%s/releases/latest", APIBaseURL, RepoOwner, RepoName) latestURL := fmt.Sprintf("%s/repos/%s/%s/releases/latest", APIBaseURL, RepoOwner, RepoName)
resp, err := client.Get(latestURL) req, err := newGitHubRequest(latestURL)
if err != nil {
return nil, fmt.Errorf("build request: %w", err)
}
resp, err := client.Do(req)
if err != nil { if err != nil {
return nil, fmt.Errorf("request failed: %w", err) return nil, fmt.Errorf("request failed: %w", err)
} }
@@ -109,10 +115,15 @@ func GetLatestRelease() (*ReleaseInfo, error) {
return &release, nil return &release, nil
} }
// 如果 /releases/latest 不可用,尝试 /releases 并取第一个
resp.Body.Close() resp.Body.Close()
listURL := fmt.Sprintf("%s/repos/%s/%s/releases?limit=1", APIBaseURL, RepoOwner, RepoName)
resp, err = client.Get(listURL) listURL := fmt.Sprintf("%s/repos/%s/%s/releases?per_page=1", APIBaseURL, RepoOwner, RepoName)
req, err = newGitHubRequest(listURL)
if err != nil {
return nil, fmt.Errorf("build request: %w", err)
}
resp, err = client.Do(req)
if err != nil { if err != nil {
return nil, fmt.Errorf("request failed: %w", err) return nil, fmt.Errorf("request failed: %w", err)
} }
@@ -135,14 +146,12 @@ func GetLatestRelease() (*ReleaseInfo, error) {
return &releases[0], nil return &releases[0], nil
} }
// CheckUpdate 检查更新(返回最新版本信息)
func CheckUpdate(component string) (*UpdateInfo, error) { func CheckUpdate(component string) (*UpdateInfo, error) {
release, err := GetLatestRelease() release, err := GetLatestRelease()
if err != nil { if err != nil {
return nil, fmt.Errorf("get latest release: %w", err) return nil, fmt.Errorf("get latest release: %w", err)
} }
// 查找对应平台的资产
var downloadURL string var downloadURL string
var assetName string var assetName string
var assetSize int64 var assetSize int64
@@ -162,14 +171,12 @@ func CheckUpdate(component string) (*UpdateInfo, error) {
}, nil }, nil
} }
// CheckUpdateForPlatform 检查指定平台的更新
func CheckUpdateForPlatform(component, osName, arch string) (*UpdateInfo, error) { func CheckUpdateForPlatform(component, osName, arch string) (*UpdateInfo, error) {
release, err := GetLatestRelease() release, err := GetLatestRelease()
if err != nil { if err != nil {
return nil, fmt.Errorf("get latest release: %w", err) return nil, fmt.Errorf("get latest release: %w", err)
} }
// 查找对应平台的资产
var downloadURL string var downloadURL string
var assetName string var assetName string
var assetSize int64 var assetSize int64
@@ -189,17 +196,12 @@ func CheckUpdateForPlatform(component, osName, arch string) (*UpdateInfo, error)
}, nil }, nil
} }
// findAssetForPlatform 在 Release 资产中查找匹配的文件
func findAssetForPlatform(assets []ReleaseAsset, component, osName, arch string) *ReleaseAsset { func findAssetForPlatform(assets []ReleaseAsset, component, osName, arch string) *ReleaseAsset {
// 构建匹配模式
// CI 格式: gotunnel-server-v1.0.0-linux-amd64.tar.gz
// 或者: gotunnel-client-v1.0.0-windows-amd64.zip
prefix := fmt.Sprintf("gotunnel-%s-", component) prefix := fmt.Sprintf("gotunnel-%s-", component)
suffix := fmt.Sprintf("-%s-%s", osName, arch) suffix := fmt.Sprintf("-%s-%s", osName, arch)
for i := range assets { for i := range assets {
name := assets[i].Name name := assets[i].Name
// 检查是否匹配 gotunnel-{component}-{version}-{os}-{arch}.{ext}
if strings.HasPrefix(name, prefix) && strings.Contains(name, suffix) { if strings.HasPrefix(name, prefix) && strings.Contains(name, suffix) {
return &assets[i] return &assets[i]
} }
@@ -207,8 +209,6 @@ func findAssetForPlatform(assets []ReleaseAsset, component, osName, arch string)
return nil return nil
} }
// CompareVersions 比较版本号
// 返回: -1 (v1 < v2), 0 (v1 == v2), 1 (v1 > v2)
func CompareVersions(v1, v2 string) int { func CompareVersions(v1, v2 string) int {
parts1 := parseVersionParts(v1) parts1 := parseVersionParts(v1)
parts2 := parseVersionParts(v2) parts2 := parseVersionParts(v2)