2.4-接入全新部署逻辑设计,内容较多,后续会在日志内单开一个md文件说明

This commit is contained in:
2026-07-29 20:23:25 +08:00
parent 948aef0fe4
commit 94bd61daa1
4 changed files with 421 additions and 222 deletions
+119 -10
View File
@@ -9,6 +9,7 @@ import (
"os/exec"
"path/filepath"
"strings"
"time"
)
type Platform struct {
@@ -22,15 +23,99 @@ var platforms = []Platform{
{"windows", "amd64", "Windows x86-64", ".exe"},
{"linux", "amd64", "Linux x86-64", ""},
{"linux", "arm64", "Linux ARM64", ""},
{"linux", "arm", "Linux ARMv7l", ""}, // GOARCH=arm, GOARM=7
{"linux", "arm", "Linux ARMv7l", ""},
}
const (
Version = "2.0.0"
BuildTime = "2026-07-26"
BuildTime = "2026-07-29"
Binary = "frpc-console"
)
// ============================================================
// 版本管理核心
// ============================================================
// readVersion 读取仓库根目录的 VERSION.ini 文件
// Preview 格式: "2.4"
// LTS 格式: "2.5 20260729"
func readVersion() (semver string, ltsDate string) {
data, err := os.ReadFile("./VERSION.ini")
if err != nil {
return "0.0.0", ""
}
// 去掉注释行(以 ; 或 # 开头)
lines := strings.Split(string(data), "\n")
var content string
for _, line := range lines {
line = strings.TrimSpace(line)
if line == "" || strings.HasPrefix(line, ";") || strings.HasPrefix(line, "#") {
continue
}
content = line
break
}
parts := strings.Fields(content)
if len(parts) < 1 {
return "0.0.0", ""
}
semver = parts[0]
if len(parts) > 1 {
ltsDate = parts[1]
}
return semver, ltsDate
}
// getVersionType 判断版本类型
// 规则: X.0 或 X.5 → LTS,其他 → Preview
func getVersionType(semver string) string {
parts := strings.Split(semver, ".")
if len(parts) < 2 {
return "preview"
}
minor := parts[1]
if minor == "0" || minor == "5" {
return "lts"
}
return "preview"
}
// getFullVersion 生成完整版本字符串
// LTS (X.0/X.5): {semver}-lts-{ltsDate} (必须有日期)
// Preview (其他): {semver}-preview-{buildTimestamp}
func getFullVersion() string {
semver, ltsDate := readVersion()
vType := getVersionType(semver)
switch vType {
case "lts":
if ltsDate == "" {
ltsDate = time.Now().Format("20060102")
}
return semver + "-lts-" + ltsDate
default:
timestamp := time.Now().Format("20060102-150405")
return semver + "-preview-" + timestamp
}
}
// getImageTag 生成镜像标签
// LTS: {semver}-lts-{ltsDate}
// Preview: preview-{buildTimestamp}
func getImageTag() string {
semver, ltsDate := readVersion()
vType := getVersionType(semver)
switch vType {
case "lts":
if ltsDate == "" {
ltsDate = time.Now().Format("20060102")
}
return semver + "-lts-" + ltsDate
default:
return "preview-" + time.Now().Format("20060102-150405")
}
}
func main() {
if len(os.Args) > 1 {
target := os.Args[1]
@@ -44,6 +129,12 @@ func main() {
case "list":
listPlatforms()
return
case "version":
fmt.Println(getFullVersion())
return
case "image-tag":
fmt.Println(getImageTag())
return
}
for _, p := range platforms {
if target == p.OS+"/"+p.Arch {
@@ -52,13 +143,17 @@ func main() {
}
}
fmt.Println("❌ 不支持的平台:", target)
fmt.Println(" 可用: windows/amd64, linux/amd64, linux/arm64, linux/armv7")
fmt.Println(" 或: all, list, clean")
fmt.Println(" 可用: windows/amd64, linux/amd64, linux/arm64, linux/arm")
fmt.Println(" 或: all, list, clean, version, image-tag")
return
}
interactiveMenu()
}
// ============================================================
// 构建函数
// ============================================================
func listPlatforms() {
fmt.Println("可用平台:")
for i, p := range platforms {
@@ -68,15 +163,19 @@ func listPlatforms() {
func interactiveMenu() {
fmt.Println("========================================")
fmt.Println(" frpc-console 多平台构建工具 v" + Version)
fmt.Println(" frpc-console 多平台构建工具")
fmt.Println("========================================")
fmt.Println()
fmt.Println(" 当前版本:", getFullVersion())
fmt.Println(" 镜像标签:", getImageTag())
fmt.Println()
for i, p := range platforms {
fmt.Printf(" %d. %s (%s/%s)\n", i+1, p.Name, p.OS, p.Arch)
}
fmt.Println(" a. 全部构建")
fmt.Println(" c. 清理构建产物")
fmt.Println(" v. 显示版本信息")
fmt.Println(" q. 退出")
fmt.Println()
@@ -96,6 +195,10 @@ func interactiveMenu() {
case "a":
buildAll()
return
case "v":
fmt.Println("版本:", getFullVersion())
fmt.Println("镜像标签:", getImageTag())
return
default:
var idx int
if n, err := fmt.Sscanf(input, "%d", &idx); n == 1 && err == nil && idx >= 1 && idx <= len(platforms) {
@@ -125,16 +228,22 @@ func build(p Platform, silent bool) {
return
}
// 构建输出文件名
fullVersion := getFullVersion()
imageTag := getImageTag()
outName := Binary + "-" + p.OS + "-" + p.Arch
if p.Arch == "arm" {
outName += "v7" // 标注 ARMv7 版本
outName += "v7"
}
outName += p.Ext
outPath := filepath.Join(outDir, outName)
cmd := exec.Command("go", "build",
"-ldflags=-s -w -X main.version="+Version,
"-ldflags="+
"-s -w "+
"-X main.buildVersion="+fullVersion+" "+
"-X main.buildImageTag="+imageTag+" "+
"-X main.buildTime="+BuildTime,
"-o", outPath,
".",
)
@@ -144,7 +253,6 @@ func build(p Platform, silent bool) {
"CGO_ENABLED=0",
)
// ARM 架构指定 GOARM=7
if p.Arch == "arm" {
cmd.Env = append(cmd.Env, "GOARM=7")
}
@@ -159,6 +267,7 @@ func build(p Platform, silent bool) {
if !silent {
fmt.Printf("✅ 构建完成: %s\n", outPath)
fmt.Printf(" 版本: %s\n", fullVersion)
if info, err := os.Stat(outPath); err == nil {
size := float64(info.Size()) / 1024 / 1024
fmt.Printf(" 📦 %.2f MB\n", size)