66 Commits
Author SHA1 Message Date
jiantw83 1867838583 Merge pull request '修正版本計算未分頁導致最新版誤判為 0.0.0' (#4) from develop into master
CD / 計算版本號 (push) Successful in 1s
CD / 發布專案 (push) Successful in 4s
Reviewed-on: actions/calculate-version#4
2026-06-23 09:21:29 +00:00
jiantw83 5a855cf5cb Merge pull request '修正版本計算未分頁導致最新版誤判為 0.0.0' (#3) from ai-review-resolve/20260623-170920 into develop
Reviewed-on: actions/calculate-version#3
2026-06-23 09:20:44 +00:00
Jeffery fa26f066b8 chore(review 工作流程): 改用 OpenCode 設定取代 Gemini API 金鑰
AI / Code Review (pull_request) Successful in 26s
2026-06-23 17:19:31 +08:00
Jeffery 9e1e30c7be chore(AI 助理設定): 移除各 AI 助理的設定與 skill 檔
AI / Code Review (pull_request) Failing after 3s
2026-06-23 17:16:24 +08:00
Jeffery 2cab970059 test(版本計算): 補上分頁與 semver 取最大的測試並調整 mock jq/curl
AI / Code Review (pull_request) Failing after 6s
2026-06-23 17:09:25 +08:00
Jeffery 51605b09ea fix(版本計算): 改用分頁取得所有 release 並以 semver 取最新穩定版 2026-06-23 17:09:25 +08:00
jiantw83 2da96a5fe0 Merge pull request 'revert 7d563c725d937ca706265209666fab4d15cd8302' (#2) from develop into master
CD / 計算版本號 (push) Successful in 1m6s
CD / 發布專案 (push) Successful in 1m13s
Reviewed-on: actions/calculate-version#2
2026-06-15 03:34:34 +00:00
jiantw83 40b6fc84d1 Merge pull request '更新 entrypoint.sh' (#1) from develop into master
CD / 計算版本號 (push) Failing after 0s
CD / 發布專案 (push) Has been skipped
Reviewed-on: actions/calculate-version#1
Reviewed-by: 系統管理員 <1+admin@noreply.localhost>
2026-06-15 03:20:33 +00:00
jiantw83 d0ccf7ab43 Merge pull request '版本 0.3.6' (#61) from develop into master
Reviewed-on: actions/calculate-version#61
2026-05-15 17:20:37 +00:00
jiantw83 a1f1e94b79 Merge pull request 'feat: update workflow names for clarity and add AI code review workflow' (#59) from develop into master
Reviewed-on: actions/calculate-version#59
2026-05-13 03:29:57 +00:00
jiantw83 3dfe0895e1 Merge pull request 'feat: 將參數輸出移到最後一個步驟' (#57) from develop into master
Reviewed-on: actions/calculate-version#57
2026-03-26 06:53:03 +00:00
jiantw83 affe0c8553 Merge pull request '更新 action.yaml' (#56) from develop into master
Reviewed-on: actions/calculate-version#56
2026-03-25 06:41:26 +00:00
jiantw83 03d1f1d79b Merge pull request '更新 Dockerfile' (#55) from develop into master
Reviewed-on: actions/calculate-version#55
2026-03-25 05:42:50 +00:00
jiantw83 c21d28c2cc Merge pull request '更新 action.yaml' (#54) from develop into master
Reviewed-on: actions/calculate-version#54
2026-03-25 02:47:06 +00:00
jiantw83 74b359a8f5 Merge pull request 'test: 修正基本版本號的過濾方法' (#53) from develop into master
Reviewed-on: actions/calculate-version#53
2026-03-24 10:36:06 +00:00
jiantw83 cfe4c1e7c5 Merge pull request 'feat: 加入 beta 版本計算' (#51) from develop into master
Reviewed-on: actions/calculate-version#51
2026-03-24 10:19:19 +00:00
jiantw83 7d36cfc6ac Merge pull request 'feat: 將清理成品的行為合併到發布專案' (#50) from develop into master
Reviewed-on: actions/calculate-version#50
2026-03-21 11:48:43 +00:00
jiantw83 ee375ccd2e Merge pull request '更新 .gitea/workflows/master.yaml' (#49) from develop into master
Reviewed-on: actions/calculate-version#49
2026-03-21 09:39:09 +00:00
jiantw83 4cf3b4aacd Merge pull request 'feat: 加上 Gitea Runner Token' (#48) from develop into master
Reviewed-on: actions/calculate-version#48
2026-03-21 02:59:17 +00:00
jiantw83 927b7813f6 Merge pull request 'feat: 清理成品' (#47) from develop into master
Reviewed-on: actions/calculate-version#47
2026-03-21 02:54:19 +00:00
jiantw83 f3800fea94 Merge pull request 'feat: 變更工作流名稱' (#46) from develop into master
Reviewed-on: actions/calculate-version#46
2026-03-20 10:15:38 +00:00
jiantw83 3a87156c5b Merge pull request 'fix: 修正工作流相依' (#45) from develop into master
Reviewed-on: actions/calculate-version#45
Reviewed-by: 系統管理員 <admin@noreply.localhost>
2026-03-20 10:10:31 +00:00
jiantw83 f199b588bd Merge pull request 'feat: 重構 CD 工作流' (#44) from develop into master
Reviewed-on: actions/calculate-version#44
2026-03-20 10:07:41 +00:00
jiantw83 d46add8a7e Merge pull request 'test: 使用不同的執行器' (#43) from develop into master
Reviewed-on: actions/calculate-version#43
2026-03-20 10:04:14 +00:00
jiantw83 1662980fa2 Merge pull request 'feat: 改回檔案的方式繼續想怎麼處理' (#42) from develop into master
Reviewed-on: actions/calculate-version#42
2026-03-20 09:38:18 +00:00
jiantw83 6780d2b32b Merge pull request 'test: 相信 AI 再試一次 GITHUB_OUTPUT' (#41) from develop into master
Reviewed-on: actions/calculate-version#41
2026-03-20 09:31:44 +00:00
jiantw83 d85479a77c Merge pull request 'feat: 修正工作流' (#40) from develop into master
Reviewed-on: actions/calculate-version#40
2026-03-20 09:26:20 +00:00
jiantw83 0b6b090d1f Merge pull request 'develop' (#39) from develop into master
Reviewed-on: actions/calculate-version#39
2026-03-20 09:23:03 +00:00
jiantw83 432872a810 Merge pull request 'feat: 從不同的工作目錄取得版本檔案' (#38) from develop into master
Reviewed-on: actions/calculate-version#38
2026-03-20 09:21:03 +00:00
jiantw83 badb04d99f Merge pull request 'test: 從共用資料夾讀取版本檔案' (#37) from develop into master
Reviewed-on: actions/calculate-version#37
2026-03-20 09:13:50 +00:00
jiantw83 69b175bf2f Merge pull request 'test: 將版本檔案放到共用資料夾' (#36) from develop into master
Reviewed-on: actions/calculate-version#36
2026-03-20 09:12:29 +00:00
jiantw83 1569ab34d2 Merge pull request 'fix: 修正指令' (#35) from develop into master
Reviewed-on: actions/calculate-version#35
2026-03-20 09:09:49 +00:00
jiantw83 3a0db85929 Merge pull request 'feat: 發布新版' (#34) from develop into master
Reviewed-on: actions/calculate-version#34
2026-03-20 09:07:55 +00:00
jiantw83 fbbd4ac22b Merge pull request 'feat: 在外部書出版本號' (#33) from develop into master
Reviewed-on: actions/calculate-version#33
2026-03-20 09:06:14 +00:00
jiantw83 d6fe823eae Merge pull request 'test: 嘗試使用兩種模式' (#32) from develop into master
Reviewed-on: actions/calculate-version#32
2026-03-20 09:04:12 +00:00
jiantw83 85ccf9331e Merge pull request 'develop' (#31) from develop into master
Reviewed-on: actions/calculate-version#31
2026-03-20 08:52:11 +00:00
jiantw83 7f55625ec9 Merge pull request 'feat: 使用新版本' (#30) from develop into master
Reviewed-on: actions/calculate-version#30
2026-03-20 08:50:05 +00:00
jiantw83 fe6cf4a651 Merge pull request 'feat: 使用新版本' (#29) from develop into master
Reviewed-on: actions/calculate-version#29
2026-03-20 08:45:56 +00:00
jiantw83 e6559154c5 Merge pull request 'feat: 發布新版本' (#28) from develop into master
Reviewed-on: actions/calculate-version#28
2026-03-20 08:45:27 +00:00
jiantw83 b9e7b91c43 Merge pull request 'feat: 使用新版本' (#27) from develop into master
Reviewed-on: actions/calculate-version#27
2026-03-20 08:43:00 +00:00
jiantw83 b5efc787c1 Merge pull request 'test: 嘗試排除沒有資料夾的問題' (#26) from develop into master
Reviewed-on: actions/calculate-version#26
2026-03-20 08:42:29 +00:00
jiantw83 45fd822e62 Merge pull request 'feat: 使用新版本' (#25) from develop into master
Reviewed-on: actions/calculate-version#25
2026-03-20 08:39:23 +00:00
jiantw83 023e6d3788 Merge pull request 'feat: 更新版本' (#24) from develop into master
Reviewed-on: actions/calculate-version#24
2026-03-20 08:38:51 +00:00
jiantw83 5910765704 Merge pull request 'feat: 修正邏輯' (#23) from develop into master
Reviewed-on: actions/calculate-version#23
2026-03-20 08:38:03 +00:00
jiantw83 a5a69e8725 Merge pull request 'feat: 更新版本號' (#22) from develop into master
Reviewed-on: actions/calculate-version#22
2026-03-20 08:27:07 +00:00
jiantw83 23e72dcf8d Merge pull request 'feat: 重新 CD' (#21) from develop into master
Reviewed-on: actions/calculate-version#21
2026-03-20 08:25:40 +00:00
jiantw83 9dba1ccf7c Merge pull request 'feat: 沒有 runner token 也不要出錯' (#20) from develop into master
Reviewed-on: actions/calculate-version#20
2026-03-20 08:24:53 +00:00
jiantw83 d4ba21c460 Merge pull request 'feat: 顯示資訊' (#19) from develop into master
Reviewed-on: actions/calculate-version#19
2026-03-20 08:21:55 +00:00
jiantw83 5956724489 Merge pull request 'feat: 更新版本號' (#18) from develop into master
Reviewed-on: actions/calculate-version#18
2026-03-20 08:18:49 +00:00
jiantw83 e143b650aa Merge pull request 'feat: 從工具外部取得 token' (#17) from develop into master
Reviewed-on: actions/calculate-version#17
2026-03-20 08:17:47 +00:00
jiantw83 a4ce4ce085 Merge pull request 'feat: 從工具外部取得 token' (#16) from develop into master
Reviewed-on: actions/calculate-version#16
2026-03-20 08:16:22 +00:00
jiantw83 602905fbcf Merge pull request 'feat: 只能拉舊的版本' (#15) from develop into master
Reviewed-on: actions/calculate-version#15
2026-03-20 08:12:25 +00:00
jiantw83 3b8ff34915 Merge pull request 'feat: 發布專案後,嘗試計算版本號' (#14) from develop into master
Reviewed-on: actions/calculate-version#14
2026-03-20 08:11:42 +00:00
jiantw83 1074718eeb Merge pull request 'feat: 嘗試工具是否有被修正' (#13) from develop into master
Reviewed-on: actions/calculate-version#13
2026-03-20 08:10:26 +00:00
jiantw83 e0c5466ee6 Merge pull request 'feat: 強制發布版本' (#12) from develop into master
Reviewed-on: actions/calculate-version#12
2026-03-20 08:09:22 +00:00
jiantw83 6b4634e8ce Merge pull request 'feat: 安裝 bash 套件' (#11) from develop into master
Reviewed-on: actions/calculate-version#11
2026-03-20 08:05:44 +00:00
jiantw83 b7b6747126 Merge pull request 'feat: 移除 entrypoint 的 /r' (#10) from develop into master
Reviewed-on: actions/calculate-version#10
2026-03-20 08:03:20 +00:00
jiantw83 bb5759aa0e Merge pull request 'test: 修改編碼嘗試執行腳本' (#9) from develop into master
Reviewed-on: actions/calculate-version#9
2026-03-20 07:59:17 +00:00
jiantw83 4273223cff Merge pull request 'test: 改用 ubuntu 嘗試執行腳本' (#8) from develop into master
Reviewed-on: actions/calculate-version#8
2026-03-20 07:57:12 +00:00
jiantw83 23cf44e584 Merge pull request 'feat: 安裝 bash 工具用來執行腳本' (#7) from develop into master
Reviewed-on: actions/calculate-version#7
2026-03-20 07:54:24 +00:00
jiantw83 f6fa064b1f Merge pull request 'feat: 強制指定計算版本號的工具版本' (#6) from develop into master
Reviewed-on: actions/calculate-version#6
2026-03-20 07:52:41 +00:00
jiantw83 9407e4a134 Merge pull request 'feat: 使用最新的工具計算版本號' (#5) from develop into master
Reviewed-on: actions/calculate-version#5
2026-03-20 07:48:29 +00:00
jiantw83 cfddd28be4 Merge pull request 'feat: 重構計算版本號' (#4) from develop into master
Reviewed-on: actions/calculate-version#4
2026-03-20 07:47:10 +00:00
jiantw83 e69490f7b6 Merge pull request '更新 .gitea/workflows/master.yaml' (#3) from develop into master
Reviewed-on: actions/calculate-version#3
2026-03-05 08:10:46 +00:00
jiantw83 1f81d3a887 Merge pull request '更新 .gitea/workflows/master.yaml' (#2) from develop into master
Reviewed-on: actions/calculate-version#2
2026-03-05 08:08:18 +00:00
jiantw83 8b84c5aa6a Merge pull request '更新 .gitea/workflows/master.yaml' (#1) from develop into master
Reviewed-on: actions/calculate-version#1
2026-03-05 08:03:12 +00:00
12 changed files with 229 additions and 248 deletions
-14
View File
@@ -1,14 +0,0 @@
# Triage Findings
When the task is to triage review findings, follow this workflow:
1. Merge all findings into one list.
2. Remove duplicates.
3. Sort by severity: `critical` -> `warning` -> `info`.
4. Renumber from 1 after sorting.
5. Fix real issues with the smallest safe change.
6. Add false positives to `.gitea/ai-review/exclusions.json`, preserving the original wording, language, and semantics as much as possible.
7. Add or update tests when behavior changes.
8. Re-check the issue after each fix.
Use the repo-local `triage-findings` skill for the same workflow when running in Codex.
-29
View File
@@ -1,29 +0,0 @@
---
name: triage-findings
description: Triage findings, fix real issues, and exclude false positives.
---
# Triage Findings
## Use
直接輸入:`triage-findings 問題原始檔(文字或截圖)`
## Workflow
1. Merge all findings.
2. Sort by severity:
- critical
- warning
- info
3. Renumber from 1.
4. Fix real issues.
5. Put false positives into `.gitea/ai-review/exclusions.json`, preserving the original wording, language, and semantics as much as possible.
6. Add tests when behavior changes.
## Output Rules
- Keep the final list short.
- Keep numbering contiguous.
- Preserve file path, location, and fix.
- When writing exclusions, prefer the original issue text over paraphrased rewrites.
-45
View File
@@ -1,45 +0,0 @@
---
name: triage-findings
description: Merge code-review findings, sort and renumber them by severity, resolve real issues, and move false positives into exclusions.
---
# Triage Findings
## When To Use
Use this skill when you receive multiple review findings, screenshots, comments, or issue lists that need to become one final triaged list.
It is also used when some findings are false positives and should be moved into the exclusions list.
## Workflow
1. Collect all findings into one list.
2. Merge duplicates into a single finding when they describe the same issue.
3. Sort the final list by severity:
- critical
- warning
- info
4. Renumber the sorted list from 1 upward.
5. Rewrite each finding concisely so the final list reads cleanly and consistently.
6. If a finding is a false positive, do not keep it in the final list.
7. Add false positives to the exclusions list using the existing schema in the repo or task context, and preserve the original finding wording as much as possible, including language and semantics.
## Resolution Flow
After the list is merged and ordered, resolve the remaining findings one by one.
1. Start from the highest severity item.
2. Identify the root cause in the relevant file or context.
3. Apply the smallest safe change that fixes the issue.
4. Add or update tests when behavior changes.
5. Re-check the issue after the change.
6. If the item is confirmed false positive, move it to exclusions instead of changing code.
7. Continue until the list is either fixed or explicitly excluded.
## Output Rules
- Keep the final findings list in severity order, then by any stable secondary order needed to make it readable.
- Keep numbering contiguous after filtering and merging.
- Preserve useful details like file path, location, and suggested fix.
- Keep exclusions entries minimal and consistent with the project schema.
- When writing exclusions, prefer the original issue text and language; only paraphrase if needed to fit the schema.
- If the source already provides a severity or title, keep it unless it conflicts with the final ordering.
@@ -1,4 +0,0 @@
interface:
display_name: "Triage Findings"
short_description: "Triage, sort, fix, and exclude review findings"
default_prompt: "Use $triage-findings to merge review findings, sort and renumber them by severity, resolve real issues one by one, and add false positives to exclusions."
-29
View File
@@ -1,29 +0,0 @@
---
name: triage-findings
description: Triage findings, fix real issues, and exclude false positives.
---
# Triage Findings
## Use
直接輸入:`triage-findings 問題原始檔(文字或截圖)`
## Workflow
1. Merge all findings.
2. Sort by severity:
- critical
- warning
- info
3. Renumber from 1.
4. Fix real issues.
5. Put false positives into `.gitea/ai-review/exclusions.json`, preserving the original wording, language, and semantics as much as possible.
6. Add tests when behavior changes.
## Output Rules
- Keep the final list short.
- Keep numbering contiguous.
- Preserve file path, location, and fix.
- When writing exclusions, prefer the original issue text over paraphrased rewrites.
+3 -3
View File
@@ -14,9 +14,9 @@ jobs:
with:
GITEA_TOKEN: ${{ secrets.RUNNER_TOKEN }}
GITEA_COMMENT_TOKEN: ${{ secrets.GITEA_TOKEN }}
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }},${{ secrets.GEMINI_API_KEY_1 }},${{ secrets.GEMINI_API_KEY_2 }},${{ secrets.GEMINI_API_KEY_3 }},${{ secrets.GEMINI_API_KEY_4 }},${{ secrets.GEMINI_API_KEY_5 }},${{ secrets.GEMINI_API_KEY_6 }},${{ secrets.GEMINI_API_KEY_7 }},${{ secrets.GEMINI_API_KEY_8 }},${{ secrets.GEMINI_API_KEY_9 }},${{ secrets.GEMINI_API_KEY_10 }},${{ secrets.GEMINI_API_KEY_11 }},${{ secrets.GEMINI_API_KEY_12 }},${{ secrets.GEMINI_API_KEY_13 }},${{ secrets.GEMINI_API_KEY_14 }},${{ secrets.GEMINI_API_KEY_15 }},${{ secrets.GEMINI_API_KEY_16 }},${{ secrets.GEMINI_API_KEY_17 }},${{ secrets.GEMINI_API_KEY_18 }},${{ secrets.GEMINI_API_KEY_19 }}
GEMINI_BASE_URL: https://generativelanguage.googleapis.com/v1beta
GEMINI_MODEL: ${{ vars.GEMINI_MODEL }}
OPENCODE_BASE_URL: ${{ vars.OPENCODE_BASE_URL }}
OPENCODE_PROVIDER: ${{ vars.OPENCODE_PROVIDER }}
OPENCODE_MODEL: ${{ vars.GEMINI_MODEL }}
permissions:
contents: write
pull-requests: write
-14
View File
@@ -1,14 +0,0 @@
# Triage Findings
Use the triage-finding workflow for review issue lists:
1. Merge findings into one list.
2. Remove duplicates.
3. Sort by severity: `critical` -> `warning` -> `info`.
4. Renumber from 1.
5. Fix real issues with the smallest safe change.
6. Put false positives into `.gitea/ai-review/exclusions.json`, preserving the original wording, language, and semantics as much as possible.
7. Add or update tests when behavior changes.
8. Re-check after each fix.
The full reusable skill lives in `.claude/skills/triage-findings/SKILL.md`.
-14
View File
@@ -1,14 +0,0 @@
# Triage Findings
Use the triage-finding workflow for review issue lists:
1. Merge findings into one list.
2. Remove duplicates.
3. Sort by severity: `critical` -> `warning` -> `info`.
4. Renumber from 1.
5. Fix real issues with the smallest safe change.
6. Put false positives into `.gitea/ai-review/exclusions.json`, preserving the original wording, language, and semantics as much as possible.
7. Add or update tests when behavior changes.
8. Re-check after each fix.
The reusable skill lives in `.gemini/skills/triage-findings/SKILL.md`.
-16
View File
@@ -1,16 +0,0 @@
# Triage Findings
When the task is to triage review findings, follow this workflow:
1. Merge all findings into one list.
2. Remove duplicates.
3. Sort by severity: `critical` -> `warning` -> `info`.
4. Renumber from 1 after sorting.
5. Fix real issues with the smallest safe change.
6. Add false positives to `.gitea/ai-review/exclusions.json`, preserving the original wording, language, and semantics as much as possible.
7. Add or update tests when behavior changes.
8. Re-check the issue after each fix.
Use the repo-local `triage-findings` skill for the same workflow when running in Codex.
Trigger it with `/triage-findings`.
-14
View File
@@ -1,14 +0,0 @@
# Triage Findings
Use the triage-finding workflow for review issue lists:
1. Merge findings into one list.
2. Remove duplicates.
3. Sort by severity: `critical` -> `warning` -> `info`.
4. Renumber from 1.
5. Fix real issues with the smallest safe change.
6. Put false positives into `.gitea/ai-review/exclusions.json`, preserving the original wording, language, and semantics as much as possible.
7. Add or update tests when behavior changes.
8. Re-check after each fix.
The reusable skill lives in `.gemini/skills/triage-findings/SKILL.md`.
+75 -20
View File
@@ -4,6 +4,7 @@ set -euo pipefail
readonly LINE="=================================================="
readonly SUBLINE="--------------------------------------------------"
readonly RELEASES_PER_PAGE=10
section() {
printf '\n%s\n%s\n%s\n' "$LINE" "$1" "$SUBLINE"
@@ -53,13 +54,17 @@ latest_stable_version() {
fi
printf '%s' "$release_json" | jq -r '
if type == "array" then
[ .[] | select(.tag_name? and (.tag_name | test("-beta\\.") | not)) | .tag_name ][0]
// "v0.0.0"
else
"v0.0.0"
end
| sub("^v"; "")
( if type == "array" then . else [] end )
| [ .[]
| select(.tag_name? and (.tag_name | test("-beta\\.") | not))
| .tag_name
| sub("^v"; "")
| select(test("^[0-9]+(\\.[0-9]+)*$"))
| split(".")
| map(tonumber)
]
| if length == 0 then [0, 0, 0] else (sort | last) end
| "\(.[0] // 0).\(.[1] // 0).\(.[2] // 0)"
'
}
@@ -124,13 +129,17 @@ calculate_version() {
printf '%s' "$release_json" | jq -r --arg is_beta "$is_beta" '
def stable_version:
if type == "array" then
[ .[] | select(.tag_name? and (.tag_name | test("-beta\\.") | not)) | .tag_name ][0]
// "v0.0.0"
else
"v0.0.0"
end
| sub("^v"; "");
( if type == "array" then . else [] end )
| [ .[]
| select(.tag_name? and (.tag_name | test("-beta\\.") | not))
| .tag_name
| sub("^v"; "")
| select(test("^[0-9]+(\\.[0-9]+)*$"))
| split(".")
| map(tonumber)
]
| if length == 0 then [0, 0, 0] else (sort | last) end
| "\(.[0] // 0).\(.[1] // 0).\(.[2] // 0)";
def next_release($latest):
($latest | split(".") | map(tonumber? // 0)) as $parts
@@ -166,6 +175,56 @@ calculate_version() {
'
}
fetch_releases() {
local base_url="$1"
local -a auth_args=()
if [ -n "${RUNNER_TOKEN:-}" ] && [ "${RUNNER_TOKEN:-}" != "null" ]; then
info "使用授權 token 取得 release" >&2
auth_args=(-H "Authorization: token $RUNNER_TOKEN")
else
info "使用匿名請求取得 release" >&2
fi
local page=1
local combined="[]"
local page_json count
while :; do
if ! page_json="$(curl -fsS ${auth_args[@]+"${auth_args[@]}"} "${base_url}?limit=${RELEASES_PER_PAGE}&page=${page}")"; then
fail "release API 請求失敗 (page=${page})"
fi
# 空字串或 null 代表已無更多資料
if [ -z "$page_json" ] || [ "$page_json" = "null" ]; then
break
fi
if ! count="$(printf '%s' "$page_json" | jq 'if type == "array" then length else -1 end')"; then
fail "release API 回傳資料無法解析 (page=${page})"
fi
if [ "$count" = "-1" ]; then
fail "release API 回傳非陣列資料 (page=${page})"
fi
info "${page} 頁取得 ${count} 筆 release" >&2
if ! combined="$(jq -n --argjson acc "$combined" --argjson page "$page_json" '$acc + $page')"; then
fail "合併 release 資料失敗 (page=${page})"
fi
# 不足一頁代表已取完
if [ "$count" -lt "$RELEASES_PER_PAGE" ]; then
break
fi
page=$((page + 1))
done
printf '%s' "$combined"
}
main() {
section "參數檢查"
@@ -186,12 +245,8 @@ main() {
RELEASE_URL="$GITEA_SERVER_URL/api/v1/repos/$GITEA_REPOSITORY/releases"
info "RELEASE_URL=$RELEASE_URL"
if [ -n "${RUNNER_TOKEN:-}" ] && [ "${RUNNER_TOKEN:-}" != "null" ]; then
info "使用授權 token 取得 release"
RELEASE_JSON="$(curl -fsS -H "Authorization: token $RUNNER_TOKEN" "$RELEASE_URL")"
else
info "使用匿名請求取得 release"
RELEASE_JSON="$(curl -fsS "$RELEASE_URL")"
if ! RELEASE_JSON="$(fetch_releases "$RELEASE_URL")"; then
fail "取得 release 資料失敗"
fi
VERSION_INFO="$(calculate_version "$RELEASE_JSON" "$IS_BETA")"
+150 -45
View File
@@ -33,7 +33,6 @@ assert_eq() {
make_mock_curl() {
local bin_dir="$1"
local response_file="$2"
cat >"$bin_dir/curl" <<'EOF'
#!/bin/sh
@@ -45,6 +44,26 @@ if [ "${FAKE_CURL_STATUS:-0}" != "0" ]; then
exit "$FAKE_CURL_STATUS"
fi
# 分頁模式:依 URL 上的 page=N 回傳對應的 page 檔,超出範圍回傳空陣列
if [ -n "${FAKE_CURL_PAGES_DIR:-}" ]; then
page=1
for arg in "$@"; do
case "$arg" in
*page=*)
page=${arg##*page=}
page=${page%%&*}
;;
esac
done
page_file="$FAKE_CURL_PAGES_DIR/$page.json"
if [ -f "$page_file" ]; then
cat "$page_file"
else
printf '[]'
fi
exit 0
fi
cat "${FAKE_CURL_RESPONSE_FILE:?}"
EOF
chmod +x "$bin_dir/curl"
@@ -55,42 +74,63 @@ make_mock_jq() {
cat >"$bin_dir/jq" <<'EOF'
#!/bin/sh
is_beta=""
query=""
python3 -c '
import json, re, sys
while [ "$#" -gt 0 ]; do
case "$1" in
-r)
shift
;;
--arg)
if [ "$2" = "is_beta" ]; then
is_beta="$3"
fi
shift 3
;;
*)
query="$1"
shift
break
;;
esac
done
args = sys.argv[1:]
named = {}
use_stdin = True
i = 0
while i < len(args):
a = args[i]
if a == "-r":
i += 1
elif a == "-n":
use_stdin = False
i += 1
elif a in ("--arg", "--argjson"):
value = args[i + 2]
named[args[i + 1]] = json.loads(value) if a == "--argjson" else value
i += 3
else:
i += 1
python3 -c 'import json, sys
query = sys.argv[1]
is_beta = sys.argv[2]
payload = sys.stdin.read()
try:
data = json.loads(payload)
except Exception:
sys.exit(4)
payload = sys.stdin.read() if use_stdin else ""
def parse_or_exit(text):
try:
return json.loads(text)
except Exception:
sys.exit(4)
# merge 模式:$acc + $page
if "acc" in named and "page" in named:
sys.stdout.write(json.dumps(named["acc"] + named["page"]))
sys.exit(0)
# count 模式:陣列長度,非陣列回 -1
if "is_beta" not in named:
data = parse_or_exit(payload)
sys.stdout.write(str(len(data)) if isinstance(data, list) else "-1")
sys.exit(0)
# calculate 模式
data = parse_or_exit(payload)
is_beta = named.get("is_beta", "")
def to_tuple(ver):
nums = []
for part in ver.split("."):
try:
nums.append(int(part))
except Exception:
nums.append(0)
while len(nums) < 3:
nums.append(0)
return tuple(nums[:3])
def next_version(latest):
parts = [int(p or 0) for p in latest.split(".")]
while len(parts) < 3:
parts.append(0)
major, minor, patch = parts[:3]
major, minor, patch = to_tuple(latest)
patch += 1
if patch >= 10:
patch = 0
@@ -98,18 +138,17 @@ def next_version(latest):
if minor >= 10:
minor = 0
major += 1
return f"{major}.{minor}.{patch}"
return "{}.{}.{}".format(major, minor, patch)
def beta_max(data, prefix):
def beta_max(items, prefix):
values = []
for item in data:
for item in items:
if not isinstance(item, dict):
continue
tag = item.get("tag_name")
if isinstance(tag, str) and tag.startswith(prefix):
suffix = tag[len(prefix):]
try:
values.append(int(suffix))
values.append(int(tag[len(prefix):]))
except Exception:
pass
return max(values) if values else 0
@@ -117,22 +156,24 @@ def beta_max(data, prefix):
if not isinstance(data, list):
base = "0.0.0"
else:
base = "0.0.0"
stable = []
for item in data:
if not isinstance(item, dict):
continue
tag = item.get("tag_name")
if isinstance(tag, str) and "-beta." not in tag:
base = tag[1:] if tag.startswith("v") else tag
break
ver = tag[1:] if tag.startswith("v") else tag
if re.match(r"^[0-9]+(\.[0-9]+)*$", ver):
stable.append(ver)
base = max(stable, key=to_tuple) if stable else "0.0.0"
next_ver = next_version(base)
if is_beta == "true":
beta = beta_max(data, f"v{next_ver}-beta.") + 1
sys.stdout.write(f"{base}\t{next_ver}-beta.{beta}")
beta = beta_max(data, "v{}-beta.".format(next_ver)) + 1
sys.stdout.write("{}\t{}-beta.{}".format(base, next_ver, beta))
else:
sys.stdout.write(f"{base}\t{next_ver}")
' "$query" "$is_beta"
sys.stdout.write("{}\t{}".format(base, next_ver))
' "$@"
EOF
chmod +x "$bin_dir/jq"
}
@@ -281,6 +322,69 @@ test_null_release_payload() {
assert_eq "version=0.0.1" "$(cat "$output_file")" "null release payload"
}
test_pagination_collects_all_pages() {
local workdir
local pages_dir
local bin_dir
local output_file
local stdout_file
local stderr_file
local curl_args
local i
workdir="$(mktemp -d)"
CLEANUP_PATHS+=("$workdir")
pages_dir="$workdir/pages"
mkdir -p "$pages_dir"
# 第 1 頁滿載 10 筆,且全部是 beta(重現「最新一整頁都是 beta」的情境)
{
printf '['
for i in $(seq 1 10); do
if [ "$i" -gt 1 ]; then printf ','; fi
printf '{"tag_name":"v1.9.0-beta.%s"}' "$i"
done
printf ']'
} >"$pages_dir/1.json"
# 第 2 頁才出現穩定版,且故意讓最大值不是第一筆(驗證 semver 取最大)
cat >"$pages_dir/2.json" <<'JSON'
[
{"tag_name":"v1.2.3"},
{"tag_name":"v1.3.1"},
{"tag_name":"v1.2.9"}
]
JSON
bin_dir="$workdir/bin"
mkdir -p "$bin_dir"
make_mock_curl "$bin_dir"
make_mock_jq "$bin_dir"
output_file="$workdir/github_output"
stdout_file="$workdir/stdout"
stderr_file="$workdir/stderr"
FAKE_CURL_STATUS=0 \
FAKE_CURL_PAGES_DIR="$pages_dir" \
FAKE_CURL_LOG_FILE="$workdir/curl_args" \
PATH="$bin_dir:$PATH" \
GITEA_SERVER_URL="https://gitea.example.com" \
GITEA_REPOSITORY="org/repo" \
IS_BETA="false" \
GITHUB_OUTPUT="$output_file" \
bash "$ROOT_DIR/entrypoint.sh" >"$stdout_file" 2>"$stderr_file"
# 穩定版在第 2 頁、最大為 1.3.1 -> 下一版 1.3.2
assert_eq "version=1.3.2" "$(cat "$output_file")" "pagination + semver max output"
# 確認確實翻到第 2 頁
curl_args="$workdir/curl_args"
if ! grep -q 'page=2' "$curl_args"; then
fail "pagination: expected a request for page=2"
fi
}
test_token_auth_header() {
local workdir
local response_file
@@ -392,6 +496,7 @@ test_beta_release_flow
test_empty_release_list
test_only_beta_releases
test_null_release_payload
test_pagination_collects_all_pages
test_token_auth_header
test_malformed_release_payload
test_curl_failure