什麼是語意化版本 (SemVer) 及其自動化實踐方式?
語意化版本教學 的核心在於建立「版本透明度」。其 SemVer 規範 定義了 主版號.次版號.修訂號 三位元結構:修訂號用於向下相容的 Bug 修正,次版號用於功能新增,而主版號則代表不相容的 API 變更。實踐 自動化發佈流程 的基石是 約定式提交 (Conventional Commits),透過 Commit 訊息(如 feat, fix)觸發工具。選型包含:在具備 CI/CD 環境時使用 semantic-release 教學 實現全自動化 Git Tag 與 Release Note 生成;而在本地環境則可透過 standard-version 實踐 進行 CHANGELOG 自動生成。這套流程能有效減少人為失誤,確保軟體交付節奏。
當我們使用 JavaScript 開發時,常常會需要使用 npm 進行 node_modules 的安裝,相關的使用說明可以參考前一篇寫的 NPM 常用指令教學。而在軟體工程中,如何管理這些套件的版本則是一門藝術。
在時間管理大師的世界裡,記住曾經和每個對象的回憶跟說過的話是很重要的,隨著對象越多就越有可能在某天踢到鐵板?!如果對象與對象之間的相似性和重疊性越高,就可能面臨不敢改變的風險。
在專案中,使用的套件與套件之間也可能產生相依性,那當版本需要升級時該怎麼評估和測試可能的影響?在使用套件的過程中,語意化版本 (SemVer) 代表的意涵就相對重要。這篇 語意化版本教學 將帶您掌握以下核心內容:
- 語意化版本 (SemVer) 原理。
- 約定式提交 (Conventional Commits) 規範。
- 自動產生版號、版本資訊工具:semantic-release 與 standard-version。
語意化版本 (SemVer):理解三位元版號的意義
Semantic 是語意化的意思,目標是讓用戶可以透過版本號看出相關資訊。所以 語意化版本 (SemVer) 控制會有三個要素:
- 版號必須有三位數字
1.2.3對應到主版號.次版號.修訂號,三位數字為非負整數,且會遞增。 - 依照 SemVer 的原則:
- 修訂號 (Patch):在做了向下相容的修正後遞增。
- 次版號 (Minor):有向下相容的新功能出現時遞增。
- 主版號 (Major):有任何不向下相容的修改時遞增。
- 開發階段的主版號會是 0,正式環境後會是大於 1 的數字
版號資訊會在 package.json 中 version 這個值,另外版本資訊都跟 git tag 有關,通常會寫在:
所以當我們每次進行發佈前:
- 修改版號
- 加上 git tag
- 撰寫
CHANGELOG.md - 更新到版本控制系統中撰寫 Release Note
- 發佈
約定式提交 (Conventional Commits):規範化的 Commit 訊息
約定式提交 (Conventional Commits) 規範是在程式碼提交時按照一組簡單的規則來建立明確的提交歷史。這是實現 自動化發佈 的基石。
當規範出現後,相關支援 SemVer 的自動化工具就能協助進行整理。
訊息格式會像這樣 類型(範圍): 敘述,範圍通常用檔名,所以一個 commit 訊息可能會是:
BREAKING CHANGE(README.md): 第一版說明文件
常用類型:
- BREAKING CHANGE: 影響功能
- feat: 新增功能
- perf: 效能改善
- fix: 修正 bug
舉例來說 Commit 就會長成
- fix(pencil): 什麼竟然有 typo
- feat(pencil): 加入橡皮擦變成擦擦筆
- perf(pencil): 2B 寬度變兩倍
其他不會被統整,但可能有機會用到的:
- docs: 文件
- refactor: 重構
- revert: 復原
- style: 長相風格相關,不影響功能
- test: 測試功能
- chore: 打雜類的工作
約定式提交有另外一個好處,那就是在 Code Review 的時候,可以很快的知道什麼該看什麼不該看,以小編的習慣來說只會認真看 feat 以及 fix 的部分。
Angular Commit Message Conventions:
https://github.com/angular/angular/blob/master/CONTRIBUTING.md#-commit-message-format
自動化發佈工具:Semantic-release 與 Standard-version
只要 commit 訊息有遵守 約定式提交 相關原則,commit-lint 或是 commitizen 等工具就有辦法做到強制產生提交資訊。這為 自動化發佈 提供了必要的數據來源。
那按照適用的環境主要有以下兩個工具:
| semantic-release | standard-version |
|---|---|
| 有 CI/CD | 無 CI/CD |
| git tag 及 releases | git tag 及 CHANGELOG.md |
semantic-release
semantic-release 自動化了套件的發布流程:
- 確定下一個版本號
- 產生成發佈說明
- 發布套件
在自動化過程中,不再需要靠感覺撰寫版號,嚴格遵循語義版本控制規範,並且透過版號表示更改的影響範圍,語義發布會在發布分支上每次成功建置後在 CI 環境中執行,不會有任何人介入發布的過程可以減少人為的失誤。
- 在程式碼進行 PR 產生 Merge 時觸發
- 透過 CI 工具中執行相關指令進行發佈
- 自動統整 commit 訊息成 Release Note
- 自動修改版號並加上 Git Tag
- 發佈
standard-version
基於 Conventional Commits 並使用 semver 生成 CHANGELOG 的版本控制工具,standard-version 只會在本機端處理版本控制、更改日誌生成和 Git Tag。
運行後 standard-version,您可以查看發布狀態、修正正錯誤並依照公司規範進行發佈。
跟 semantic-release 一樣都都是很棒的工具,允許自動化的情況下是建議盡量使用 semantic-release 而不是 standard-version。
- 本機端執行指令
- 自動統整 Conventional Commitsbing 並更新
CHANGELOG.md - 更新版號並加上 git tag
- 執行 Push 相關指令更新至版控系統
- 發佈
FAQ:語意化版本與自動化發佈常見問題
Q1:什麼情況下該定義為「主版號 (Major)」的變更?
A: SemVer 規範 指出:只要您的修改會導致舊有用戶的程式碼無法直接運行(Breaking Change),就必須遞增主版號。即使只是刪除了一個棄用屬性或更改了 API 回傳結構,都應視為主版號變動,以提醒用戶需進行遷移。
Q2:semantic-release 是否支援單一 Repo 管理多個 Package (Monorepo)?
A:預設的 semantic-release 教學 適用於單一 Package。對於 Monorepo,建議是搭配外掛(如 @semantic-release/monorepo)。這能確保每個子專案都能根據其 Commit 歷史獨立計算版號。
Q3:如何處理團隊成員不小心寫錯 Commit 格式的問題?
A:防範措施是在 Git Hook 中加入 commit-lint。透過 Pre-commit 檢查,強制攔截不符合 約定式提交 規範的訊息。這能確保 自動化發佈流程 始終具備乾淨數據源,避免版號計算失敗。
喜歡這篇文章,請幫忙拍拍手喔 🤣