From 30f5dce8dc02df67a179c6f8f7f89dd9143fb96c Mon Sep 17 00:00:00 2001 From: Jeffery Date: Tue, 23 Jun 2026 16:14:51 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat(=E6=B8=85=E7=90=86=E6=88=90=E5=93=81):?= =?UTF-8?q?=20=E6=96=B0=E5=A2=9E=E5=88=AA=E9=99=A4=E6=9C=AA=E6=8C=87?= =?UTF-8?q?=E5=AE=9A=20release=20=E7=9A=84=20tag=20=E6=AD=A5=E9=A9=9F?= =?UTF-8?q?=E4=B8=A6=E6=8A=BD=E5=87=BA=E5=88=86=E9=A0=81=E5=85=B1=E7=94=A8?= =?UTF-8?q?=E5=87=BD=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 刪除舊版本成品後,重新取得 release 清單並刪除所有未指定到 release 的 tag。 Co-Authored-By: Claude Opus 4.8 (1M context) --- entrypoint.sh | 106 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 76 insertions(+), 30 deletions(-) diff --git a/entrypoint.sh b/entrypoint.sh index b7599b8..cfa7dc0 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -52,6 +52,27 @@ require_integer() { fi } +fetch_all_pages() { + local base_url="$1" + local all_json='[]' + local page=1 + local page_url page_json + + while :; do + page_url="$base_url?page=$page" + page_json="$(curl -fsS "${auth_header[@]}" "$page_url")" + + if [ "$(jq 'length' <<<"$page_json")" -eq 0 ]; then + break + fi + + all_json="$(jq -s 'add' <<<"$all_json"$'\n'"$page_json")" + page=$((page + 1)) + done + + printf '%s' "$all_json" +} + section "參數檢查" require_value "GITEA_SERVER_URL" "$GITEA_SERVER_URL" require_value "GITEA_REPOSITORY" "$GITEA_REPOSITORY" @@ -74,21 +95,7 @@ fi section "取得成品資訊" info "GET $release_api_url" -release_json='[]' -page=1 - -while :; do - page_url="$release_api_url?page=$page" - page_json="$(curl -fsS "${auth_header[@]}" "$page_url")" - - if [ "$(jq 'length' <<<"$page_json")" -eq 0 ]; then - break - fi - - release_json="$(jq -s 'add' <<<"$release_json"$'\n'"$page_json")" - page=$((page + 1)) -done - +release_json="$(fetch_all_pages "$release_api_url")" release_json="$(jq -e 'sort_by(.created_at) | reverse' <<<"$release_json")" release_count="$(jq 'length' <<<"$release_json")" @@ -97,35 +104,74 @@ info "KEEP_COUNT=$KEEP_COUNT" if [ "$release_count" -le "$KEEP_COUNT" ]; then success "沒有需要清理的舊版本成品" - exit 0 +else + section "刪除舊版本成品" + + release_to_delete="$(jq -c ".[$KEEP_COUNT:]" <<<"$release_json")" + + while IFS= read -r release_item; do + [ -z "$release_item" ] && continue + + release_id="$(jq -r '.id' <<<"$release_item")" + release_tag="$(jq -r '.tag_name' <<<"$release_item")" + release_name="$(jq -r '.name' <<<"$release_item")" + + if is_empty_or_null "$release_id"; then + warn "略過沒有 id 的成品: $release_tag ($release_name)" + continue + fi + + delete_url="$GITEA_SERVER_URL/api/v1/repos/$GITEA_REPOSITORY/releases/$release_id" + info "DELETE $release_tag ($release_name)" + + delete_code="$(curl -sS -o /dev/null -w "%{http_code}" -X DELETE "${auth_header[@]}" "$delete_url")" + + if [ "$delete_code" -eq 204 ]; then + success "成功刪除: $release_tag ($release_name)" + else + fail "刪除失敗: $release_tag ($release_name), HTTP $delete_code" + fi + done < <(jq -c '.[]' <<<"$release_to_delete") fi -section "刪除舊版本成品" +section "刪除未指定 release 的 tag" -release_to_delete="$(jq -c ".[$KEEP_COUNT:]" <<<"$release_json")" +# 重新取得 release 清單,得到刪除舊版本後仍指定 tag 的成品 +current_release_json="$(fetch_all_pages "$release_api_url")" +release_tags_json="$(jq -c '[.[].tag_name]' <<<"$current_release_json")" -while IFS= read -r release_item; do - [ -z "$release_item" ] && continue +tag_api_url="$GITEA_SERVER_URL/api/v1/repos/$GITEA_REPOSITORY/tags" +info "GET $tag_api_url" - release_id="$(jq -r '.id' <<<"$release_item")" - release_tag="$(jq -r '.tag_name' <<<"$release_item")" - release_name="$(jq -r '.name' <<<"$release_item")" +tag_json="$(fetch_all_pages "$tag_api_url")" +tag_count="$(jq 'length' <<<"$tag_json")" +info "TAG_COUNT=$tag_count" - if is_empty_or_null "$release_id"; then - warn "略過沒有 id 的成品: $release_tag ($release_name)" +while IFS= read -r tag_item; do + [ -z "$tag_item" ] && continue + + tag_name="$(jq -r '.name' <<<"$tag_item")" + + if is_empty_or_null "$tag_name"; then + warn "略過沒有名稱的 tag" continue fi - delete_url="$GITEA_SERVER_URL/api/v1/repos/$GITEA_REPOSITORY/releases/$release_id" - info "DELETE $release_tag ($release_name)" + if [ "$(jq --arg name "$tag_name" 'any(.[]; . == $name)' <<<"$release_tags_json")" = "true" ]; then + info "保留指定 release 的 tag: $tag_name" + continue + fi + + delete_url="$tag_api_url/$tag_name" + info "DELETE tag $tag_name" delete_code="$(curl -sS -o /dev/null -w "%{http_code}" -X DELETE "${auth_header[@]}" "$delete_url")" if [ "$delete_code" -eq 204 ]; then - success "成功刪除: $release_tag ($release_name)" + success "成功刪除未指定 release 的 tag: $tag_name" else - fail "刪除失敗: $release_tag ($release_name), HTTP $delete_code" + fail "刪除 tag 失敗: $tag_name, HTTP $delete_code" fi -done < <(jq -c '.[]' <<<"$release_to_delete") +done < <(jq -c '.[]' <<<"$tag_json") separator -- 2.53.0 From 6cad836ce31a13c40b4c31430fa5d9f2885a9fc4 Mon Sep 17 00:00:00 2001 From: Jeffery Date: Tue, 23 Jun 2026 16:14:56 +0800 Subject: [PATCH 2/3] =?UTF-8?q?test(=E6=B8=85=E7=90=86=E6=88=90=E5=93=81):?= =?UTF-8?q?=20=E6=96=B0=E5=A2=9E=20tag=20=E6=B8=85=E7=90=86=E6=B8=AC?= =?UTF-8?q?=E8=A9=A6=E4=B8=A6=E6=8A=BD=E5=87=BA=E5=85=B1=E7=94=A8=20jq=20m?= =?UTF-8?q?ock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 entrypoint_tag_cleanup.sh 驗證孤兒 tag 刪除、保留指定 release 的 tag;分頁測試改為端點感知並共用 jq mock。 Co-Authored-By: Claude Opus 4.8 (1M context) --- tests/entrypoint_pagination.sh | 99 ++++++------------------------ tests/entrypoint_tag_cleanup.sh | 104 ++++++++++++++++++++++++++++++++ tests/lib/jq_mock.py | 98 ++++++++++++++++++++++++++++++ 3 files changed, 222 insertions(+), 79 deletions(-) create mode 100644 tests/entrypoint_tag_cleanup.sh create mode 100644 tests/lib/jq_mock.py diff --git a/tests/entrypoint_pagination.sh b/tests/entrypoint_pagination.sh index a13ebf3..fe042cc 100644 --- a/tests/entrypoint_pagination.sh +++ b/tests/entrypoint_pagination.sh @@ -1,6 +1,9 @@ #!/usr/bin/env bash set -Eeuo pipefail +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +repo_root="$(cd "$script_dir/.." && pwd)" + tmpdir="$(mktemp -d)" trap 'rm -rf "$tmpdir"' EXIT @@ -22,14 +25,20 @@ if [[ " $* " == *" -X DELETE "* ]]; then exit 0 fi +# tags 端點沒有需要清理的 tag +if [[ "$last_arg" == */tags?* ]]; then + printf '%s' '[]' + exit 0 +fi + case "$last_arg" in - *page=1) + */releases?*page=1) printf '%s' '[{"id":4,"tag_name":"v4","name":"release-4","created_at":"2024-04-01T00:00:00Z"},{"id":3,"tag_name":"v3","name":"release-3","created_at":"2024-03-01T00:00:00Z"}]' ;; - *page=2) + */releases?*page=2) printf '%s' '[{"id":2,"tag_name":"v2","name":"release-2","created_at":"2024-02-01T00:00:00Z"},{"id":1,"tag_name":"v1","name":"release-1","created_at":"2024-01-01T00:00:00Z"}]' ;; - *page=3) + */releases?*page=3) printf '%s' '[]' ;; *) @@ -40,80 +49,7 @@ esac EOF chmod +x "$bin_dir/curl" -cat >"$bin_dir/jq.py" <<'PY' -#!/usr/bin/env python3 -import json -import re -import sys - -expr = "" -flags = set() -args = sys.argv[1:] - -while args: - current = args.pop(0) - if current in {"-e", "-c", "-r", "-s"}: - flags.add(current) - continue - if current == "--": - if not args: - raise SystemExit("missing jq expression") - expr = args.pop(0) - break - if current.startswith("-"): - flags.add(current) - continue - expr = current - break - -raw = sys.stdin.read() - -def dump(value): - if "-r" in flags and isinstance(value, (str, int, float)) and not isinstance(value, bool): - sys.stdout.write(str(value)) - else: - sys.stdout.write(json.dumps(value, separators=(",", ":"))) - -if expr == "length": - data = json.loads(raw or "null") - print(len(data)) - raise SystemExit(0) - -if expr == "add": - arrays = [json.loads(line) for line in raw.splitlines() if line.strip()] - merged = [] - for item in arrays: - merged.extend(item) - dump(merged) - raise SystemExit(0) - -if expr == "sort_by(.created_at) | reverse": - data = json.loads(raw or "[]") - dump(sorted(data, key=lambda item: item["created_at"], reverse=True)) - raise SystemExit(0) - -match = re.fullmatch(r"\.\[(\d+):\]", expr) -if match: - data = json.loads(raw or "[]") - dump(data[int(match.group(1)):]) - raise SystemExit(0) - -if expr == ".[]": - data = json.loads(raw or "[]") - for item in data: - dump(item) - sys.stdout.write("\n") - raise SystemExit(0) - -match = re.fullmatch(r"\.(id|tag_name|name)", expr) -if match: - data = json.loads(raw or "null") - value = data.get(match.group(1)) - dump(value) - raise SystemExit(0) - -raise SystemExit(f"unsupported jq expression: {expr}") -PY +cp "$script_dir/lib/jq_mock.py" "$bin_dir/jq.py" chmod +x "$bin_dir/jq.py" cat >"$bin_dir/jq" <<'EOF' @@ -129,7 +65,7 @@ GITEA_SERVER_URL="https://gitea.example.test" \ GITEA_REPOSITORY="owner/repo" \ KEEP_COUNT="2" \ RUNNER_TOKEN="" \ -bash ./entrypoint.sh >/dev/null +bash "$repo_root/entrypoint.sh" >/dev/null grep -q 'page=1' "$curl_log" grep -q 'page=2' "$curl_log" @@ -138,6 +74,11 @@ grep -q '/releases/2' "$curl_log" grep -q '/releases/1' "$curl_log" if grep -q '/releases/3' "$curl_log" || grep -q '/releases/4' "$curl_log"; then - printf 'unexpected deletion request in %s\n' "$curl_log" >&2 + printf 'unexpected release deletion request in %s\n' "$curl_log" >&2 + exit 1 +fi + +if grep -q '/tags/' "$curl_log"; then + printf 'unexpected tag deletion request in %s\n' "$curl_log" >&2 exit 1 fi diff --git a/tests/entrypoint_tag_cleanup.sh b/tests/entrypoint_tag_cleanup.sh new file mode 100644 index 0000000..3d3ad68 --- /dev/null +++ b/tests/entrypoint_tag_cleanup.sh @@ -0,0 +1,104 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +repo_root="$(cd "$script_dir/.." && pwd)" + +tmpdir="$(mktemp -d)" +trap 'rm -rf "$tmpdir"' EXIT + +curl_log="$tmpdir/curl.log" +bin_dir="$tmpdir/bin" +mkdir -p "$bin_dir" + +cat >"$bin_dir/curl" <<'EOF' +#!/usr/bin/env bash +set -Eeuo pipefail + +log_file="${CURL_LOG:?}" +printf '%s\n' "$*" >>"$log_file" + +last_arg="${!#}" + +if [[ " $* " == *" -X DELETE "* ]]; then + printf '204' + exit 0 +fi + +# 倉庫所有 tag:v1~v4 加上兩個未指定 release 的孤兒 tag +if [[ "$last_arg" == */tags?* ]]; then + case "$last_arg" in + *page=1) + printf '%s' '[{"name":"v4"},{"name":"v3"},{"name":"v2"},{"name":"v1"},{"name":"tmp-build"},{"name":"v0"}]' + ;; + *) + printf '%s' '[]' + ;; + esac + exit 0 +fi + +# /releases GET:刪除舊版本後重新取得時,只回傳仍保留的 release +if grep -Eq -- '-X DELETE .*/releases/[0-9]' "$log_file"; then + case "$last_arg" in + *page=1) + printf '%s' '[{"id":4,"tag_name":"v4","name":"release-4","created_at":"2024-04-01T00:00:00Z"},{"id":3,"tag_name":"v3","name":"release-3","created_at":"2024-03-01T00:00:00Z"}]' + ;; + *) + printf '%s' '[]' + ;; + esac + exit 0 +fi + +case "$last_arg" in + *page=1) + printf '%s' '[{"id":4,"tag_name":"v4","name":"release-4","created_at":"2024-04-01T00:00:00Z"},{"id":3,"tag_name":"v3","name":"release-3","created_at":"2024-03-01T00:00:00Z"}]' + ;; + *page=2) + printf '%s' '[{"id":2,"tag_name":"v2","name":"release-2","created_at":"2024-02-01T00:00:00Z"},{"id":1,"tag_name":"v1","name":"release-1","created_at":"2024-01-01T00:00:00Z"}]' + ;; + *) + printf '%s' '[]' + ;; +esac +EOF +chmod +x "$bin_dir/curl" + +cp "$script_dir/lib/jq_mock.py" "$bin_dir/jq.py" +chmod +x "$bin_dir/jq.py" + +cat >"$bin_dir/jq" <<'EOF' +#!/usr/bin/env bash +set -Eeuo pipefail +exec python3 "$0.py" "$@" +EOF +chmod +x "$bin_dir/jq" + +PATH="$bin_dir:$PATH" \ +CURL_LOG="$curl_log" \ +GITEA_SERVER_URL="https://gitea.example.test" \ +GITEA_REPOSITORY="owner/repo" \ +KEEP_COUNT="2" \ +RUNNER_TOKEN="" \ +bash "$repo_root/entrypoint.sh" >/dev/null + +# 舊版本 release 仍被刪除 +grep -q '/releases/2' "$curl_log" +grep -q '/releases/1' "$curl_log" + +# 未指定 release 的 tag(含被刪除 release 留下的 tag 與其他孤兒 tag)被刪除 +for tag in v2 v1 tmp-build v0; do + if ! grep -q "/tags/$tag" "$curl_log"; then + printf 'expected tag deletion /tags/%s not found in %s\n' "$tag" "$curl_log" >&2 + exit 1 + fi +done + +# 仍指定 release 的 tag 不可被刪除 +for tag in v4 v3; do + if grep -q "/tags/$tag" "$curl_log"; then + printf 'unexpected deletion of release-assigned tag /tags/%s in %s\n' "$tag" "$curl_log" >&2 + exit 1 + fi +done diff --git a/tests/lib/jq_mock.py b/tests/lib/jq_mock.py new file mode 100644 index 0000000..0f05284 --- /dev/null +++ b/tests/lib/jq_mock.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python3 +"""Minimal jq stand-in for entrypoint.sh tests. + +Only the jq expressions used by entrypoint.sh are implemented. Unknown +expressions fail loudly so new jq usage is noticed instead of silently +producing wrong results. +""" +import json +import re +import sys + +expr = "" +flags = set() +named_args = {} +args = sys.argv[1:] + +while args: + current = args.pop(0) + if current in {"-e", "-c", "-r", "-s"}: + flags.add(current) + continue + if current == "--arg": + key = args.pop(0) + value = args.pop(0) + named_args[key] = value + continue + if current == "--": + if not args: + raise SystemExit("missing jq expression") + expr = args.pop(0) + break + if current.startswith("-"): + flags.add(current) + continue + expr = current + break + +raw = sys.stdin.read() + + +def dump(value): + if "-r" in flags and isinstance(value, (str, int, float)) and not isinstance(value, bool): + sys.stdout.write(str(value)) + else: + sys.stdout.write(json.dumps(value, separators=(",", ":"))) + + +if expr == "length": + data = json.loads(raw or "null") + print(len(data)) + raise SystemExit(0) + +if expr == "add": + arrays = [json.loads(line) for line in raw.splitlines() if line.strip()] + merged = [] + for item in arrays: + merged.extend(item) + dump(merged) + raise SystemExit(0) + +if expr == "sort_by(.created_at) | reverse": + data = json.loads(raw or "[]") + dump(sorted(data, key=lambda item: item["created_at"], reverse=True)) + raise SystemExit(0) + +if expr == "[.[].tag_name]": + data = json.loads(raw or "[]") + dump([item["tag_name"] for item in data]) + raise SystemExit(0) + +match = re.fullmatch(r"any\(\.\[\]; \. == \$(\w+)\)", expr) +if match: + data = json.loads(raw or "[]") + needle = named_args[match.group(1)] + sys.stdout.write("true" if any(item == needle for item in data) else "false") + raise SystemExit(0) + +match = re.fullmatch(r"\.\[(\d+):\]", expr) +if match: + data = json.loads(raw or "[]") + dump(data[int(match.group(1)):]) + raise SystemExit(0) + +if expr == ".[]": + data = json.loads(raw or "[]") + for item in data: + dump(item) + sys.stdout.write("\n") + raise SystemExit(0) + +match = re.fullmatch(r"\.(id|tag_name|name)", expr) +if match: + data = json.loads(raw or "null") + value = data.get(match.group(1)) + dump(value) + raise SystemExit(0) + +raise SystemExit(f"unsupported jq expression: {expr}") -- 2.53.0 From e567759c066188d474633398bf147f2ab9299a2b Mon Sep 17 00:00:00 2001 From: Jeffery Date: Tue, 23 Jun 2026 16:18:41 +0800 Subject: [PATCH 3/3] =?UTF-8?q?chore(AI=20=E5=8A=A9=E7=90=86=E8=A8=AD?= =?UTF-8?q?=E5=AE=9A):=20=E7=A7=BB=E9=99=A4=20AI=20=E5=8A=A9=E7=90=86?= =?UTF-8?q?=E8=A8=AD=E5=AE=9A=E8=88=87=E6=8C=87=E7=A4=BA=E6=AA=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 移除 CLAUDE.md、GEMINI.md 與 .claude/.codex/.gemini/.amazonq 及 Copilot 的設定與指示檔。 Co-Authored-By: Claude Opus 4.8 (1M context) --- .amazonq/rules/triage-findings.md | 14 ------ .claude/skills/triage-findings/SKILL.md | 29 ------------ .codex/skills/triage-findings/SKILL.md | 45 ------------------- .../skills/triage-findings/agents/openai.yaml | 4 -- .gemini/skills/triage-findings/SKILL.md | 29 ------------ .github/copilot-instructions.md | 14 ------ .github/skills/triage-findings/SKILL.md | 14 ------ CLAUDE.md | 16 ------- GEMINI.md | 14 ------ 9 files changed, 179 deletions(-) delete mode 100644 .amazonq/rules/triage-findings.md delete mode 100644 .claude/skills/triage-findings/SKILL.md delete mode 100644 .codex/skills/triage-findings/SKILL.md delete mode 100644 .codex/skills/triage-findings/agents/openai.yaml delete mode 100644 .gemini/skills/triage-findings/SKILL.md delete mode 100644 .github/copilot-instructions.md delete mode 100644 .github/skills/triage-findings/SKILL.md delete mode 100644 CLAUDE.md delete mode 100644 GEMINI.md diff --git a/.amazonq/rules/triage-findings.md b/.amazonq/rules/triage-findings.md deleted file mode 100644 index 4b65ce1..0000000 --- a/.amazonq/rules/triage-findings.md +++ /dev/null @@ -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. diff --git a/.claude/skills/triage-findings/SKILL.md b/.claude/skills/triage-findings/SKILL.md deleted file mode 100644 index c4ab450..0000000 --- a/.claude/skills/triage-findings/SKILL.md +++ /dev/null @@ -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. diff --git a/.codex/skills/triage-findings/SKILL.md b/.codex/skills/triage-findings/SKILL.md deleted file mode 100644 index 21476cb..0000000 --- a/.codex/skills/triage-findings/SKILL.md +++ /dev/null @@ -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. diff --git a/.codex/skills/triage-findings/agents/openai.yaml b/.codex/skills/triage-findings/agents/openai.yaml deleted file mode 100644 index 6f59e2c..0000000 --- a/.codex/skills/triage-findings/agents/openai.yaml +++ /dev/null @@ -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." diff --git a/.gemini/skills/triage-findings/SKILL.md b/.gemini/skills/triage-findings/SKILL.md deleted file mode 100644 index c4ab450..0000000 --- a/.gemini/skills/triage-findings/SKILL.md +++ /dev/null @@ -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. diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md deleted file mode 100644 index f1a77ef..0000000 --- a/.github/copilot-instructions.md +++ /dev/null @@ -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`. diff --git a/.github/skills/triage-findings/SKILL.md b/.github/skills/triage-findings/SKILL.md deleted file mode 100644 index 8ca4117..0000000 --- a/.github/skills/triage-findings/SKILL.md +++ /dev/null @@ -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`. diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index fa2403d..0000000 --- a/CLAUDE.md +++ /dev/null @@ -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`. diff --git a/GEMINI.md b/GEMINI.md deleted file mode 100644 index 8ca4117..0000000 --- a/GEMINI.md +++ /dev/null @@ -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`. -- 2.53.0