Compare commits
8
Commits
v0.0.0-beta.18
...
v0.0.7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
73e79f6be8 | ||
|
|
fa4f7cd50b | ||
|
|
c8fe088e42 | ||
|
|
33d5aacee5 | ||
|
|
6ee9195f52 | ||
|
|
768ab84b00 | ||
|
|
c60b71e987 | ||
|
|
96cb99c136 |
@@ -1,19 +0,0 @@
|
||||
# Dockerfile draft
|
||||
<!--
|
||||
Purpose: 建立 action 執行映像 / build the action runtime image
|
||||
Timestamp: 2026/07/11 17:23:33 (Asia/Taipei)
|
||||
-->
|
||||
|
||||
```dockerfile
|
||||
# FROM node:lts-alpine
|
||||
|
||||
# WORKDIR /action
|
||||
|
||||
# COPY src/ /action/src/
|
||||
# COPY entrypoint.sh /action/entrypoint.sh
|
||||
|
||||
# RUN chmod +x /action/entrypoint.sh
|
||||
|
||||
# ENTRYPOINT ["/action/entrypoint.sh"]
|
||||
```
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
# action.yml draft
|
||||
<!--
|
||||
Purpose: 計算版本號 / calculate the next version number for the action
|
||||
Timestamp: 2026/07/11 17:23:33 (Asia/Taipei)
|
||||
-->
|
||||
|
||||
```yaml
|
||||
# name: 'Calculate Version'
|
||||
# description: '計算版本號'
|
||||
# author: 'Jeffery'
|
||||
# inputs:
|
||||
# is_beta:
|
||||
# description: '是否為 beta 版本'
|
||||
# default: 'false'
|
||||
# runner_token:
|
||||
# description: '用於讀取 release 的 token'
|
||||
# required: false
|
||||
# outputs:
|
||||
# version:
|
||||
# description: '計算出的版本號'
|
||||
# runs:
|
||||
# using: 'docker'
|
||||
# image: 'Dockerfile'
|
||||
# env:
|
||||
# GITEA_SERVER_URL: ${{ gitea.server_url }}
|
||||
# GITEA_REPOSITORY: ${{ gitea.repository }}
|
||||
# GITEA_TOKEN: ${{ gitea.token }}
|
||||
# RUNNER_TOKEN: ${{ inputs.runner_token || secrets.GITEA_TOKEN || secrets.RUNNER_TOKEN }}
|
||||
# IS_BETA: ${{ inputs.is_beta }}
|
||||
```
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
# entrypoint.sh draft
|
||||
<!--
|
||||
Purpose: 啟動 Node.js 主程式 / start the Node.js entrypoint
|
||||
Timestamp: 2026/07/11 17:23:33 (Asia/Taipei)
|
||||
-->
|
||||
|
||||
```sh
|
||||
# #!/bin/sh
|
||||
# set -eu
|
||||
|
||||
# exec node /action/src/index.js "$@"
|
||||
```
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
# `src/index.js` function drafts
|
||||
|
||||
## 1. `section(title)`
|
||||
|
||||
- 來源位置: `src/index.js:9-11`
|
||||
- 完整簽名: `function section(title)`
|
||||
- 行為分析: 只把 `currentStage` 更新成傳入標題,讓後續 `info()` 能夠在 log 前加上階段前綴。沒有回傳值,也沒有其他副作用。 / It only updates `currentStage` so later `info()` calls can prefix logs with the current stage. It returns nothing and has no other side effects.
|
||||
- 建議摘要: 設定目前執行階段。 / Set the current execution stage.
|
||||
- 參數註解:
|
||||
- `title`: 階段名稱字串,通常是流程標題,例如 `參數檢查`。 / Stage title string, typically a workflow label such as `參數檢查`.
|
||||
- 備註與使用情境: 當主流程要切換到不同步驟時先呼叫它,這樣 `info()` 的輸出會帶上對應階段,方便追 log。 / Call it before a workflow step so `info()` output carries the right stage prefix for easier log tracing.
|
||||
- 內部呼叫: 無。 / None.
|
||||
|
||||
## 2. `info(message)`
|
||||
|
||||
- 來源位置: `src/index.js:13-20`
|
||||
- 完整簽名: `function info(message)`
|
||||
- 行為分析: 產生台灣時區的時間戳,結合目前 `currentStage` 組成固定格式的資訊 log,並直接寫到 `stdout`。時間格式化是輸出格式整理,不改變流程邏輯。 / It builds a Taiwan-time timestamp, combines it with `currentStage`, and writes a fixed-format info log directly to `stdout`. The timestamp formatting is output normalization only and does not change logic.
|
||||
- 建議摘要: 輸出帶階段前綴與台灣時間的資訊訊息。 / Emit an info log with stage prefix and Taiwan timestamp.
|
||||
- 參數註解:
|
||||
- `message`: 要輸出的訊息內容。 / Message body to print.
|
||||
- 備註與使用情境: 當 action 需要對齊 Gitea action log 風格時使用,例如列出版本 URL、頁數與計算結果。 / Use it when the action should emit structured logs, such as release URLs, page counts, or computed versions.
|
||||
- 內部呼叫: 無;但依賴 `currentStage`、`new Date()`、`toLocaleString()` 與 `process.stdout.write()`。 / None; it depends on `currentStage`, `new Date()`, `toLocaleString()`, and `process.stdout.write()`.
|
||||
|
||||
## 3. `fail(message)`
|
||||
|
||||
- 來源位置: `src/index.js:22-24`
|
||||
- 完整簽名: `function fail(message)`
|
||||
- 行為分析: 直接丟出 `Error`,用於統一中止流程並讓呼叫端接住錯誤。 / It throws an `Error` immediately, providing a single place to abort the flow and let callers handle the failure.
|
||||
- 建議摘要: 以錯誤訊息中止執行。 / Abort execution with an error message.
|
||||
- 參數註解:
|
||||
- `message`: 錯誤訊息。 / Error message.
|
||||
- 備註與使用情境: `requireEnv()` 會用它回報必要環境變數缺失。 / `requireEnv()` uses it to report missing required environment variables.
|
||||
- 內部呼叫: 無。 / None.
|
||||
|
||||
## 4. `requireEnv(name, value)`
|
||||
|
||||
- 來源位置: `src/index.js:26-32`
|
||||
- 完整簽名: `function requireEnv(name, value)`
|
||||
- 行為分析: 檢查環境變數值是否為空或字串 `null`;若是就透過 `fail()` 中止,否則原樣回傳。這是嚴格驗證,不做額外轉型。 / It checks whether an environment value is empty or the string `null`; if so it aborts via `fail()`, otherwise it returns the original value unchanged. This is strict validation with no extra coercion.
|
||||
- 建議摘要: 驗證必要環境變數並回傳原值。 / Validate a required environment variable and return the original value.
|
||||
- 參數註解:
|
||||
- `name`: 變數名稱,用於錯誤訊息。 / Variable name used in the error message.
|
||||
- `value`: 已讀取的環境變數值。 / The already-read environment value.
|
||||
- 備註與使用情境: 在 `main()` 讀取 `GITEA_SERVER_URL` 與 `GITEA_REPOSITORY` 時使用,避免後續 URL 組裝失敗。 / Used in `main()` for `GITEA_SERVER_URL` and `GITEA_REPOSITORY` so later URL assembly does not fail silently.
|
||||
- 內部呼叫: `fail()`。 / `fail()`.
|
||||
|
||||
## 5. `normalizeBetaFlag(value = 'false')`
|
||||
|
||||
- 來源位置: `src/index.js:34-40`
|
||||
- 完整簽名: `function normalizeBetaFlag(value = 'false')`
|
||||
- 行為分析: 將空值或字串 `null` 標準化成 `'false'`;其他值則轉成字串後回傳。這讓後續 beta 判斷只處理字串。 / It normalizes empty values or the string `null` to `'false'`; all other values are stringified and returned. This keeps later beta checks string-based.
|
||||
- 建議摘要: 將 beta 旗標標準化成字串。 / Normalize the beta flag to a string.
|
||||
- 參數註解:
|
||||
- `value`: 來源值,預設為 `'false'`。 / Source value, defaulting to `'false'`.
|
||||
- 備註與使用情境: 當 runner/secret 可能傳入空字串、`null` 或布林字面值時,這個函式可避免型別分歧。 / Useful when runner or secret inputs may arrive as empty strings, `null`, or boolean-like values.
|
||||
- 內部呼叫: 無。 / None.
|
||||
|
||||
## 6. `writeOutput(version)`
|
||||
|
||||
- 來源位置: `src/index.js:42-52`
|
||||
- 完整簽名: `function writeOutput(version)`
|
||||
- 行為分析: 組出 `version=...` 這一行;若 `GITHUB_OUTPUT` 存在就附加到檔案,否則直接寫到 `stdout`。輸出格式是 action contract 的一部分,這裡僅做路徑分流,不改內容。 / It builds a `version=...` line; if `GITHUB_OUTPUT` exists it appends to that file, otherwise it writes directly to `stdout`. The output format is part of the action contract; this function only chooses the destination and does not alter the payload.
|
||||
- 建議摘要: 將版本號寫入 GitHub/Gitea action output。 / Write the version to the action output.
|
||||
- 參數註解:
|
||||
- `version`: 要輸出的版本字串。 / Version string to emit.
|
||||
- 備註與使用情境: 在本 action 結尾輸出最終版本,讓下游 workflow 可直接讀取 `version` output。 / Use it at the end of the action so downstream workflows can consume the `version` output.
|
||||
- 內部呼叫: 無;但依賴 `fs.appendFileSync()`、`process.env.GITHUB_OUTPUT` 與 `process.stdout.write()`。 / None; it depends on `fs.appendFileSync()`, `process.env.GITHUB_OUTPUT`, and `process.stdout.write()`.
|
||||
|
||||
## 7. `parseVersionParts(version)`
|
||||
|
||||
- 來源位置: `src/index.js:54-61`
|
||||
- 完整簽名: `function parseVersionParts(version)`
|
||||
- 行為分析: 將版本字串以 `.` 切開,逐段用十進位整數解析;無法解析的段落會變成 `0`。這是保守的數字化處理,方便後續比較與遞增。 / It splits a version string on `.`, parses each part as a base-10 integer, and turns non-numeric parts into `0`. This is conservative normalization for later comparison and incrementing.
|
||||
- 建議摘要: 將版本字串拆成數字陣列。 / Split a version string into numeric parts.
|
||||
- 參數註解:
|
||||
- `version`: 例如 `1.2.3` 或 `v1.2.3` 經前置處理後的純版本字串。 / A version string such as `1.2.3`, usually already stripped of any leading `v`.
|
||||
- 備註與使用情境: `stableVersionFromTag()` 與 `nextReleaseVersion()` 都依賴它來統一版本比較基礎。 / `stableVersionFromTag()` and `nextReleaseVersion()` both rely on it to normalize version math.
|
||||
- 內部呼叫: 無。 / None.
|
||||
|
||||
## 8. `compareVersionParts(left, right)`
|
||||
|
||||
- 來源位置: `src/index.js:63-76`
|
||||
- 完整簽名: `function compareVersionParts(left, right)`
|
||||
- 行為分析: 依序比較兩個數字陣列,遇到第一個不同的欄位就回傳差值;若全相同則回傳 `0`。這是典型的版本排序 comparator。 / It compares two numeric arrays element by element, returning the first non-zero difference, or `0` if all parts match. This is a standard version-sorting comparator.
|
||||
- 建議摘要: 比較兩組版本分段大小。 / Compare two version-part arrays.
|
||||
- 參數註解:
|
||||
- `left`: 左側版本分段。 / Left-side version parts.
|
||||
- `right`: 右側版本分段。 / Right-side version parts.
|
||||
- 備註與使用情境: 在 `latestStableVersion()` 排序 release 版本時使用。 / Used by `latestStableVersion()` when sorting releases.
|
||||
- 內部呼叫: 無。 / None.
|
||||
|
||||
## 9. `stableVersionFromTag(tagName)`
|
||||
|
||||
- 來源位置: `src/index.js:78-89`
|
||||
- 完整簽名: `function stableVersionFromTag(tagName)`
|
||||
- 行為分析: 排除非字串、含 `-beta.` 的 tag,然後允許 `v1.2.3` 或 `1.2.3` 這類純數字版本,最後回傳數字陣列;不符合者回傳 `null`。這是在提取 stable release。 / It rejects non-strings and tags containing `-beta.`, then accepts pure numeric versions like `v1.2.3` or `1.2.3`, returning an array of numbers; anything else returns `null`. This extracts stable releases only.
|
||||
- 建議摘要: 從 tag 名稱抽出穩定版版本。 / Extract a stable version from a tag name.
|
||||
- 參數註解:
|
||||
- `tagName`: release 的 `tag_name`。 / Release `tag_name`.
|
||||
- 備註與使用情境: 當 release 清單混有 beta tag 與正式 tag 時,用它可以避免 beta 參與最新穩定版計算。 / Useful when a release list mixes beta and stable tags, so beta tags do not affect the stable baseline.
|
||||
- 內部呼叫: `parseVersionParts()`。 / `parseVersionParts()`.
|
||||
|
||||
## 10. `latestStableVersion(releaseJson)`
|
||||
|
||||
- 來源位置: `src/index.js:91-107`
|
||||
- 完整簽名: `function latestStableVersion(releaseJson)`
|
||||
- 行為分析: 若輸入不是非空陣列就回傳 `0.0.0`;否則先挑出所有穩定版 tag,再用 `compareVersionParts()` 排序,取最後一筆組回 `x.y.z`。這會忽略 beta tag,也會把不足三段的版本以缺省 0 補齊。 / It returns `0.0.0` when the input is not a non-empty array; otherwise it filters stable tags, sorts them with `compareVersionParts()`, and rebuilds the last one as `x.y.z`. Beta tags are ignored, and missing third parts are padded with `0`.
|
||||
- 建議摘要: 找出最新的正式版版本號。 / Find the latest stable release version.
|
||||
- 參數註解:
|
||||
- `releaseJson`: release API 回傳的陣列。 / Array returned by the release API.
|
||||
- 備註與使用情境: 在計算下一版時作為 base version,確保 beta 只建立在最新正式版之上。 / Used as the base version for next-release calculation so beta builds rest on the latest stable release.
|
||||
- 內部呼叫: `stableVersionFromTag()`、`compareVersionParts()`。 / `stableVersionFromTag()` and `compareVersionParts()`.
|
||||
|
||||
## 11. `nextReleaseVersion(latestVersion)`
|
||||
|
||||
- 來源位置: `src/index.js:109-127`
|
||||
- 完整簽名: `function nextReleaseVersion(latestVersion)`
|
||||
- 行為分析: 將版本拆成 major/minor/patch 後只先遞增 patch;若 patch 到 10 就進位到 minor,minor 到 10 再進位到 major。這是專案自訂的十進位進位規則,不是一般 npm semver 的語意。 / It splits a version into major/minor/patch, increments patch first, then carries into minor at 10 and into major at 10. This is a project-specific decimal carry rule, not standard npm semver behavior.
|
||||
- 建議摘要: 計算下一個正式版版本號。 / Compute the next stable release version.
|
||||
- 參數註解:
|
||||
- `latestVersion`: 目前最新正式版,例如 `1.2.9`。 / Current stable version, for example `1.2.9`.
|
||||
- 備註與使用情境: 當 release 進入下一版時,以這個函式產生候選正式版。 / Use it to derive the candidate stable version for the next release.
|
||||
- 內部呼叫: `parseVersionParts()`。 / `parseVersionParts()`.
|
||||
|
||||
## 12. `nextBetaNumber(releaseJson, version)`
|
||||
|
||||
- 來源位置: `src/index.js:129-146`
|
||||
- 完整簽名: `function nextBetaNumber(releaseJson, version)`
|
||||
- 行為分析: 在 release 清單中找出符合 `v{version}-beta.N` 的 tag,取最大 `N` 再加 1;若找不到就從 1 開始。這只對指定版本前綴生效。 / It scans the release list for tags matching `v{version}-beta.N`, takes the maximum `N`, and adds one; if none are found, it starts at 1. It only applies to the specified version prefix.
|
||||
- 建議摘要: 取得下一個 beta 序號。 / Get the next beta sequence number.
|
||||
- 參數註解:
|
||||
- `releaseJson`: release API 回傳的陣列。 / Array returned by the release API.
|
||||
- `version`: 目標正式版版本字串,例如 `1.2.4`。 / Target stable version string, such as `1.2.4`.
|
||||
- 備註與使用情境: 當要發行同一個正式版的多個 beta 時,這個函式可確保序號遞增。 / Use it when multiple beta builds are published for the same stable target so the suffix increments correctly.
|
||||
- 內部呼叫: 無。 / None.
|
||||
|
||||
## 13. `calculateVersion(releaseJson, isBeta)`
|
||||
|
||||
- 來源位置: `src/index.js:148-164`
|
||||
- 完整簽名: `function calculateVersion(releaseJson, isBeta)`
|
||||
- 行為分析: 先處理空 release 清單的起始值,再依 `isBeta` 決定回傳正式版或 beta 版的 `[latestTag, newVersion]`。beta 模式會以最新正式版為 base,再加上下一個 beta 序號。 / It first handles the empty-release baseline, then returns either a stable or beta `[latestTag, newVersion]` tuple depending on `isBeta`. In beta mode it uses the latest stable release as the base and appends the next beta number.
|
||||
- 建議摘要: 計算最新版與下一版。 / Calculate the latest and next version.
|
||||
- 參數註解:
|
||||
- `releaseJson`: release 清單。 / Release list.
|
||||
- `isBeta`: 是否輸出 beta 版本,期望值為 `'true'` 或其他字串。 / Whether to emit a beta version; expected values are `'true'` or another string.
|
||||
- 備註與使用情境: 這是 action 的核心版本決策點,`main()` 只負責組裝輸入與輸出結果。 / This is the action’s core versioning decision point; `main()` only gathers inputs and emits the result.
|
||||
- 內部呼叫: `latestStableVersion()`、`nextReleaseVersion()`、`nextBetaNumber()`。 / `latestStableVersion()`, `nextReleaseVersion()`, and `nextBetaNumber()`.
|
||||
|
||||
## 14. `requestJson(url, token)`
|
||||
|
||||
- 來源位置: `src/index.js:166-209`
|
||||
- 完整簽名: `function requestJson(url, token)`
|
||||
- 行為分析: 依 URL 協定選擇 `http` 或 `https`,以 GET 發送請求,必要時加上 token header,收集回應後嘗試解析 JSON。非 2xx 會丟錯,空 body 會回傳空字串。 / It picks `http` or `https` from the URL protocol, sends a GET request, adds a token header when needed, collects the response, and tries to parse JSON. Non-2xx responses throw, and an empty body resolves to an empty string.
|
||||
- 建議摘要: 以 Promise 包裝的 JSON HTTP 請求。 / Promise-wrapped JSON HTTP request.
|
||||
- 參數註解:
|
||||
- `url`: `URL` 物件,指向 release API。 / `URL` object pointing to the release API.
|
||||
- `token`: 存取 token,可為空。 / Access token, optional.
|
||||
- 備註與使用情境: 這個函式負責所有 release API 取資料的底層 I/O,錯誤訊息已針對 API 回應格式做保守處理。 / This function handles the low-level I/O for all release API fetches, with conservative error handling for API responses.
|
||||
- 內部呼叫: 無;但使用 `http.request()`、`https.request()` 與 `JSON.parse()`。 / None; it uses `http.request()`, `https.request()`, and `JSON.parse()`.
|
||||
|
||||
## 15. `fetchReleases(baseUrl, repository, token)`
|
||||
|
||||
- 來源位置: `src/index.js:211-241`
|
||||
- 完整簽名: `async function fetchReleases(baseUrl, repository, token)`
|
||||
- 行為分析: 以固定頁大小分頁呼叫 release API,直到回應為空、`null` 或最後一頁資料少於 `RELEASES_PER_PAGE` 為止,並把所有頁面串成一個陣列。這是典型的保守型 pagination 收集。 / It pages through the release API with a fixed page size until the response is empty, `null`, or shorter than `RELEASES_PER_PAGE`, concatenating all pages into one array. This is a conservative pagination collector.
|
||||
- 建議摘要: 取得所有 release 頁面資料。 / Fetch all paginated release data.
|
||||
- 參數註解:
|
||||
- `baseUrl`: Gitea server base URL。 / Gitea server base URL.
|
||||
- `repository`: `owner/repo` 格式的 repository 名稱。 / Repository name in `owner/repo` form.
|
||||
- `token`: API 存取 token。 / API access token.
|
||||
- 備註與使用情境: 當 repository release 數量超過單頁上限時,這個函式確保版本計算看到完整資料。 / Use it when release counts exceed one page so version calculation still sees the full dataset.
|
||||
- 內部呼叫: `requestJson()`、`info()`。 / `requestJson()` and `info()`.
|
||||
|
||||
## 16. `main()`
|
||||
|
||||
- 來源位置: `src/index.js:243-267`
|
||||
- 完整簽名: `async function main()`
|
||||
- 行為分析: 依序做參數檢查、組出 release URL、抓取 release、計算版本、寫出 output。它同時負責 log 分段與 env 讀取,是整個 action 的執行入口。 / It performs parameter checks, builds the release URL, fetches releases, calculates the version, and writes the output. It also manages stage logging and environment reads, making it the action’s execution entry point.
|
||||
- 建議摘要: 執行版本計算流程。 / Run the version calculation flow.
|
||||
- 參數註解: 無。 / None.
|
||||
- 備註與使用情境: 直接執行 `node src/index.js` 時會走這個函式;在 action 容器內也是主要入口。 / This runs when executing `node src/index.js` directly and is also the main entry inside the action container.
|
||||
- 內部呼叫: `section()`、`requireEnv()`、`normalizeBetaFlag()`、`info()`、`fetchReleases()`、`calculateVersion()`、`writeOutput()`。 / `section()`, `requireEnv()`, `normalizeBetaFlag()`, `info()`, `fetchReleases()`, `calculateVersion()`, and `writeOutput()`.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -1,73 +1,139 @@
|
||||
# --------------------------------------------------
|
||||
# 用途:定義 CI 工作流程,處理 pull request 的版本發佈與測試。
|
||||
# 更新日期:2026/07/11 17:44:33(Asia/Taipei)
|
||||
# 更新日期:2026/07/11 21:08:44(Asia/Taipei)
|
||||
# --------------------------------------------------
|
||||
|
||||
# 工作流程名稱。
|
||||
name: CI
|
||||
|
||||
# 定義觸發條件。
|
||||
on:
|
||||
# 只在 pull_request 事件上執行,避免其他事件重複觸發。
|
||||
pull_request:
|
||||
# 限定 PR 目標分支為 master 與 develop。
|
||||
branches:
|
||||
# 正式分支。
|
||||
- master
|
||||
# 開發分支。
|
||||
- develop
|
||||
# 只在 PR 建立與同步更新時執行。
|
||||
types: [opened, synchronize]
|
||||
|
||||
# 定義各個 job。
|
||||
jobs:
|
||||
# build job 先建立 release,並計算基礎版本資訊。
|
||||
build:
|
||||
# 顯示名稱。
|
||||
name: 1. BUILD
|
||||
# 使用 Ubuntu runner。
|
||||
runs-on: ubuntu
|
||||
# 供此 job 與後續輸出共用的環境變數。
|
||||
env:
|
||||
# 預設 beta 版版本字串,使用 run_number 保持唯一。
|
||||
VERSION: "0.0.0-beta.${{ gitea.run_number }}"
|
||||
# 只要 PR 的 base branch 是 develop,就視為 beta 流程。
|
||||
IS_BETA: ${{ gitea.base_ref == 'develop' }}
|
||||
# 將環境變數輸出到下游 job。
|
||||
outputs:
|
||||
# 提供 test job 使用的版本號。
|
||||
version: ${{ env.VERSION }}
|
||||
# 提供 test 與 result job 使用的 beta 判斷結果。
|
||||
is_beta: ${{ env.IS_BETA }}
|
||||
# 定義 build job 的步驟。
|
||||
steps:
|
||||
# 在 Gitea 上建立 release,並讓 tag 與版本對齊。
|
||||
- name: Publishing Release
|
||||
# 使用外部 release action,版本由倉庫變數控制。
|
||||
uses: akkuman/gitea-release-action@${{ vars.ACTION_GITEA_RELEASE_VERSION }}
|
||||
with:
|
||||
# release 名稱包含倉庫名稱與版本號。
|
||||
name: "${{ gitea.event.repository.name }} v${{ env.VERSION }}"
|
||||
# tag 名稱固定使用 v 前綴。
|
||||
tag_name: "v${{ env.VERSION }}"
|
||||
# 對應到目前提交。
|
||||
target_commitish: ${{ gitea.sha }}
|
||||
# beta 分支建立 prerelease,正式分支則不是。
|
||||
prerelease: ${{ env.IS_BETA }}
|
||||
|
||||
# test job 以 build 輸出為基礎執行版本計算與 beta 專屬檢查。
|
||||
test:
|
||||
# 顯示名稱。
|
||||
name: 2. TEST
|
||||
# 使用 Ubuntu runner。
|
||||
runs-on: ubuntu
|
||||
# 必須等 build 完成,才能取得版本資訊。
|
||||
needs: [build]
|
||||
# 將 build 的輸出轉成此 job 的環境變數。
|
||||
env:
|
||||
# 取用 build job 輸出的版本。
|
||||
VERSION: ${{ needs.build.outputs.version }}
|
||||
# 取用 build job 輸出的 beta 狀態。
|
||||
IS_BETA: ${{ needs.build.outputs.is_beta }}
|
||||
# 將 calculate-version 的結果往下輸出。
|
||||
outputs:
|
||||
# 最終版本號由 calculate-version step 產生。
|
||||
version: ${{ steps.calculate-version.outputs.version }}
|
||||
# 定義 test job 的步驟。
|
||||
steps:
|
||||
# 執行 calculate-version action 取得版本號。
|
||||
- name: Run Calculate Version
|
||||
# 用 commit 對應版本的動態 action 版本。
|
||||
id: calculate-version
|
||||
uses: https://gitea.jsc.idv.tw/actions/calculate-version@v${{ env.VERSION }}
|
||||
with:
|
||||
# 將 beta 狀態轉成布林值傳入 action。
|
||||
is_beta: ${{ env.IS_BETA == "true" }}
|
||||
# beta 流程才需要安裝 LLM CLI。
|
||||
- name: Setup LLM CLI
|
||||
# 動態指定 setup action 版本。
|
||||
uses: https://gitea.jsc.idv.tw/actions/setup-${{ vars.ACTION_SETUP_LLM_CLI }}
|
||||
# 只有 beta 分支才執行。
|
||||
if: ${{ env.IS_BETA == 'true' }}
|
||||
with:
|
||||
# 提供 OAuth 憑證給 CLI 安裝流程。
|
||||
oauth: ${{ secrets.LLM_OAUTH }}
|
||||
# beta 流程才執行 AI Code Review。
|
||||
- name: Run AI Code Review
|
||||
# 用倉庫變數指定 action 版本。
|
||||
uses: https://gitea.jsc.idv.tw/actions/ai-code-review@${{ vars.ACTION_AI_CODE_REVIEW_VERSION }}
|
||||
# 步驟 id 供必要時引用輸出。
|
||||
id: ai-code-review
|
||||
# 只有 beta 分支才執行。
|
||||
if: ${{ env.IS_BETA == 'true' }}
|
||||
with:
|
||||
# 提供 token 給 AI review 流程。
|
||||
token: ${{ secrets.TOKEN }}
|
||||
# 指定模型名稱。
|
||||
model: ${{ vars.LLM_NAME }}
|
||||
|
||||
# result job 只在非 beta 流程時,根據 test 的結果再發佈一次 release。
|
||||
result:
|
||||
# 顯示名稱。
|
||||
name: 3. RESULT
|
||||
# 使用 Ubuntu runner。
|
||||
runs-on: ubuntu
|
||||
# 必須等待 build 與 test 都完成。
|
||||
needs: [build, test]
|
||||
# 只有正式版才會進到這個 job。
|
||||
if: ${{ needs.build.outputs.is_beta == 'false' }}
|
||||
# 重新帶入版本與 beta 狀態,供 release 步驟使用。
|
||||
env:
|
||||
# 取用 test job 算出的版本號。
|
||||
VERSION: ${{ needs.test.outputs.version }}
|
||||
# 取用 build job 的 beta 狀態。
|
||||
IS_BETA: ${{ needs.build.outputs.is_beta }}
|
||||
# 定義 result job 的步驟。
|
||||
steps:
|
||||
# 再次發佈 release,作為正式結果。
|
||||
- name: Publishing Release
|
||||
# 與 build job 使用相同的 release action 與版本來源。
|
||||
uses: akkuman/gitea-release-action@${{ vars.ACTION_GITEA_RELEASE_VERSION }}
|
||||
with:
|
||||
# release 名稱包含倉庫名稱與最終版本號。
|
||||
name: "${{ gitea.event.repository.name }} v${{ env.VERSION }}"
|
||||
# 使用與 build 相同的 tag 命名方式。
|
||||
tag_name: "v${{ env.VERSION }}"
|
||||
# 指向目前提交。
|
||||
target_commitish: ${{ gitea.sha }}
|
||||
# 這裡再次判斷是否為 beta,正式版時會是 false。
|
||||
prerelease: ${{ env.IS_BETA == "true" }}
|
||||
|
||||
@@ -1,28 +1,48 @@
|
||||
# --------------------------------------------------
|
||||
# 用途:定義 CD 工作流程,於 master push 後部署並顯示相關 tag。
|
||||
# 更新日期:2026/07/11 17:44:33(Asia/Taipei)
|
||||
# 用途:定義 CD 工作流程,於 master push 後找出對應 tag 並輸出結果。
|
||||
# 更新日期:2026/07/11 21:08:44(Asia/Taipei)
|
||||
# --------------------------------------------------
|
||||
|
||||
# 工作流程名稱。
|
||||
name: CD
|
||||
|
||||
# 定義觸發條件。
|
||||
on:
|
||||
# 只在 push 事件上執行。
|
||||
push:
|
||||
# 限定 master 分支,避免其他分支觸發部署流程。
|
||||
branches:
|
||||
# 正式分支。
|
||||
- master
|
||||
|
||||
# 定義部署工作。
|
||||
jobs:
|
||||
# deploy job:檢出原始碼並找出 commit 對應的 tag。
|
||||
deploy:
|
||||
# 顯示名稱。
|
||||
name: DEPLOY
|
||||
# 使用 Ubuntu runner。
|
||||
runs-on: ubuntu
|
||||
# 由 push 事件中的 commits 取出要查找的 commit SHA。
|
||||
env:
|
||||
# 目前流程預設取第二筆 commit 的 id;此索引是否永遠存在需人工確認。
|
||||
COMMIT_SHA: ${{ gitea.event.commits[1].id }}
|
||||
# 定義 deploy job 的步驟。
|
||||
steps:
|
||||
# 先檢出完整原始碼與 tag 歷史,讓後續可以查詢 tag。
|
||||
- name: Source Code Checkout
|
||||
# 使用 checkout action,版本由倉庫變數控制。
|
||||
uses: actions/checkout@${{ vars.ACTION_CHECKOUT_VERSION }}
|
||||
with:
|
||||
# 取得完整歷史,避免 tag 查詢因淺層 clone 而失敗。
|
||||
fetch-depth: 0
|
||||
# 根據 COMMIT_SHA 找出包含該提交的最新 tag。
|
||||
- name: Get Commit Tag
|
||||
# 將查到的 tag 寫入 Gitea output。
|
||||
id: commit
|
||||
run: >-
|
||||
echo "tag=$(git for-each-ref --sort=-refname --format='%(refname:strip=2)' refs/tags --contains ${{ env.COMMIT_SHA }} | head -n 1)" >> $GITEA_OUTPUT
|
||||
# 將查到的 tag 輸出到日誌,方便人工確認。
|
||||
- name: Show Tag
|
||||
run: >-
|
||||
echo "[DEPLOY][INF][$(TZ='Asia/Taipei' date +'%Y/%m/%d %H:%M:%S')]: ${{ steps.commit.outputs.tag }}"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 工作流程說明
|
||||
|
||||
以下內容整理 `.gitea/workflows/` 目前的工作流程與用途,作為後續覆蓋 `.gitea/workflows/readme.md` 的說明文件。
|
||||
以下內容整理 `.gitea/workflows/` 目前的工作流程與用途,作為專案內工作流程的說明文件。
|
||||
|
||||
## 總覽
|
||||
|
||||
|
||||
+9
-2
@@ -1,15 +1,22 @@
|
||||
# --------------------------------------------------
|
||||
# 用途:定義 calculate-version action 的 Docker 執行環境。
|
||||
# 更新日期:2026/07/11 17:44:33(Asia/Taipei)
|
||||
# 用途:定義 calculate-version action 的 Docker 執行環境與啟動入口。
|
||||
# 更新日期:2026/07/11 21:08:44(Asia/Taipei)
|
||||
# --------------------------------------------------
|
||||
|
||||
# 使用 Node LTS Alpine 映像,兼顧 Node 執行環境與較小的映像體積。
|
||||
FROM node:lts-alpine
|
||||
|
||||
# 將工作目錄切換到 /action,後續複製與執行都以此為基準。
|
||||
WORKDIR /action
|
||||
|
||||
# 複製 action 的主程式來源到容器內,供 entrypoint 執行。
|
||||
COPY src/ /action/src/
|
||||
|
||||
# 複製 entrypoint 腳本到容器內,作為啟動入口。
|
||||
COPY entrypoint.sh /action/entrypoint.sh
|
||||
|
||||
# 賦予 entrypoint 可執行權限,否則容器啟動時無法直接執行。
|
||||
RUN chmod +x /action/entrypoint.sh
|
||||
|
||||
# 指定容器啟動時直接執行 entrypoint 腳本。
|
||||
ENTRYPOINT ["/action/entrypoint.sh"]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# calculate-version
|
||||
|
||||
更新時間:2026/07/11 17:53:32(Asia/Taipei)
|
||||
更新時間:2026/07/11 21:08:44(Asia/Taipei)
|
||||
|
||||
這個專案是一個 Gitea Docker action,會讀取 repository 的 release 清單,計算下一個正式版或 beta 版本號,並將結果輸出成 action output。
|
||||
這個專案是一個以 Node.js 實作的 Gitea Docker action,負責從 release 清單計算下一個正式版或 beta 版本,並把結果輸出給後續工作流程使用。
|
||||
|
||||
## 專案列表
|
||||
|
||||
@@ -10,19 +10,19 @@
|
||||
|
||||
| 專案名稱 | 專案描述 |
|
||||
| --- | --- |
|
||||
| [calculate-version](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/ai-review-resolve/develop-20260711-150530/) | 這是一個以 Node.js 實作的 Gitea Docker action,提供 release 擷取、版本解析、beta 推算與 action 主流程輸出。 |
|
||||
| [calculate-version](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/develop/) | 這是一個以 Node.js 實作的 Gitea Docker action,負責取得 release 資料、計算下一個版本號,並輸出給 workflow 或 action 使用。 |
|
||||
|
||||
### 參考專案表
|
||||
|
||||
| 專案名稱 | 參考專案列表 |
|
||||
| --- | --- |
|
||||
| [calculate-version](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/ai-review-resolve/develop-20260711-150530/) | 無 |
|
||||
| [calculate-version](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/develop/) | 無 |
|
||||
|
||||
### NuGet 套件表
|
||||
|
||||
| 專案名稱 | NuGet 套件列表 |
|
||||
| --- | --- |
|
||||
| [calculate-version](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/ai-review-resolve/develop-20260711-150530/) | 無 |
|
||||
| [calculate-version](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/develop/) | 無 |
|
||||
|
||||
## 功能列表
|
||||
|
||||
@@ -30,21 +30,21 @@
|
||||
|
||||
| 功能名稱 | 功能描述 |
|
||||
| --- | --- |
|
||||
| [calculate-version.normalizeBetaFlag](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/ai-review-resolve/develop-20260711-150530/src/index.js#L72) | [把空值或 `null` 正規化成 beta 旗標字串](#calculateversionnormalizebetaflag) |
|
||||
| [calculate-version.parseVersionParts](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/ai-review-resolve/develop-20260711-150530/src/index.js#L107) | [把版本字串拆成數字片段](#calculateversionparseversionparts) |
|
||||
| [calculate-version.compareVersionParts](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/ai-review-resolve/develop-20260711-150530/src/index.js#L125) | [逐段比較版本片段,供排序使用](#calculateversioncompareversionparts) |
|
||||
| [calculate-version.stableVersionFromTag](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/ai-review-resolve/develop-20260711-150530/src/index.js#L148) | [解析穩定版 tag 為版本片段](#calculateversionstableversionfromtag) |
|
||||
| [calculate-version.latestStableVersion](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/ai-review-resolve/develop-20260711-150530/src/index.js#L169) | [從 release 清單找出最新穩定版](#calculateversionlateststableversion) |
|
||||
| [calculate-version.nextReleaseVersion](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/ai-review-resolve/develop-20260711-150530/src/index.js#L195) | [將正式版版本號遞增一版](#calculateversionnextreleaseversion) |
|
||||
| [calculate-version.nextBetaNumber](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/ai-review-resolve/develop-20260711-150530/src/index.js#L224) | [推算下一個 beta 編號](#calculateversionnextbetanumber) |
|
||||
| [calculate-version.calculateVersion](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/ai-review-resolve/develop-20260711-150530/src/index.js#L252) | [回傳目前最新版本與下一個版本](#calculateversioncalculateversion) |
|
||||
| [calculate-version.fetchReleases](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/ai-review-resolve/develop-20260711-150530/src/index.js#L334) | [分頁抓取 repository release 清單](#calculateversionfetchreleases) |
|
||||
| [calculate-version.main](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/ai-review-resolve/develop-20260711-150530/src/index.js#L373) | [執行 action 主流程並輸出結果](#calculateversionmain) |
|
||||
| [calculate-version.normalizeBetaFlag](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/develop/src/index.js#L95) | [將 beta 輸入正規化成字串 `false`](#calculateversionnormalizebetaflag) |
|
||||
| [calculate-version.parseVersionParts](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/develop/src/index.js#L130) | [將版本字串拆成可比較的數字片段](#calculateversionparseversionparts) |
|
||||
| [calculate-version.compareVersionParts](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/develop/src/index.js#L148) | [比較兩組版本片段的大小](#calculateversioncompareversionparts) |
|
||||
| [calculate-version.stableVersionFromTag](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/develop/src/index.js#L171) | [從 tag 解析穩定版版本片段](#calculateversionstableversionfromtag) |
|
||||
| [calculate-version.latestStableVersion](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/develop/src/index.js#L192) | [找出 release 清單中的最新穩定版](#calculateversionlateststableversion) |
|
||||
| [calculate-version.nextReleaseVersion](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/develop/src/index.js#L218) | [推算下一個正式版版本號](#calculateversionnextreleaseversion) |
|
||||
| [calculate-version.nextBetaNumber](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/develop/src/index.js#L247) | [推算下一個 beta 編號](#calculateversionnextbetanumber) |
|
||||
| [calculate-version.calculateVersion](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/develop/src/index.js#L275) | [依 release 資料與 beta 旗標計算目前版本與下一版](#calculateversioncalculateversion) |
|
||||
| [calculate-version.fetchReleases](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/develop/src/index.js#L357) | [分頁抓取 repository 的 release 清單](#calculateversionfetchreleases) |
|
||||
| [calculate-version.main](https://gitea.jsc.idv.tw/actions/calculate-version/src/branch/develop/src/index.js#L396) | [執行 action 主流程並輸出版本結果](#calculateversionmain) |
|
||||
|
||||
## 使用範例
|
||||
|
||||
### <a id="calculateversionnormalizebetaflag"></a>calculate-version.normalizeBetaFlag
|
||||
把空值、`null` 或未定義值正規化成 `false`,讓後續版本判斷只處理字串。
|
||||
將 action 輸入或環境變數轉成固定的字串旗標,避免後續流程混用空值與字串。
|
||||
|
||||
```js
|
||||
const { normalizeBetaFlag } = require('./src/index.js');
|
||||
@@ -53,7 +53,7 @@ const isBeta = normalizeBetaFlag(process.env.IS_BETA);
|
||||
```
|
||||
|
||||
### <a id="calculateversionparseversionparts"></a>calculate-version.parseVersionParts
|
||||
將版本字串拆成數字陣列,非數字片段會保守視為 `0`。
|
||||
將版本字串拆成數字陣列,適合後續比較或進位運算。
|
||||
|
||||
```js
|
||||
const { parseVersionParts } = require('./src/index.js');
|
||||
@@ -62,7 +62,7 @@ const parts = parseVersionParts('1.2.3');
|
||||
```
|
||||
|
||||
### <a id="calculateversioncompareversionparts"></a>calculate-version.compareVersionParts
|
||||
逐段比較兩組版本片段,適合搭配 `Array.prototype.sort()` 使用。
|
||||
比較兩組版本片段,常用於排序 release 版本。
|
||||
|
||||
```js
|
||||
const { compareVersionParts } = require('./src/index.js');
|
||||
@@ -71,7 +71,7 @@ const sorted = [[1, 2, 10], [1, 2, 3]].sort(compareVersionParts);
|
||||
```
|
||||
|
||||
### <a id="calculateversionstableversionfromtag"></a>calculate-version.stableVersionFromTag
|
||||
從 tag 名稱擷取穩定版版本資訊,像 `v1.2.3` 會被解析成版本片段。
|
||||
從 tag 名稱過濾出穩定版版本,忽略 beta 與不合法格式。
|
||||
|
||||
```js
|
||||
const { stableVersionFromTag } = require('./src/index.js');
|
||||
@@ -80,7 +80,7 @@ const parts = stableVersionFromTag('v1.2.3');
|
||||
```
|
||||
|
||||
### <a id="calculateversionlateststableversion"></a>calculate-version.latestStableVersion
|
||||
從 release 清單中找出最新的穩定版版本號,找不到時回傳 `0.0.0`。
|
||||
從 release 清單中找出最新穩定版,若沒有可用資料就回傳 `0.0.0`。
|
||||
|
||||
```js
|
||||
const { latestStableVersion } = require('./src/index.js');
|
||||
@@ -93,7 +93,7 @@ const latest = latestStableVersion([
|
||||
```
|
||||
|
||||
### <a id="calculateversionnextreleaseversion"></a>calculate-version.nextReleaseVersion
|
||||
將正式版版本號遞增一版,`patch` 與 `minor` 都會以 10 為進位界線。
|
||||
將正式版版本號往下一版遞增,patch 會以 10 為進位界線。
|
||||
|
||||
```js
|
||||
const { nextReleaseVersion } = require('./src/index.js');
|
||||
@@ -114,7 +114,7 @@ const betaNumber = nextBetaNumber([
|
||||
```
|
||||
|
||||
### <a id="calculateversioncalculateversion"></a>calculate-version.calculateVersion
|
||||
回傳目前最新版本與下一個版本,beta 模式時會產生對應的 `-beta.N` 結果。
|
||||
依 release 資料與 beta 狀態回傳 `[latestVersion, nextVersion]`。
|
||||
|
||||
```js
|
||||
const { calculateVersion } = require('./src/index.js');
|
||||
@@ -126,7 +126,7 @@ const [latest, nextVersion] = calculateVersion([
|
||||
```
|
||||
|
||||
### <a id="calculateversionfetchreleases"></a>calculate-version.fetchReleases
|
||||
分頁抓取 repository 的 release 清單,直到 API 回傳空資料或最後一頁不足頁面上限。
|
||||
分頁抓取 repository 的 release 清單,直到 API 沒有新資料為止。
|
||||
|
||||
```js
|
||||
const { fetchReleases } = require('./src/index.js');
|
||||
@@ -139,7 +139,7 @@ const { fetchReleases } = require('./src/index.js');
|
||||
```
|
||||
|
||||
### <a id="calculateversionmain"></a>calculate-version.main
|
||||
執行 action 主流程,會讀取環境變數、抓取 release、計算版本並輸出結果。
|
||||
執行 action 主流程,通常由 Gitea action runtime 觸發。
|
||||
|
||||
```js
|
||||
const { main } = require('./src/index.js');
|
||||
|
||||
+28
-1
@@ -1,27 +1,54 @@
|
||||
# --------------------------------------------------
|
||||
# 用途:宣告 Calculate Version action 的輸入、輸出與 Docker 執行方式。
|
||||
# 更新日期:2026/07/11 17:44:33(Asia/Taipei)
|
||||
# 更新日期:2026/07/11 21:08:44(Asia/Taipei)
|
||||
# --------------------------------------------------
|
||||
|
||||
# action 的顯示名稱。
|
||||
name: "Calculate Version"
|
||||
|
||||
# action 的簡短描述。
|
||||
description: "計算版本號"
|
||||
|
||||
# action 的作者資訊。
|
||||
author: "Jeffery"
|
||||
|
||||
# 宣告可由呼叫端傳入的輸入參數。
|
||||
inputs:
|
||||
# 是否以 beta 模式計算版本,預設關閉。
|
||||
is_beta:
|
||||
# 參數說明文字。
|
||||
description: "是否為 beta 版本"
|
||||
# 未提供時預設為 false,讓一般流程走正式版邏輯。
|
||||
default: "false"
|
||||
# 用於讀取 release 資訊的 token,保留為可選輸入。
|
||||
runner_token:
|
||||
# 參數說明文字。
|
||||
description: "用於讀取 release 的 token"
|
||||
# 明確標示不是必填,呼叫端可依環境提供。
|
||||
required: false
|
||||
|
||||
# 宣告 action 會輸出的結果欄位。
|
||||
outputs:
|
||||
# 將計算後的版本號輸出給後續工作流程使用。
|
||||
version:
|
||||
# 輸出說明文字。
|
||||
description: "計算出的版本號"
|
||||
|
||||
# 指定此 action 以 Docker 模式執行。
|
||||
runs:
|
||||
# 透過 Docker image 啟動。
|
||||
using: "docker"
|
||||
# 使用同目錄下的 Dockerfile 建置映像。
|
||||
image: "Dockerfile"
|
||||
# 將 Gitea 與呼叫端輸入注入容器環境,供 entrypoint 與 Node 程式讀取。
|
||||
env:
|
||||
# Gitea 伺服器 URL,供程式組出 API 或資源路徑。
|
||||
GITEA_SERVER_URL: ${{ gitea.server_url }}
|
||||
# 目前倉庫識別資訊。
|
||||
GITEA_REPOSITORY: ${{ gitea.repository }}
|
||||
# Gitea token,供程式讀取受保護資源。
|
||||
GITEA_TOKEN: ${{ gitea.token }}
|
||||
# runner_token 的優先來源是輸入值,其次是 secrets.GITEA_TOKEN,再其次是 secrets.RUNNER_TOKEN。
|
||||
RUNNER_TOKEN: ${{ inputs.runner_token || secrets.GITEA_TOKEN || secrets.RUNNER_TOKEN }}
|
||||
# 將呼叫端的 beta 設定直接傳入容器。
|
||||
IS_BETA: ${{ inputs.is_beta }}
|
||||
|
||||
+4
-2
@@ -1,9 +1,11 @@
|
||||
#!/bin/sh
|
||||
# --------------------------------------------------
|
||||
# 用途:啟動 calculate-version action,將所有參數交給 Node 主程式。
|
||||
# 更新日期:2026/07/11 17:44:33(Asia/Taipei)
|
||||
# 用途:啟動 calculate-version action,並將所有參數直接轉交給 Node 主程式。
|
||||
# 更新日期:2026/07/11 21:08:44(Asia/Taipei)
|
||||
# --------------------------------------------------
|
||||
|
||||
# 啟用嚴格模式,讓未定義變數與任一命令失敗都能立即中止流程。
|
||||
set -eu
|
||||
|
||||
# 直接以 exec 取代 shell 行程,避免多一層 shell 包裝,並把所有參數原封不動傳給 Node。
|
||||
exec node /action/src/index.js "$@"
|
||||
|
||||
+30
-12
@@ -17,6 +17,34 @@ function section(title) {
|
||||
currentStage = title;
|
||||
}
|
||||
|
||||
/**
|
||||
* 產生統一格式的時間戳記字串。
|
||||
*
|
||||
* @returns {string} Asia/Taipei 時區格式化後的時間戳記。
|
||||
* @remarks
|
||||
* 由 `info()` 與錯誤輸出共用,避免不同輸出路徑各自拼出不同格式。
|
||||
*/
|
||||
function formatTimestamp() {
|
||||
return new Date()
|
||||
.toLocaleString('sv-SE', { timeZone: 'Asia/Taipei', hour12: false })
|
||||
.replace(/-/g, '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* 以統一格式組裝單行 log。
|
||||
*
|
||||
* @param {string} level 訊息等級。
|
||||
* @param {string} message 要輸出的訊息內容。
|
||||
* @returns {string} 已格式化完成且含換行的 log 字串。
|
||||
* @remarks
|
||||
* 讓一般資訊與錯誤訊息共用同一套前綴格式,降低未來調整格式時的維護成本。
|
||||
*/
|
||||
function formatLogLine(level, message) {
|
||||
const stagePrefix = currentStage ? `[${currentStage}]` : '';
|
||||
|
||||
return `${stagePrefix}[${level}][${formatTimestamp()}]: ${message}\n`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 以統一格式輸出資訊訊息。
|
||||
*
|
||||
@@ -25,12 +53,7 @@ function section(title) {
|
||||
* 會附加目前階段與 Asia/Taipei 時區時間戳記,適合用於流程進度與狀態輸出。
|
||||
*/
|
||||
function info(message) {
|
||||
const timestamp = new Date()
|
||||
.toLocaleString('sv-SE', { timeZone: 'Asia/Taipei', hour12: false })
|
||||
.replace(/-/g, '/');
|
||||
const stagePrefix = currentStage ? `[${currentStage}]` : '';
|
||||
|
||||
process.stdout.write(`${stagePrefix}[INF][${timestamp}]: ${message}\n`);
|
||||
process.stdout.write(formatLogLine('INF', message));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -398,12 +421,7 @@ async function main() {
|
||||
|
||||
if (require.main === module) {
|
||||
main().catch((error) => {
|
||||
const timestamp = new Date()
|
||||
.toLocaleString('sv-SE', { timeZone: 'Asia/Taipei', hour12: false })
|
||||
.replace(/-/g, '/');
|
||||
const stagePrefix = currentStage ? `[${currentStage}]` : '';
|
||||
|
||||
process.stderr.write(`${stagePrefix}[ERR][${timestamp}]: ${error.message}\n`);
|
||||
process.stderr.write(formatLogLine('ERR', error.message));
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
const assert = require('node:assert/strict');
|
||||
const { spawnSync } = require('node:child_process');
|
||||
const path = require('node:path');
|
||||
const test = require('node:test');
|
||||
|
||||
test('主流程失敗時會輸出階段前綴與錯誤碼', () => {
|
||||
const result = spawnSync(
|
||||
process.execPath,
|
||||
[path.join(__dirname, 'index.js')],
|
||||
{
|
||||
cwd: path.join(__dirname, '..'),
|
||||
env: {
|
||||
...process.env,
|
||||
GITEA_SERVER_URL: '',
|
||||
GITEA_REPOSITORY: 'owner/repo',
|
||||
RUNNER_TOKEN: 'token',
|
||||
IS_BETA: 'false',
|
||||
},
|
||||
encoding: 'utf8',
|
||||
},
|
||||
);
|
||||
|
||||
assert.equal(result.status, 1);
|
||||
assert.match(result.stderr, /^\[參數檢查\]\[ERR\]\[\d{4}\/\d{2}\/\d{2} /);
|
||||
assert.match(result.stderr, /GITEA_SERVER_URL 未設定/);
|
||||
});
|
||||
Reference in New Issue
Block a user