版本編號規範
本文件說明 AppFuse 專案的版本編號策略,包含設計理念、適用範圍與實際範例。
設計理念
版本號的主要目的是傳達資訊給使用者。不同類型的軟體需要傳達不同的資訊:
| 軟體類型 | 使用者關心的問題 | 適合的版本策略 |
|---|---|---|
| Library(被依賴) | 升級會不會破壞我的程式? | SemVer(語義化版本) |
| Application(最終產物) | 這是什麼時候的版本? | CalVer(日曆版本) |
基於此,AppFuse 專案根據模組性質採用不同的版本策略。
框架層(Library)→ SemVer
適用模組
被其他專案依賴的 Library 使用 語義化版本 (Semantic Versioning):
| 模組 | 版本格式 | 當前版本 | 說明 |
|---|---|---|---|
| appfuse-server | MAJOR.MINOR.PATCH | 4.0.0-SNAPSHOT | Spring Boot 工具集(跟隨 Spring Boot) |
| appfuse-web | MAJOR.MINOR.PATCH | 19.0.0 | React 元件庫(跟隨 React) |
| appfuse-docs | MAJOR.MINOR.PATCH | 4.0.0 | 框架文檔站(跟隨 appfuse-server) |
| appfuse-docs-host | MAJOR.MINOR.PATCH | 4.0.0-SNAPSHOT | 框架文檔托管(跟隨 appfuse-server) |
版本號意義
MAJOR.MINOR.PATCH[-SNAPSHOT]
│ │ │ │
│ │ │ └─ 開發中版本標記
│ │ └───────── 向後相容的 Bug 修復
│ └─────────────── 向後相容的功能新增
└───────────────────── 不相容的 API 變更
跟隨 Spring Boot 主版本
appfuse-server 採用跟隨 Spring Boot 主版本的策略:
| appfuse-server 版本 | 對應 Spring Boot | 最低 JDK |
|---|---|---|
| 3.x.x | Spring Boot 3.x | JDK 17+ |
| 4.x.x | Spring Boot 4.x | JDK 25+ |
理由:
- 讓消費端清楚知道所需的運行環境
- Spring Boot 大版本升級通常伴隨 breaking changes
- 版本號直接反映平台需求,降低升級時的意外
跟隨 React 主版本
appfuse-web 採用跟隨 React 主版本的策略:
| appfuse-web 版本 | 對應 React | 說明 |
|---|---|---|
| 18.x.x | React 18.x | 支援 Concurrent Rendering |
| 19.x.x | React 19.x | 支援 Server Components、React Compiler |
理由:
- 與 appfuse-server 跟隨 Spring Boot 的策略一致
- 讓消費端清楚知道需要哪個 React 版本
- React 大版本升級可能引入新特性(如 Server Components)
框架文檔版本
appfuse-docs 與 appfuse-docs-host 跟隨 appfuse-server 版本,讓使用者知道這是哪個版本框架的文檔。
參考實作層(Application)→ CalVer
適用模組
最終應用程式使用 日曆版本 (Calendar Versioning):
| 模組 | 版本格式 | 當前版本 | 說明 |
|---|---|---|---|
| app-server | YYYY.N.P-SNAPSHOT | 2026.1.0-SNAPSHOT | 後端 RESTful API |
| app-web | YYYY.N.P | 2026.1.0 | 前端 SPA |
| app-web-mockup | YYYY.N.P | 2026.1.0 | Prototype |
| app-docs | YYYY.N.P | 2026.1.0 | 應用文檔站 |
| app-web-host | YYYY.N.P-SNAPSHOT | 2026.1.0-SNAPSHOT | 前端托管層 |
| app-docs-host | YYYY.N.P-SNAPSHOT | 2026.1.0-SNAPSHOT | 文檔托管層 |
版本號格式
YYYY.N.P[-SNAPSHOT]
│ │ │ │
│ │ │ └─ 開發中版本標記(Gradle 專案)
│ │ └─────── 問題修訂次數(從 0 開始)
│ └───────── 該年度功能更新次數(從 1 開始)
└───────────── 西元年份
版本號範例
| 版本 | 意義 |
|---|---|
2026.1.0 | 2026 年第 1 次功能發布 |
2026.1.1 | 2026 年第 1 次功能發布的第 1 次修訂 |
2026.1.2 | 2026 年第 1 次功能發布的第 2 次修訂 |
2026.2.0 | 2026 年第 2 次功能發布 |
2027.1.0 | 2027 年第 1 次功能發布 |
為什麼選擇 CalVer?
- 不被依賴:應用程式是最終產物,沒有其他專案會依賴它
- 用戶導向:最終用戶關心的是「這是什麼時候的版本」
- 相容性無意義:應用程式升級是整體替換,不存在 API 相容性問題
- 直觀易懂:看到
2026.2.0就知道是 2026 年第 2 次更新
托管層版本同步
托管層與被托管的應用保持版本同步:
app-web (2026.1.0) ──build──→ app-web-host (2026.1.0-SNAPSHOT)
app-docs (2026.1.0) ──build──→ app-docs-host (2026.1.0-SNAPSHOT)
理由:當部署 app-web-host:2026.1.0 時,立即知道它包含的是 app-web:2026.1.0。
知名專案的版本策略參考
SemVer 範例
- React: 18.2.0, 19.0.0
- Spring Boot: 3.2.0, 4.0.0
- Node.js: 20.10.0, 22.0.0
CalVer 範例
- Ubuntu: 24.04, 24.10(YYYY.MM)
- JetBrains IDEs: 2024.1, 2024.2(YYYY.N)
- pip: 24.0, 24.1(YY.N)
版本變更流程
框架層版本變更
- PATCH(如 4.0.0 → 4.0.1):Bug 修復
- MINOR(如 4.0.0 → 4.1.0):新功能,向後相容
- MAJOR(如 4.x → 5.x):Breaking changes,通常跟隨 Spring Boot 升級
參考實作層版本變更
- 功能發布(如 2026.1.0 → 2026.2.0):新增功能或重大更新
- 問題修訂(如 2026.1.0 → 2026.1.1):Bug 修復或小幅調整
- 年度更新(如 2026.x.x → 2027.1.0):跨年度的第一次發布
版本號位置
Gradle 專案(Java/Kotlin)
版本定義在 gradle.properties:
# appfuse-server/gradle.properties
version=4.0.0-SNAPSHOT
# app-server/gradle.properties
version=2026.1.0-SNAPSHOT
npm 專案(JavaScript/TypeScript)
版本定義在 package.json:
{
"name": "app-web",
"version": "2026.1.0"
}
常見問題
Q: 為什麼 appfuse-server 用 4.0.0 而不是 0.1.0?
因為 appfuse-server 跟隨 Spring Boot 主版本。當使用 Spring Boot 4.x 時,版本號為 4.x.x,讓消費端立即知道需要 Spring Boot 4.x 環境和 JDK 25+。
Q: CalVer 的年份跨年時怎麼處理?
跨年後的第一次發布使用新年份,例如:
- 2026 年最後一次:
2026.12.0 - 2027 年第一次:
2027.1.0
Q: SNAPSHOT 是什麼意思?
-SNAPSHOT 表示這是開發中的版本,尚未正式發布。Gradle 會從 snapshot repository 下載,每次建構可能獲得不同的內容。正式發布時移除此後綴。
Q: npm 專案為什麼沒有 SNAPSHOT?
npm 生態系統使用不同的預發布標記方式(如 -alpha, -beta, -rc)。對於私有的應用程式專案,直接使用正式版本號即可。
Q: 為什麼 appfuse-web 用 19.0.0 而不是 0.1.x?
因為 appfuse-web 跟隨 React 主版本。當使用 React 19.x 時,版本號為 19.x.x,讓消費端立即知道需要 React 19.x。這與 appfuse-server 跟隨 Spring Boot 的策略一致。
總結
框架層 (Library) → SemVer(跟隨底層框架主版本)
├── appfuse-server: 4.0.0-SNAPSHOT (跟隨 Spring Boot 4.x)
├── appfuse-web: 19.0.0 (跟隨 React 19.x)
├── appfuse-docs: 4.0.0
└── appfuse-docs-host: 4.0.0-SNAPSHOT
參考實作層 (Application) → CalVer(YYYY.N.P)
├── app-server: 2026.1.0-SNAPSHOT
├── app-web: 2026.1.0
├── app-web-mockup: 2026.1.0
├── app-docs: 2026.1.0
├── app-web-host: 2026.1.0-SNAPSHOT
└── app-docs-host: 2026.1.0-SNAPSHOT