Merge pull request #2 from ctwj/fix_version

fix: 修复版本显示不正确的问题
This commit is contained in:
ctwj
2025-08-20 17:19:41 +08:00
committed by GitHub
6 changed files with 519 additions and 9 deletions

130
BUILD.md Normal file
View File

@@ -0,0 +1,130 @@
# 编译说明
## 方案1使用编译脚本推荐
### 在Git Bash中执行
```bash
# 给脚本添加执行权限(首次使用)
chmod +x scripts/build.sh
# 编译Linux版本推荐用于服务器部署
./scripts/build.sh
# 或者明确指定编译Linux版本
./scripts/build.sh build-linux
# 或者指定目标文件名
./scripts/build.sh build-linux myapp
# 编译当前平台版本(用于本地测试)
./scripts/build.sh build
```
### 编译脚本功能:
- 自动读取 `VERSION` 文件中的版本号
- 自动获取Git提交信息和分支信息
- 自动获取构建时间
- 将版本信息编译到可执行文件中
- 支持跨平台编译默认编译Linux版本
- 使用静态链接,适合服务器部署
## 方案2手动编译
### Linux版本推荐
```bash
# 获取版本信息
VERSION=$(cat VERSION)
GIT_COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
GIT_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
BUILD_TIME=$(date '+%Y-%m-%d %H:%M:%S')
# 编译Linux版本
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags "-X 'github.com/ctwj/urldb/utils.Version=${VERSION}' -X 'github.com/ctwj/urldb/utils.BuildTime=${BUILD_TIME}' -X 'github.com/ctwj/urldb/utils.GitCommit=${GIT_COMMIT}' -X 'github.com/ctwj/urldb/utils.GitBranch=${GIT_BRANCH}'" -o main .
```
### 当前平台版本:
```bash
# 获取版本信息
VERSION=$(cat VERSION)
GIT_COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
GIT_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
BUILD_TIME=$(date '+%Y-%m-%d %H:%M:%S')
# 编译当前平台版本
go build -ldflags "-X 'github.com/ctwj/urldb/utils.Version=${VERSION}' -X 'github.com/ctwj/urldb/utils.BuildTime=${BUILD_TIME}' -X 'github.com/ctwj/urldb/utils.GitCommit=${GIT_COMMIT}' -X 'github.com/ctwj/urldb/utils.GitBranch=${GIT_BRANCH}'" -o main .
```
## 验证版本信息
编译完成后,可以通过以下方式验证版本信息:
```bash
# 命令行验证
./main version
# 启动服务器后通过API验证
curl http://localhost:8080/api/version
```
## 部署说明
使用方案1编译后部署时只需要
1. 复制可执行文件到服务器
2. 启动程序
**不再需要复制 `VERSION` 文件**,因为版本信息已经编译到程序中。
### 使用部署脚本(可选)
```bash
# 给部署脚本添加执行权限
chmod +x scripts/deploy-example.sh
# 部署到服务器
./scripts/deploy-example.sh root example.com /opt/urldb
```
### 使用Docker构建脚本
```bash
# 给脚本添加执行权限
chmod +x scripts/docker-build.sh
# 构建Docker镜像
./scripts/docker-build.sh build
# 构建指定版本镜像
./scripts/docker-build.sh build 1.2.4
# 推送镜像到Docker Hub
./scripts/docker-build.sh push 1.2.4
```
### 手动Docker构建
```bash
# 构建镜像
docker build --target backend -t ctwj/urldb-backend:1.2.3 .
docker build --target frontend -t ctwj/urldb-frontend:1.2.3 .
```
## 版本管理
更新版本号:
```bash
# 更新版本号
./scripts/version.sh patch # 修订版本
./scripts/version.sh minor # 次版本
./scripts/version.sh major # 主版本
# 然后重新编译
./scripts/build.sh
# 或者构建Docker镜像
./scripts/docker-build.sh build
```

View File

@@ -28,11 +28,26 @@ WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
# 复制VERSION文件确保构建时能正确读取版本号
COPY VERSION ./
# 复制所有源代码
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
# 定义构建参数
ARG VERSION
ARG GIT_COMMIT
ARG GIT_BRANCH
ARG BUILD_TIME
# 获取版本信息并编译
RUN VERSION=${VERSION:-$(cat VERSION)} && \
GIT_COMMIT=${GIT_COMMIT:-$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")} && \
GIT_BRANCH=${GIT_BRANCH:-$(git branch --show-current 2>/dev/null || echo "unknown")} && \
BUILD_TIME=${BUILD_TIME:-$(date '+%Y-%m-%d %H:%M:%S')} && \
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo \
-ldflags "-X 'github.com/ctwj/urldb/utils.Version=${VERSION}' \
-X 'github.com/ctwj/urldb/utils.BuildTime=${BUILD_TIME}' \
-X 'github.com/ctwj/urldb/utils.GitCommit=${GIT_COMMIT}' \
-X 'github.com/ctwj/urldb/utils.GitBranch=${GIT_BRANCH}'" \
-o main .
# 后端运行阶段
FROM alpine:latest AS backend

13
main.go
View File

@@ -1,6 +1,7 @@
package main
import (
"fmt"
"log"
"os"
"strings"
@@ -18,6 +19,18 @@ import (
)
func main() {
// 检查命令行参数
if len(os.Args) > 1 && os.Args[1] == "version" {
versionInfo := utils.GetVersionInfo()
fmt.Printf("版本: v%s\n", versionInfo.Version)
fmt.Printf("构建时间: %s\n", versionInfo.BuildTime.Format("2006-01-02 15:04:05"))
fmt.Printf("Git提交: %s\n", versionInfo.GitCommit)
fmt.Printf("Git分支: %s\n", versionInfo.GitBranch)
fmt.Printf("Go版本: %s\n", versionInfo.GoVersion)
fmt.Printf("平台: %s/%s\n", versionInfo.Platform, versionInfo.Arch)
return
}
// 初始化日志系统
if err := utils.InitLogger(nil); err != nil {
log.Fatal("初始化日志系统失败:", err)

178
scripts/build.sh Normal file
View File

@@ -0,0 +1,178 @@
#!/bin/bash
# 编译脚本 - 自动注入版本信息
# 用法: ./scripts/build.sh [target]
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 获取当前版本
get_current_version() {
cat VERSION
}
# 获取Git信息
get_git_commit() {
git rev-parse --short HEAD 2>/dev/null || echo "unknown"
}
get_git_branch() {
git branch --show-current 2>/dev/null || echo "unknown"
}
# 获取构建时间
get_build_time() {
date '+%Y-%m-%d %H:%M:%S'
}
# 编译函数
build() {
local target=${1:-"main"}
local version=$(get_current_version)
local git_commit=$(get_git_commit)
local git_branch=$(get_git_branch)
local build_time=$(get_build_time)
echo -e "${BLUE}开始编译...${NC}"
echo -e "版本: ${GREEN}${version}${NC}"
echo -e "Git提交: ${GREEN}${git_commit}${NC}"
echo -e "Git分支: ${GREEN}${git_branch}${NC}"
echo -e "构建时间: ${GREEN}${build_time}${NC}"
# 构建 ldflags
local ldflags="-X 'github.com/ctwj/urldb/utils.Version=${version}'"
ldflags="${ldflags} -X 'github.com/ctwj/urldb/utils.BuildTime=${build_time}'"
ldflags="${ldflags} -X 'github.com/ctwj/urldb/utils.GitCommit=${git_commit}'"
ldflags="${ldflags} -X 'github.com/ctwj/urldb/utils.GitBranch=${git_branch}'"
# 编译 - 使用跨平台编译设置
echo -e "${YELLOW}编译中...${NC}"
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags "${ldflags}" -o "${target}" .
if [ $? -eq 0 ]; then
echo -e "${GREEN}编译成功!${NC}"
echo -e "可执行文件: ${GREEN}${target}${NC}"
echo -e "目标平台: ${GREEN}Linux${NC}"
# 显示版本信息在Linux环境下
echo -e "${BLUE}版本信息验证:${NC}"
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
./${target} version 2>/dev/null || echo "无法验证版本信息"
else
echo "当前非Linux环境无法直接验证版本信息"
echo "请将编译后的文件复制到Linux服务器上验证"
fi
else
echo -e "${RED}编译失败!${NC}"
exit 1
fi
}
# 清理函数
clean() {
echo -e "${YELLOW}清理编译文件...${NC}"
rm -f main
echo -e "${GREEN}清理完成${NC}"
}
# 显示帮助
show_help() {
echo -e "${BLUE}编译脚本${NC}"
echo ""
echo "用法: $0 [命令]"
echo ""
echo "命令:"
echo " build [target] 编译程序 (当前平台)"
echo " build-linux [target] 编译Linux版本 (推荐)"
echo " clean 清理编译文件"
echo " help 显示此帮助信息"
echo ""
echo "示例:"
echo " $0 # 编译Linux版本 (默认)"
echo " $0 build-linux # 编译Linux版本"
echo " $0 build-linux app # 编译Linux版本为 app"
echo " $0 build # 编译当前平台版本"
echo " $0 clean # 清理编译文件"
echo ""
echo "注意:"
echo " - Linux版本使用静态链接适合部署到服务器"
echo " - 默认编译Linux版本无需复制VERSION文件"
}
# Linux编译函数
build_linux() {
local target=${1:-"main"}
local version=$(get_current_version)
local git_commit=$(get_git_commit)
local git_branch=$(get_git_branch)
local build_time=$(get_build_time)
echo -e "${BLUE}开始Linux编译...${NC}"
echo -e "版本: ${GREEN}${version}${NC}"
echo -e "Git提交: ${GREEN}${git_commit}${NC}"
echo -e "Git分支: ${GREEN}${git_branch}${NC}"
echo -e "构建时间: ${GREEN}${build_time}${NC}"
# 构建 ldflags
local ldflags="-X 'github.com/ctwj/urldb/utils.Version=${version}'"
ldflags="${ldflags} -X 'github.com/ctwj/urldb/utils.BuildTime=${build_time}'"
ldflags="${ldflags} -X 'github.com/ctwj/urldb/utils.GitCommit=${git_commit}'"
ldflags="${ldflags} -X 'github.com/ctwj/urldb/utils.GitBranch=${git_branch}'"
# Linux编译
echo -e "${YELLOW}编译中...${NC}"
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags "${ldflags}" -o "${target}" .
if [ $? -eq 0 ]; then
echo -e "${GREEN}Linux编译成功!${NC}"
echo -e "可执行文件: ${GREEN}${target}${NC}"
echo -e "目标平台: ${GREEN}Linux${NC}"
echo -e "静态链接: ${GREEN}${NC}"
# 显示文件信息
if command -v file >/dev/null 2>&1; then
echo -e "${BLUE}文件信息:${NC}"
file "${target}"
fi
echo -e "${BLUE}注意: 请在Linux服务器上验证版本信息${NC}"
else
echo -e "${RED}Linux编译失败!${NC}"
exit 1
fi
}
# 主函数
main() {
case $1 in
"build")
build $2
;;
"build-linux")
build_linux $2
;;
"clean")
clean
;;
"help"|"-h"|"--help")
show_help
;;
"")
build_linux
;;
*)
echo -e "${RED}错误: 未知命令 '$1'${NC}"
echo "使用 '$0 help' 查看帮助信息"
exit 1
;;
esac
}
# 运行主函数
main "$@"

155
scripts/docker-build.sh Normal file
View File

@@ -0,0 +1,155 @@
#!/bin/bash
# Docker构建脚本
# 用法: ./scripts/docker-build.sh [version]
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 获取版本号
get_version() {
if [ -n "$1" ]; then
echo "$1"
else
cat VERSION
fi
}
# 获取Git信息
get_git_commit() {
git rev-parse --short HEAD 2>/dev/null || echo "unknown"
}
get_git_branch() {
git branch --show-current 2>/dev/null || echo "unknown"
}
# 构建Docker镜像
build_docker() {
local version=$(get_version $1)
local git_commit=$(get_git_commit)
local git_branch=$(get_git_branch)
local build_time=$(date '+%Y-%m-%d %H:%M:%S')
echo -e "${BLUE}开始Docker构建...${NC}"
echo -e "版本: ${GREEN}${version}${NC}"
echo -e "Git提交: ${GREEN}${git_commit}${NC}"
echo -e "Git分支: ${GREEN}${git_branch}${NC}"
echo -e "构建时间: ${GREEN}${build_time}${NC}"
# 直接使用 docker build避免 buildx 的复杂性
BUILD_CMD="docker build"
echo -e "${BLUE}使用构建命令: ${BUILD_CMD}${NC}"
# 构建前端镜像
echo -e "${YELLOW}构建前端镜像...${NC}"
FRONTEND_CMD="${BUILD_CMD} --build-arg VERSION=${version} --build-arg GIT_COMMIT=${git_commit} --build-arg GIT_BRANCH=${git_branch} --build-arg BUILD_TIME=${build_time} --target frontend -t ctwj/urldb-frontend:${version} ."
echo -e "${BLUE}执行命令: ${FRONTEND_CMD}${NC}"
${BUILD_CMD} \
--build-arg VERSION=${version} \
--build-arg GIT_COMMIT=${git_commit} \
--build-arg GIT_BRANCH=${git_branch} \
--build-arg "BUILD_TIME=${build_time}" \
--target frontend \
-t ctwj/urldb-frontend:${version} \
.
# 构建后端镜像
echo -e "${YELLOW}构建后端镜像...${NC}"
BACKEND_CMD="${BUILD_CMD} --build-arg VERSION=${version} --build-arg GIT_COMMIT=${git_commit} --build-arg GIT_BRANCH=${git_branch} --build-arg BUILD_TIME=${build_time} --target backend -t ctwj/urldb-backend:${version} ."
echo -e "${BLUE}执行命令: ${BACKEND_CMD}${NC}"
${BUILD_CMD} \
--build-arg VERSION=${version} \
--build-arg GIT_COMMIT=${git_commit} \
--build-arg GIT_BRANCH=${git_branch} \
--build-arg BUILD_TIME="${build_time}" \
--target backend \
-t ctwj/urldb-backend:${version} \
.
echo -e "${GREEN}Docker构建完成!${NC}"
echo -e "镜像标签:"
echo -e " ${GREEN}ctwj/urldb-backend:${version}${NC}"
echo -e " ${GREEN}ctwj/urldb-frontend:${version}${NC}"
}
# 推送镜像
push_images() {
local version=$(get_version $1)
echo -e "${YELLOW}推送镜像到Docker Hub...${NC}"
# 推送后端镜像
docker push ctwj/urldb-backend:${version}
# 推送前端镜像
docker push ctwj/urldb-frontend:${version}
echo -e "${GREEN}镜像推送完成!${NC}"
}
# 清理镜像
clean_images() {
local version=$(get_version $1)
echo -e "${YELLOW}清理Docker镜像...${NC}"
docker rmi ctwj/urldb-backend:${version} 2>/dev/null || true
docker rmi ctwj/urldb-frontend:${version} 2>/dev/null || true
echo -e "${GREEN}镜像清理完成${NC}"
}
# 显示帮助
show_help() {
echo -e "${BLUE}Docker构建脚本${NC}"
echo ""
echo "用法: $0 [命令] [版本]"
echo ""
echo "命令:"
echo " build [version] 构建Docker镜像"
echo " push [version] 推送镜像到Docker Hub"
echo " clean [version] 清理Docker镜像"
echo " help 显示此帮助信息"
echo ""
echo "示例:"
echo " $0 build # 构建当前版本镜像"
echo " $0 build 1.2.4 # 构建指定版本镜像"
echo " $0 push 1.2.4 # 推送指定版本镜像"
echo " $0 clean # 清理当前版本镜像"
}
# 主函数
main() {
case $1 in
"build")
build_docker $2
;;
"push")
push_images $2
;;
"clean")
clean_images $2
;;
"help"|"-h"|"--help")
show_help
;;
"")
show_help
;;
*)
echo -e "${RED}错误: 未知命令 '$1'${NC}"
echo "使用 '$0 help' 查看帮助信息"
exit 1
;;
esac
}
# 运行主函数
main "$@"

View File

@@ -23,13 +23,14 @@ type VersionInfo struct {
// 编译时注入的版本信息
var (
Version = getVersionFromFile()
// 这些变量将在编译时通过 ldflags 注入
Version = "unknown" // 默认版本,编译时会被覆盖
BuildTime = GetCurrentTimeString()
GitCommit = "unknown"
GitBranch = "unknown"
)
// getVersionFromFile 从VERSION文件读取版本号
// getVersionFromFile 从VERSION文件读取版本号(备用方案)
func getVersionFromFile() string {
data, err := os.ReadFile("VERSION")
if err != nil {
@@ -42,11 +43,29 @@ func getVersionFromFile() string {
func GetVersionInfo() *VersionInfo {
buildTime, _ := ParseTime(BuildTime)
// 检查版本信息是否通过编译时注入
version := Version
gitCommit := GitCommit
gitBranch := GitBranch
// 如果编译时注入的版本是默认值,尝试从文件读取
if version == "unknown" {
version = getVersionFromFile()
}
// 如果Git信息是默认值尝试从文件读取
if gitCommit == "unknown" {
gitCommit = "unknown"
}
if gitBranch == "unknown" {
gitBranch = "unknown"
}
return &VersionInfo{
Version: Version,
Version: version,
BuildTime: buildTime,
GitCommit: GitCommit,
GitBranch: GitBranch,
GitCommit: gitCommit,
GitBranch: gitBranch,
GoVersion: runtime.Version(),
NodeVersion: getNodeVersion(),
Platform: runtime.GOOS,