語意化版本 (SemVer) 與自動發佈 定義約定式提交規範並實作自動產生版號與日誌

me
林彥成
2022-09-28 | 4 min.
文章目錄
  1. 1. 什麼是語意化版本 (SemVer) 及其自動化實踐方式?
  2. 2. 語意化版本 (SemVer):理解三位元版號的意義
  3. 3. 約定式提交 (Conventional Commits):規範化的 Commit 訊息
  4. 4. 自動化發佈工具:Semantic-release 與 Standard-version
    1. 4.1. semantic-release
    2. 4.2. standard-version
  5. 5. FAQ:語意化版本與自動化發佈常見問題
    1. 5.1. Q1:什麼情況下該定義為「主版號 (Major)」的變更?
    2. 5.2. Q2:semantic-release 是否支援單一 Repo 管理多個 Package (Monorepo)?
    3. 5.3. Q3:如何處理團隊成員不小心寫錯 Commit 格式的問題?

什麼是語意化版本 (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-releasestandard-version

語意化版本 (SemVer):理解三位元版號的意義

Semantic 是語意化的意思,目標是讓用戶可以透過版本號看出相關資訊。所以 語意化版本 (SemVer) 控制會有三個要素:

  1. 版號必須有三位數字 1.2.3 對應到 主版號.次版號.修訂號,三位數字為非負整數,且會遞增。
  2. 依照 SemVer 的原則
  • 修訂號 (Patch):在做了向下相容的修正後遞增。
  • 次版號 (Minor):有向下相容的新功能出現時遞增。
  • 主版號 (Major):有任何不向下相容的修改時遞增。
  1. 開發階段的主版號會是 0,正式環境後會是大於 1 的數字

版號資訊會在 package.json 中 version 這個值,另外版本資訊都跟 git tag 有關,通常會寫在:

所以當我們每次進行發佈前:

  1. 修改版號
  2. 加上 git tag
  3. 撰寫 CHANGELOG.md
  4. 更新到版本控制系統中撰寫 Release Note
  5. 發佈

約定式提交 (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-releasestandard-version
有 CI/CD無 CI/CD
git tag 及 releasesgit tag 及 CHANGELOG.md

semantic-release

semantic-release 自動化了套件的發布流程:

  1. 確定下一個版本號
  2. 產生成發佈說明
  3. 發布套件

在自動化過程中,不再需要靠感覺撰寫版號,嚴格遵循語義版本控制規範,並且透過版號表示更改的影響範圍,語義發布會在發布分支上每次成功建置後在 CI 環境中執行,不會有任何人介入發布的過程可以減少人為的失誤。

  1. 在程式碼進行 PR 產生 Merge 時觸發
  2. 透過 CI 工具中執行相關指令進行發佈
  3. 自動統整 commit 訊息成 Release Note
  4. 自動修改版號並加上 Git Tag
  5. 發佈

standard-version

基於 Conventional Commits 並使用 semver 生成 CHANGELOG 的版本控制工具,standard-version 只會在本機端處理版本控制、更改日誌生成和 Git Tag。

運行後 standard-version,您可以查看發布狀態、修正正錯誤並依照公司規範進行發佈。

跟 semantic-release 一樣都都是很棒的工具,允許自動化的情況下是建議盡量使用 semantic-release 而不是 standard-version。

  1. 本機端執行指令
  2. 自動統整 Conventional Commitsbing 並更新 CHANGELOG.md
  3. 更新版號並加上 git tag
  4. 執行 Push 相關指令更新至版控系統
  5. 發佈

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 檢查,強制攔截不符合 約定式提交 規範的訊息。這能確保 自動化發佈流程 始終具備乾淨數據源,避免版號計算失敗。



喜歡這篇文章,請幫忙拍拍手喔 🤣