Calculate Next Version

從 git tag 取得最新版號,依 is_beta 計算下一個正式版或 beta 版號(各號碼滿 9 進位)並輸出為 value 的 Gitea/GitHub Docker container action。

  • 更新時間:2026/07/16 09:23:47

action 使用方式

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0   # 需要完整 tag 歷史才能計算版號
      - id: version
        uses: docker-actions/calculate-next-version@master
        with:
          is_beta: 'false'
      - run: echo "下一版號:${{ steps.version.outputs.value }}"
類型 名稱 必填 預設值 說明
input is_beta false 是否為 beta 版(true 時產生 X.Y.Z-beta.N 版號)
output value 計算出的下一版號

版號規則:

  • 版號來源為 repo 的 git tag(格式 X.Y.ZX.Y.Z-beta.N,不帶前綴),取最大版號;無任何版號 tag 時從 0.0.1beta 為 0.0.1-beta.1)起算。
  • is_beta=false:最新為正式版 → patch +11.2.31.2.4);最新為 beta → 去掉 beta 尾碼轉正式(1.2.4-beta.31.2.4)。
  • is_beta=true:最新為正式版 → patch +1 加 -beta.1;最新為 beta → beta 號 +1beta.9beta.10,無上限)。
  • major/minor/patch 各上限 9,滿 9 進位(1.2.91.3.01.9.92.0.0);9.9.9 再進位則報錯並以非零 exit code 結束。

日誌格式:所有輸出訊息統一為 [階段][等級][時間]: 訊息階段 選填;等級INF/WRN/ERR/TRC/DBG時間 為 Asia/Taipei 時區的 yyyy/MM/dd HH:mm:ss)。

專案列表

專案描述表

專案名稱 專案描述
calculate-next-version Docker container action:提供版號解析/比較/進位計算(version 模組)與統一格式日誌輸出(logger 模組),從 git tag 計算下一個正式版或 beta 版號並寫出為 action 輸出 value

參考專案表

專案名稱 參考專案列表
calculate-next-version

NuGet 套件表

專案名稱 NuGet 套件列表
calculate-next-version 無(Node.js 專案,僅使用 node 內建模組,無外部相依)

功能列表

calculate-next-version

功能名稱 功能描述
logger.inf 輸出 INF(一般資訊)等級的日誌訊息到 stdout
logger.wrn 輸出 WRN(警告)等級的日誌訊息到 stdout
logger.err 輸出 ERR(錯誤)等級的日誌訊息到 stderr
logger.trc 輸出 TRC(細部追蹤)等級的日誌訊息到 stdout
logger.dbg 輸出 DBG(除錯)等級的日誌訊息到 stdout
version.parse 解析版號字串為版號物件,不符格式回傳 null
version.stringify 將版號物件轉換為版號字串
version.compare 比較兩個版號物件的大小,正式版大於同號 beta
version.next 依最新版號與 is_beta 旗標計算下一版號

使用範例

logger.inf

輸出 INF(一般資訊)等級的日誌訊息到 stdout,格式為 [階段][等級][時間]: 訊息(時間為 Asia/Taipei 時區的 yyyy/MM/dd HH:mm:ss);stage 選填,省略時訊息不含 [階段] 區塊。用於記錄流程中的正常進度,例如讀到的輸入、計算結果、寫出的輸出。

const logger = require('./logger');

logger.inf('下一版號:1.2.4', '計算版號');
// [計算版號][INF][2026/07/16 09:23:47]: 下一版號:1.2.4

logger.inf('計算完成');
// [INF][2026/07/16 09:23:47]: 計算完成

logger.wrn

輸出 WRN(警告)等級的日誌訊息到 stdout,格式與參數同 logger.inf。用於非致命的異常狀況,例如找不到任何版號 tag、需注意的邊界條件。

const logger = require('./logger');

logger.wrn('找不到任何符合 X.Y.Z 或 X.Y.Z-beta.N 格式的 tag,將從起始版號計算', '讀取版號');
// [讀取版號][WRN][2026/07/16 09:23:47]: 找不到任何符合 X.Y.Z 或 X.Y.Z-beta.N 格式的 tag,將從起始版號計算

logger.err

輸出 ERR(錯誤)等級的日誌訊息到 stderr(console.error),格式與參數同 logger.inf。用於可預期錯誤與未捕捉例外的回報;呼叫端通常在輸出後以非零 exit code 結束。

const logger = require('./logger');

logger.err('找不到環境變數 GITHUB_OUTPUT,無法寫出輸出', '寫出結果');
// [寫出結果][ERR][2026/07/16 09:23:47]: 找不到環境變數 GITHUB_OUTPUT,無法寫出輸出
process.exit(1);

logger.trc

輸出 TRC(細部追蹤)等級的日誌訊息到 stdout,格式與參數同 logger.inf。用於記錄低層次操作的細節,例如實際執行的外部指令、逐筆解析的中間結果。

const logger = require('./logger');

logger.trc('執行指令:git tag --list', '讀取版號');
// [讀取版號][TRC][2026/07/16 09:23:47]: 執行指令:git tag --list

logger.dbg

輸出 DBG(除錯)等級的日誌訊息到 stdout,格式與參數同 logger.inf。用於協助開發者追蹤程式流程與詳細狀態,例如被略過的不符格式 tag。

const logger = require('./logger');

logger.dbg('略過不符合版號格式的 tagnot-a-version', '讀取版號');
// [讀取版號][DBG][2026/07/16 09:23:47]: 略過不符合版號格式的 tagnot-a-version

version.parse

解析版號字串為版號物件 { major, minor, patch, beta };支援正式版(X.Y.Z)與 beta 版(X.Y.Z-beta.N)兩種格式,betanull 表示正式版。不符合格式(含 null、非字串轉出的值)時回傳 null、不拋出例外,適合逐一解析 git tag 並過濾非版號 tag。

const { parse } = require('./version');

parse('1.2.3');        // => { major: 1, minor: 2, patch: 3, beta: null }
parse('1.2.3-beta.5'); // => { major: 1, minor: 2, patch: 3, beta: 5 }
parse('v1.2');         // => null(不符合格式)

version.stringify

將版號物件轉換為版號字串;betanull 時輸出 X.Y.Z,否則輸出 X.Y.Z-beta.N。為 version.parse 的反向操作,用於日誌輸出與最終寫出 action 的 value

const { stringify } = require('./version');

stringify({ major: 1, minor: 2, patch: 3, beta: null }); // => '1.2.3'
stringify({ major: 1, minor: 2, patch: 3, beta: 5 });    // => '1.2.3-beta.5'

version.compare

比較兩個版號物件的大小,回傳正數(a > b)、0(相等)或負數(a < b)。依 major → minor → patch → beta 的順序比較;同號碼時正式版大於 beta 版(1.2.4 > 1.2.4-beta.3),beta 版之間依號碼比較。用於在所有 git tag 中挑出最大(最新)的版號。

const { parse, compare } = require('./version');

compare(parse('1.2.4'), parse('1.2.4-beta.3'));        // => 1(正式版較大)
compare(parse('1.2.4-beta.5'), parse('1.2.4-beta.3')); // => 2beta 依號碼比較)
compare(parse('2.0.0'), parse('1.9.9'));               // => 1

version.next

依最新版號與 is_beta 旗標計算下一版號。latestnull 時起算 0.0.1beta 為 0.0.1-beta.1);最新為 beta 版時,isBeta=false 去尾碼轉正式、isBeta=true 則 beta 號 +1(無上限);最新為正式版時 patch 進位(各位數滿 9 進位),isBeta=true 再加 -beta.1。最新正式版已達 9.9.9 需再進位時拋出 Error(呼叫端輸出 ERR 後以非零 exit code 結束)。

const { parse, next, stringify } = require('./version');

stringify(next(parse('1.2.3'), false));        // => '1.2.4'
stringify(next(parse('1.2.3'), true));         // => '1.2.4-beta.1'
stringify(next(parse('1.2.4-beta.3'), false)); // => '1.2.4'(轉正式)
stringify(next(parse('1.2.9'), false));        // => '1.3.0'(滿 9 進位)
stringify(next(null, true));                   // => '0.0.1-beta.1'
2026-07-17 05:04:05 +00:00
Languages
JavaScript 90.5%
Shell 9.5%