2 Commits
Author SHA1 Message Date
JefferyandClaude Fable 5 76a896c306 docs(README): 補充 git tag 讀取失敗時回退起始版號的行為說明
docker-actions/template: CI / BUILD (pull_request) Successful in 1m3s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 11:08:58 +08:00
JefferyandClaude Fable 5 8dfce93271 feat(讀取版號): git tag 讀取失敗時輸出 ERR 並改以起始版號 0.0.1 作為預設值
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 11:08:58 +08:00
2 changed files with 22 additions and 8 deletions
+2 -1
View File
@@ -2,7 +2,7 @@
從 git tag 取得最新版號,依 `is_beta` 計算下一個正式版或 beta 版號(各號碼滿 9 進位)並輸出為 `value` 的 Gitea/GitHub Docker container action。
- 更新時間:2026/07/16 09:23:47
- 更新時間:2026/07/16 11:08:39
## action 使用方式
@@ -29,6 +29,7 @@ jobs:
版號規則:
- 版號來源為 repo 的 git tag(格式 `X.Y.Z``X.Y.Z-beta.N`,不帶前綴),取最大版號;無任何版號 tag 時從 `0.0.1`beta 為 `0.0.1-beta.1`)起算。
- git tag 讀取失敗(例如 workspace 不是 git repository、workflow 未先執行 `actions/checkout`)時不會中止:輸出 ERR 說明原因後,改以起始版號 `0.0.1`beta 為 `0.0.1-beta.1`)作為預設值繼續輸出。
- `is_beta=false`:最新為正式版 → patch +1`1.2.3``1.2.4`);最新為 beta → 去掉 beta 尾碼轉正式(`1.2.4-beta.3``1.2.4`)。
- `is_beta=true`:最新為正式版 → patch +1 加 `-beta.1`;最新為 beta → beta 號 +1`beta.9``beta.10`,無上限)。
- major/minor/patch 各上限 9,滿 9 進位(`1.2.9``1.3.0``1.9.9``2.0.0`);`9.9.9` 再進位則報錯並以非零 exit code 結束。
+20 -7
View File
@@ -18,7 +18,8 @@ process.on('unhandledRejection', (reason) => {
* 同步執行 git 指令並回傳標準輸出。
*
* 先以 TRC 等級記錄實際執行的指令字串,再透過 execFileSync 同步執行,
* 回傳去除前後空白的 stdout 內容。
* 回傳去除前後空白的 stdout 內容。stderr 不直通主控台(擷取到 error.stderr),
* 失敗時由呼叫端以統一格式輸出,避免與格式化訊息重複。
*
* @param {string[]} args - git 指令的引數陣列(不含 'git' 本身),例如 ['tag', '--list']
* @param {string} stage - 日誌用的流程階段名稱,例如 '讀取版號'
@@ -31,7 +32,7 @@ process.on('unhandledRejection', (reason) => {
*/
function git(args, stage) {
logger.trc(`執行指令:git ${args.join(' ')}`, stage);
return execFileSync('git', args, { encoding: 'utf8' }).trim();
return execFileSync('git', args, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }).trim();
}
/**
@@ -69,22 +70,34 @@ function readIsBeta() {
*(容器內以 root 執行而 workspace 屬於其他使用者時,git 會拒絕存取),
* 再列出全部 tag、逐一以 parse() 解析並以 compare() 取最大版號;
* 不符合版號格式的 tag 以 DBG 記錄後略過。
* git tag 讀取失敗(例如 workspace 不是 git repository、workflow 未先執行
* actions/checkout)時不中止程序:輸出 ERR 說明原因與修正方式後回傳 null,
* 讓呼叫端改以起始版號(0.0.1)計算。
*
* @returns {?{major: number, minor: number, patch: number, beta: ?number}}
* 最新版號物件;找不到任何符合格式的 tag 時輸出 WRN 並回傳 null(呼叫端從起始版號計算)
* @throws {Error} git 指令執行失敗時,由 git() 拋出
* 最新版號物件;找不到任何符合格式的 tag、或 git tag 讀取失敗時回傳 null
* (呼叫端從起始版號計算)
*
* @example
* const latest = findLatestVersion();
* // tag 有 1.2.3、1.2.4-beta.3 時 => { major: 1, minor: 2, patch: 4, beta: 3 }
* // workspace 不是 git repo 時 => null,並輸出:
* // [讀取版號][ERR][時間]: 無法讀取 git tagfatal: not a git repository ...
*/
function findLatestVersion() {
const stage = '讀取版號';
const workspace = process.env.GITHUB_WORKSPACE || process.cwd();
git(['config', '--global', '--add', 'safe.directory', workspace], stage);
const output = git(['-C', workspace, 'tag', '--list'], stage);
let output;
try {
git(['config', '--global', '--add', 'safe.directory', workspace], stage);
output = git(['-C', workspace, 'tag', '--list'], stage);
} catch (error) {
const detail = (error.stderr || error.message || String(error)).toString().trim().replace(/\s*\n\s*/g, '');
logger.err(`無法讀取 ${workspace} 的 git tag${detail}`, stage);
logger.wrn('請確認 workflow 已先執行 actions/checkoutfetch-depth: 0);本次改以起始版號計算', stage);
return null;
}
const tags = output === '' ? [] : output.split('\n');
logger.inf(`git tag 共 ${tags.length}`, stage);