From cee5b2f67ff142bed4a856a129bbdf7103298359 Mon Sep 17 00:00:00 2001 From: Jeffery Date: Tue, 30 Jun 2026 12:41:17 +0800 Subject: [PATCH] =?UTF-8?q?docs(README):=20=E6=96=B0=E5=A2=9E=E5=B0=88?= =?UTF-8?q?=E6=A1=88=E8=AA=AA=E6=98=8E=E3=80=81=E8=BC=B8=E5=85=A5=E5=8F=83?= =?UTF-8?q?=E6=95=B8=E8=88=87=E4=BD=BF=E7=94=A8=E7=AF=84=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增根目錄 README,含行為總覽、action 輸入與環境變數、workflow 使用範例、 專案列表與各 function 的功能列表與使用範例(連結至 Gitea 來源行)。 Co-Authored-By: Claude Opus 4.8 (1M context) --- README.md | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..c229e66 --- /dev/null +++ b/README.md @@ -0,0 +1,207 @@ +# Release Cleanup + +> 更新時間:2026/06/30 12:02:55(台灣時區 Asia/Taipei) + +清理舊成品的 **Gitea / GitHub docker container action**。依保留數量清理 repo 的舊 release,並刪除沒有對應 release 的 tag;正式版與 beta 版各自獨立保留指定數量。 + +- 主程式語言:JavaScript(Node.js,使用原生 `fetch`,需 Node 18+) +- 執行方式:docker container action(`action.yaml` → `Dockerfile` → `entrypoint.sh` → `node /app/index.js`) + +## 行為總覽 + +1. **參數檢查**:驗證 `GITEA_SERVER_URL`、`GITEA_REPOSITORY`、`KEEP_COUNT`(缺值或 `KEEP_COUNT` 非整數時以 exit code 1 結束)。 +2. **取得成品資訊**:取得所有 release,依建立時間由新到舊排序,並以 tag 名稱含 `-beta.` 與否分為正式版與 beta 版。 +3. **刪除舊版本成品**:正式版與 beta 版**各自**保留最新 `KEEP_COUNT` 筆,刪除其餘 release(單筆刪除失敗只記錄錯誤,不中斷)。 +4. **刪除未指定 release 的 tag**:重新取得 release 後,刪除所有未被任何 release 指定的 tag。 + +`GITEA_TOKEN` 為空時以匿名身分呼叫 API。取得分頁失敗或參數不合法則直接以 exit code 1 結束程序。 + +## Action 輸入與環境變數 + +| 名稱 | 來源 | 必填 | 預設 | 說明 | +| --- | --- | --- | --- | --- | +| `keep_count` | `inputs` | 否 | `2` | 正式版與 beta 版各自要保留的成品數量 | +| `GITEA_SERVER_URL` | env(`gitea.server_url`) | 是 | — | Gitea 站台 URL | +| `GITEA_REPOSITORY` | env(`gitea.repository`) | 是 | — | `owner/repo` 形式的儲存庫 | +| `GITEA_TOKEN` | env(`gitea.token`) | 否 | — | API token;為空時以匿名呼叫 | + +### Workflow 使用範例 + +```yaml +jobs: + cleanup: + runs-on: ubuntu-latest + steps: + - name: Release Cleanup + uses: docker-actions/release-cleanup@develop + with: + keep_count: 3 +``` + +## 專案列表 + +### 專案描述 + +| 專案名稱 | 專案描述 | +| --- | --- | +| [release-cleanup](https://gitea.jsc.idv.tw/docker-actions/release-cleanup/src/branch/develop/app) | 清理 Gitea repo 舊 release 與孤兒 tag 的 docker container action;正式版與 beta 版各自保留指定數量 | + +### 參考專案 + +| 專案名稱 | 參考專案列表 | +| --- | --- | +| [release-cleanup](https://gitea.jsc.idv.tw/docker-actions/release-cleanup/src/branch/develop/app) | 無 | + +### NuGet 套件 + +| 專案名稱 | NuGet 套件列表 | +| --- | --- | +| [release-cleanup](https://gitea.jsc.idv.tw/docker-actions/release-cleanup/src/branch/develop/app) | 無 | + +> 註:本專案為 Node.js 專案,無 .NET ProjectReference 與 NuGet 套件;`app/package.json` 亦無第三方相依(僅使用 Node 內建 API)。 + +## 功能列表 + +### release-cleanup + +| 功能名稱 | 功能描述 | +| --- | --- | +| [separator](https://gitea.jsc.idv.tw/docker-actions/release-cleanup/src/branch/develop/app/index.js#L10) | [在 stdout 輸出視覺分隔線](#separator) | +| [section](https://gitea.jsc.idv.tw/docker-actions/release-cleanup/src/branch/develop/app/index.js#L21) | [輸出區段標題區塊](#section) | +| [info](https://gitea.jsc.idv.tw/docker-actions/release-cleanup/src/branch/develop/app/index.js#L33) | [以 \[INFO\] 前綴輸出資訊訊息](#info) | +| [success](https://gitea.jsc.idv.tw/docker-actions/release-cleanup/src/branch/develop/app/index.js#L43) | [以 \[OK\] 前綴輸出成功訊息](#success) | +| [warn](https://gitea.jsc.idv.tw/docker-actions/release-cleanup/src/branch/develop/app/index.js#L53) | [以 \[WARN\] 前綴輸出警告訊息](#warn) | +| [fail](https://gitea.jsc.idv.tw/docker-actions/release-cleanup/src/branch/develop/app/index.js#L64) | [以 \[ERR\] 前綴輸出錯誤訊息到 stderr](#fail) | +| [isEmptyOrNull](https://gitea.jsc.idv.tw/docker-actions/release-cleanup/src/branch/develop/app/index.js#L76) | [判斷值是否視為空 / 未設定](#isemptyornull) | +| [requireValue](https://gitea.jsc.idv.tw/docker-actions/release-cleanup/src/branch/develop/app/index.js#L89) | [檢查必填值,空值時結束程序](#requirevalue) | +| [requireInteger](https://gitea.jsc.idv.tw/docker-actions/release-cleanup/src/branch/develop/app/index.js#L106) | [驗證非負整數,不符時結束程序](#requireinteger) | +| [isBeta](https://gitea.jsc.idv.tw/docker-actions/release-cleanup/src/branch/develop/app/index.js#L120) | [判斷名稱是否為 beta 版本](#isbeta) | +| [main](https://gitea.jsc.idv.tw/docker-actions/release-cleanup/src/branch/develop/app/index.js#L140) | [Action 主流程:清理舊 release 與孤兒 tag](#main) | + +## 使用範例 + + +### separator + +在 stdout 輸出一條前後帶換行、由 50 個等號組成的視覺分隔線,用於在 log 中切割區段。無參數、無回傳值。 + +```js +separator(); +// 輸出: +// +// ================================================== +``` + + +### section + +輸出一個區段標題區塊:上緣等號分隔線、標題文字、下緣虛線,用於標示流程進入新階段。 + +```js +section('參數檢查'); +// 輸出: +// ================================================== +// 參數檢查 +// -------------------------------------------------- +``` + + +### info + +以 `[INFO]` 前綴將一般資訊訊息輸出到 stdout(`console.log`)。 + +```js +info('RELEASE_COUNT=10'); +// 輸出:[INFO] RELEASE_COUNT=10 +``` + + +### success + +以 `[OK]` 前綴將成功訊息輸出到 stdout。 + +```js +success('成功刪除: v1.0.0 (Release 1.0.0)'); +// 輸出:[OK] 成功刪除: v1.0.0 (Release 1.0.0) +``` + + +### warn + +以 `[WARN]` 前綴將警告訊息輸出到 stdout(非致命情況,程式會繼續執行)。 + +```js +warn('GITEA_TOKEN is empty; release API calls will be anonymous'); +// 輸出:[WARN] GITEA_TOKEN is empty; release API calls will be anonymous +``` + + +### fail + +以 `[ERR]` 前綴將錯誤訊息輸出到 **stderr**(`console.error`)。僅負責輸出,不會結束程序;是否離開由呼叫端決定。 + +```js +fail('刪除失敗: v0.1.0 (Release 0.1.0), HTTP 500'); +process.exit(1); // 終止由呼叫端負責 +``` + + +### isEmptyOrNull + +判斷值是否視為「空 / 未設定」,涵蓋 `undefined`、`null`、空字串,以及字面字串 `'null'`(用於處理 CI/環境變數把未設定值帶成字串 `"null"` 的情況)。 + +```js +isEmptyOrNull(''); // true +isEmptyOrNull('null'); // true(字面字串) +isEmptyOrNull('abc'); // false +``` + + +### requireValue + +檢查必填值。先以 `[INFO]` 印出 `name=value`,若值被判定為空則印出 `[ERR]` 並以 exit code 1 結束程序。 + +```js +requireValue('GITEA_SERVER_URL', process.env.GITEA_SERVER_URL); +// 值為空 → 輸出 [ERR] GITEA_SERVER_URL is required,並 process.exit(1) +``` + +> 前置條件:應在程式啟動早期呼叫。注意此函式會將值原樣印到 stdout,故不用於機密值(程式對 `GITEA_TOKEN` 改以 redacted 方式輸出)。 + + +### requireInteger + +驗證值是否為非負整數字串(正則 `/^[0-9]+$/`,允許前導零、不允許負號或小數),不符合時印出 `[ERR]` 並以 exit code 1 結束程序。 + +```js +requireInteger('KEEP_COUNT', '2'); // 通過 +requireInteger('KEEP_COUNT', '-1'); // 輸出 [ERR] ... 並 process.exit(1) +``` + + +### isBeta + +判斷 release / tag 名稱是否為 beta 版本,規則為名稱中含有子字串 `-beta.`。 + +```js +isBeta('v1.2.3-beta.1'); // true +isBeta('v1.2.3'); // false +isBeta('v1.2.3-beta'); // false(無結尾的點,不符合 -beta.) +``` + + +### main + +Action 主流程(`async`)。讀取環境變數後依序執行參數檢查、取得 release、刪除舊版本(正式版與 beta 版各自保留 `KEEP_COUNT` 筆)、刪除未指定 release 的 tag。由檔尾 `main().catch(...)` 立即執行。 + +```js +// 容器啟動時由 entrypoint.sh 執行:exec node /app/index.js +// 需提供環境變數: +// GITEA_SERVER_URL、GITEA_REPOSITORY、KEEP_COUNT(必要)、GITEA_TOKEN(選填) +main().catch((err) => { + fail(err && err.stack ? err.stack : String(err)); + process.exit(1); +}); +``` + +> 前置條件:執行環境須提供必要環境變數,且可連線到 Gitea API。結果:清理符合條件的舊 release 與孤兒 tag,並輸出處理過程 log。