# 版本号管理指南
本文档说明如何在小程序和后端服务中管理和显示版本号。
## 版本号机制
### 小程序版本号
- **格式**: `x.y.z`(微信要求每段 0-999)
- **生成规则**:
- `x` = package.json 中的 major 版本
- `y` = CI 构建编号 / 100
- `z` = CI 构建编号 % 100
- **示例**: 构建编号 42 → 版本 `1.0.42`,构建编号 123 → 版本 `1.1.23`
### 后端版本号
- **格式**: `1.0.{BUILD_NUMBER}`
- **生成规则**: 使用 CI 构建编号作为 patch 版本
- **示例**: 构建编号 42 → 版本 `1.0.42`
## 版本号注入流程
### 小程序(CI 构建时)
1. CI 读取 `MINIAPP_BUILD_NUMBER`(Gitea Actions 运行编号)
2. 调用 `resolve-version.cjs` 生成版本号
3. 将版本号写入 `mini/utils/version.js`
4. 上传小程序时使用该版本号
**生成的 version.js 示例**:
```javascript
module.exports = {
version: "1.0.42",
buildNumber: "42",
buildTime: "2026-08-08T12:34:56Z",
commitSha: "abc1234",
};
```
### 后端(CI 构建时)
1. CI 读取 `GITEA_RUN_NUMBER`(Gitea Actions 运行编号)
2. 生成版本号 `1.0.{RUN_NUMBER}`
3. 使用 `ldflags` 注入到 Go 二进制文件
4. 同时保存到 `bin/version.env` 文件
**生成的 version.env 示例**:
```
APP_VERSION=1.0.42
APP_BUILD_TIME=2026-08-08T12:34:56Z
APP_COMMIT_SHA=abc1234
```
## 版本号显示
### 小程序端
#### 1. 个人中心页(settings)
自动显示版本号和构建信息:
```
老黄历小程序 v1.0.42
构建 #42 (abc1234)
提供农历、黄历、八字、许愿等功能
```
#### 2. 使用版本号组件
在其他页面中使用 `version-badge` 组件:
**wxml**:
```xml
```
**json**:
```json
{
"usingComponents": {
"version-badge": "/components/version-badge/version-badge"
}
}
```
**显示效果**:
- 简单: `v1.0.42`
- 详细: `v1.0.42 #42 (abc1234)`
- 完整: `v1.0.42 #42 (abc1234) 2026/08/08 12:34`
### 后端 API
#### 获取版本信息
**接口**: `GET /api/version`
**响应**:
```json
{
"version": "1.0.42",
"buildTime": "2026-08-08T12:34:56Z",
"commitSha": "abc1234",
"goVersion": "go1.22"
}
```
**使用示例**:
```bash
curl http://localhost:8080/api/version
```
## 部署通知中的版本号
### 小程序部署通知
```
✅ 小程序开发版上传成功
状态: 成功
仓库: gouki/lunar
分支: main
提交: abc1234
作者: gouki
工作流: Publish Mini Program Dev Version #42
版本: 1.0.42 上传结果已保存到: /opt/lunar/ci-artifacts/miniapp-upload-latest.json
```
### 后端部署通知
```
✅ 后端服务部署成功
状态: 成功
仓库: gouki/lunar
分支: main
提交: abc1234
作者: gouki
工作流: Build and Deploy Server #42
版本: v1.0.42
部署包: /opt/lunar/ci-artifacts/server-deploy-latest.tar.gz
```
## 版本号一致性检查
### 本地开发环境
**小程序**:
```bash
# 查看 package.json 中的版本
cat mini/package.json | grep version
# 查看 version.js 中的版本
cat mini/utils/version.js
```
**后端**:
```bash
# 本地运行时版本为 "dev"
curl http://localhost:8080/api/version
```
### 生产环境
**小程序**:
1. 打开小程序
2. 进入"我的"页面
3. 查看"关于"部分的版本号
**后端**:
```bash
# 访问生产环境的版本接口
curl https://your-domain.com/api/version
```
### CI 构建产物
**小程序**:
```bash
# SSH 到服务器
ssh doc79
# 查看上传结果
cat /opt/lunar/ci-artifacts/miniapp-upload-latest.json | jq .version
```
**后端**:
```bash
# 查看版本信息文件
cat /opt/lunar/production/current/bin/version.env
# 或者访问 API
curl http://localhost:8080/api/version
```
## 版本号追踪
### 通过 Git Commit SHA
每个版本都包含 Git commit SHA(前 7 位),可以追溯到具体的代码提交:
```bash
# 查看某个版本的完整 commit 信息
git show abc1234
# 查看某个版本的变更内容
git log --oneline abc1234^..abc1234
```
### 通过构建编号
构建编号对应 Gitea Actions 的运行编号:
1. 访问 Gitea 网页界面
2. 进入仓库 → Actions
3. 查找对应编号的运行记录
4. 查看完整的构建日志和产物
## 故障排查
### 版本号不正确
**问题**: 小程序显示的版本号与预期不符
**排查步骤**:
1. 检查 `mini/utils/version.js` 是否被正确生成
2. 检查 CI 日志中的版本号解析过程
3. 确认 `MINIAPP_BUILD_NUMBER` 环境变量是否正确传递
### 版本号未更新
**问题**: 部署后版本号没有变化
**可能原因**:
1. CI 构建缓存导致 `version.js` 未被重新生成
2. 小程序缓存导致旧版本仍在使用
**解决方法**:
1. 清除 CI 构建缓存
2. 在小程序中清除缓存并重新编译
3. 确认 CI 日志中版本号已更新
### 后端版本号显示为 "dev"
**问题**: 生产环境的 `/api/version` 返回 `"version": "dev"`
**原因**: 环境变量未正确注入
**解决方法**:
1. 检查 CI 构建日志,确认 `ldflags` 注入成功
2. 检查部署脚本,确认 `version.env` 文件被正确加载
3. 检查容器环境变量配置
## 最佳实践
1. **版本号语义化**: 遵循语义化版本规范(SemVer)
2. **版本号可见性**: 在用户界面和 API 中都显示版本号
3. **版本号追踪**: 通过 commit SHA 和构建编号追踪版本
4. **版本号一致性**: 确保本地、CI、生产环境的版本号一致
5. **版本号文档**: 在 CHANGELOG 中记录每个版本的变更
## 相关文件
- 小程序版本配置: `mini/utils/version.js`
- 小程序版本组件: `mini/components/version-badge/`
- 后端版本接口: `server/internal/handler/version.go`
- 小程序 CI 配置: `.gitea/workflows/miniapp-preview.yml`
- 后端 CI 配置: `.gitea/workflows/server-deploy.yml`
- 版本解析脚本: `mini/ci/resolve-version.cjs`
## 更新日志
- 2026-08-08: 初始版本,支持小程序和后端的版本号注入、显示和追踪