跳至主要内容

版本編號規範

本文件說明 AppFuse 專案的版本編號策略,包含設計理念、適用範圍與實際範例。

設計理念

版本號的主要目的是傳達資訊給使用者。不同類型的軟體需要傳達不同的資訊:

軟體類型使用者關心的問題適合的版本策略
Library(被依賴)升級會不會破壞我的程式?SemVer(語義化版本)
Application(最終產物)這是什麼時候的版本?CalVer(日曆版本)

基於此,AppFuse 專案根據模組性質採用不同的版本策略。

框架層(Library)→ SemVer

適用模組

被其他專案依賴的 Library 使用 語義化版本 (Semantic Versioning)

模組版本格式當前版本說明
appfuse-serverMAJOR.MINOR.PATCH4.0.0-SNAPSHOTSpring Boot 工具集(跟隨 Spring Boot)
appfuse-webMAJOR.MINOR.PATCH19.0.0React 元件庫(跟隨 React)
appfuse-docsMAJOR.MINOR.PATCH4.0.0框架文檔站(跟隨 appfuse-server)
appfuse-docs-hostMAJOR.MINOR.PATCH4.0.0-SNAPSHOT框架文檔托管(跟隨 appfuse-server)

版本號意義

MAJOR.MINOR.PATCH[-SNAPSHOT]
│ │ │ │
│ │ │ └─ 開發中版本標記
│ │ └───────── 向後相容的 Bug 修復
│ └─────────────── 向後相容的功能新增
└───────────────────── 不相容的 API 變更

跟隨 Spring Boot 主版本

appfuse-server 採用跟隨 Spring Boot 主版本的策略:

appfuse-server 版本對應 Spring Boot最低 JDK
3.x.xSpring Boot 3.xJDK 17+
4.x.xSpring Boot 4.xJDK 25+

理由

  • 讓消費端清楚知道所需的運行環境
  • Spring Boot 大版本升級通常伴隨 breaking changes
  • 版本號直接反映平台需求,降低升級時的意外

跟隨 React 主版本

appfuse-web 採用跟隨 React 主版本的策略:

appfuse-web 版本對應 React說明
18.x.xReact 18.x支援 Concurrent Rendering
19.x.xReact 19.x支援 Server Components、React Compiler

理由

  • 與 appfuse-server 跟隨 Spring Boot 的策略一致
  • 讓消費端清楚知道需要哪個 React 版本
  • React 大版本升級可能引入新特性(如 Server Components)

框架文檔版本

appfuse-docsappfuse-docs-host 跟隨 appfuse-server 版本,讓使用者知道這是哪個版本框架的文檔。

參考實作層(Application)→ CalVer

適用模組

最終應用程式使用 日曆版本 (Calendar Versioning)

模組版本格式當前版本說明
app-serverYYYY.N.P-SNAPSHOT2026.1.0-SNAPSHOT後端 RESTful API
app-webYYYY.N.P2026.1.0前端 SPA
app-web-mockupYYYY.N.P2026.1.0Prototype
app-docsYYYY.N.P2026.1.0應用文檔站
app-web-hostYYYY.N.P-SNAPSHOT2026.1.0-SNAPSHOT前端托管層
app-docs-hostYYYY.N.P-SNAPSHOT2026.1.0-SNAPSHOT文檔托管層

版本號格式

YYYY.N.P[-SNAPSHOT]
│ │ │ │
│ │ │ └─ 開發中版本標記(Gradle 專案)
│ │ └─────── 問題修訂次數(從 0 開始)
│ └───────── 該年度功能更新次數(從 1 開始)
└───────────── 西元年份

版本號範例

版本意義
2026.1.02026 年第 1 次功能發布
2026.1.12026 年第 1 次功能發布的第 1 次修訂
2026.1.22026 年第 1 次功能發布的第 2 次修訂
2026.2.02026 年第 2 次功能發布
2027.1.02027 年第 1 次功能發布

為什麼選擇 CalVer?

  1. 不被依賴:應用程式是最終產物,沒有其他專案會依賴它
  2. 用戶導向:最終用戶關心的是「這是什麼時候的版本」
  3. 相容性無意義:應用程式升級是整體替換,不存在 API 相容性問題
  4. 直觀易懂:看到 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)

版本變更流程

框架層版本變更

  1. PATCH(如 4.0.0 → 4.0.1):Bug 修復
  2. MINOR(如 4.0.0 → 4.1.0):新功能,向後相容
  3. MAJOR(如 4.x → 5.x):Breaking changes,通常跟隨 Spring Boot 升級

參考實作層版本變更

  1. 功能發布(如 2026.1.0 → 2026.2.0):新增功能或重大更新
  2. 問題修訂(如 2026.1.0 → 2026.1.1):Bug 修復或小幅調整
  3. 年度更新(如 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