統一日誌格式與文件化,新增容錯回退、sha 已標記檢查與 v 前綴支援 #4

Merged
admin merged 7 commits from develop into master 2026-07-16 05:35:59 +00:00
Showing only changes of commit 8dfce93271 - Show all commits
+20 -7
View File
@@ -18,7 +18,8 @@ process.on('unhandledRejection', (reason) => {
* 同步執行 git 指令並回傳標準輸出。 * 同步執行 git 指令並回傳標準輸出。
* *
* 先以 TRC 等級記錄實際執行的指令字串,再透過 execFileSync 同步執行, * 先以 TRC 等級記錄實際執行的指令字串,再透過 execFileSync 同步執行,
* 回傳去除前後空白的 stdout 內容。 * 回傳去除前後空白的 stdout 內容。stderr 不直通主控台(擷取到 error.stderr),
* 失敗時由呼叫端以統一格式輸出,避免與格式化訊息重複。
* *
* @param {string[]} args - git 指令的引數陣列(不含 'git' 本身),例如 ['tag', '--list'] * @param {string[]} args - git 指令的引數陣列(不含 'git' 本身),例如 ['tag', '--list']
* @param {string} stage - 日誌用的流程階段名稱,例如 '讀取版號' * @param {string} stage - 日誌用的流程階段名稱,例如 '讀取版號'
@@ -31,7 +32,7 @@ process.on('unhandledRejection', (reason) => {
*/ */
function git(args, stage) { function git(args, stage) {
logger.trc(`執行指令:git ${args.join(' ')}`, 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 會拒絕存取), *(容器內以 root 執行而 workspace 屬於其他使用者時,git 會拒絕存取),
* 再列出全部 tag、逐一以 parse() 解析並以 compare() 取最大版號; * 再列出全部 tag、逐一以 parse() 解析並以 compare() 取最大版號;
* 不符合版號格式的 tag 以 DBG 記錄後略過。 * 不符合版號格式的 tag 以 DBG 記錄後略過。
* git tag 讀取失敗(例如 workspace 不是 git repository、workflow 未先執行
* actions/checkout)時不中止程序:輸出 ERR 說明原因與修正方式後回傳 null,
* 讓呼叫端改以起始版號(0.0.1)計算。
* *
* @returns {?{major: number, minor: number, patch: number, beta: ?number}} * @returns {?{major: number, minor: number, patch: number, beta: ?number}}
* 最新版號物件;找不到任何符合格式的 tag 時輸出 WRN 並回傳 null(呼叫端從起始版號計算) * 最新版號物件;找不到任何符合格式的 tag、或 git tag 讀取失敗時回傳 null
* @throws {Error} git 指令執行失敗時,由 git() 拋出 * (呼叫端從起始版號計算)
* *
* @example * @example
* const latest = findLatestVersion(); * const latest = findLatestVersion();
* // tag 有 1.2.3、1.2.4-beta.3 時 => { major: 1, minor: 2, patch: 4, beta: 3 } * // 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() { function findLatestVersion() {
const stage = '讀取版號'; const stage = '讀取版號';
const workspace = process.env.GITHUB_WORKSPACE || process.cwd(); const workspace = process.env.GITHUB_WORKSPACE || process.cwd();
git(['config', '--global', '--add', 'safe.directory', workspace], stage); let output;
try {
const output = git(['-C', workspace, 'tag', '--list'], stage); 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'); const tags = output === '' ? [] : output.split('\n');
logger.inf(`git tag 共 ${tags.length}`, stage); logger.inf(`git tag 共 ${tags.length}`, stage);