feat/change-requests/pr-comment-replies #28
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "jsc-gitea",
|
"name": "jsc-gitea",
|
||||||
"version": "0.1.6",
|
"version": "0.1.7",
|
||||||
"description": "Gitea API 工具、Wiki 讀寫、議題轉換、HTML 匯出與存取庫批次同步",
|
"description": "Gitea API 工具、Wiki 讀寫、議題轉換、HTML 匯出與存取庫批次同步",
|
||||||
"skills": "./skills",
|
"skills": "./skills",
|
||||||
"author": {
|
"author": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "jsc-gitea",
|
"name": "jsc-gitea",
|
||||||
"version": "0.1.6",
|
"version": "0.1.7",
|
||||||
"description": "Gitea API 工具、Wiki 讀寫、議題轉換、HTML 匯出與存取庫批次同步",
|
"description": "Gitea API 工具、Wiki 讀寫、議題轉換、HTML 匯出與存取庫批次同步",
|
||||||
"skills": "./skills"
|
"skills": "./skills"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ gitea.sh pr-get <owner>/<repo> <pr-index> # 印出 PR 的標題、base
|
|||||||
# 前三行固定 title、base、body 三個標記,第 4 行起是描述原文
|
# 前三行固定 title、base、body 三個標記,第 4 行起是描述原文
|
||||||
gitea.sh pr-edit <owner>/<repo> <pr-index> <title> <body-file>
|
gitea.sh pr-edit <owner>/<repo> <pr-index> <title> <body-file>
|
||||||
# 更新 PR 的標題與描述;描述從檔案讀,裝得下多行
|
# 更新 PR 的標題與描述;描述從檔案讀,裝得下多行
|
||||||
gitea.sh pr-comments <owner>/<repo> <pr-index> # 印出所有留言(issue 留言、審查評語、行內留言),依時間排序
|
gitea.sh pr-comments <owner>/<repo> <pr-index> # 印出所有留言(issue 留言、審查評語、行內留言),第三欄帶 #id,依時間排序
|
||||||
|
gitea.sh comment-reply <owner>/<repo> <pr-index> <issue|review|inline> <comment-id> <body-file>
|
||||||
|
# 回覆本輪處理過的 PR 留言;inline 走 review comment reply,其餘補一則 PR 留言
|
||||||
gitea.sh pr-depend <owner>/<repo> <pr-index> <dep-owner>/<dep-repo> <dep-index>
|
gitea.sh pr-depend <owner>/<repo> <pr-index> <dep-owner>/<dep-repo> <dep-index>
|
||||||
# 把 PR 掛上前置 PR 依賴;依賴未關閉前 Gitea 會阻擋合併
|
# 把 PR 掛上前置 PR 依賴;依賴未關閉前 Gitea 會阻擋合併
|
||||||
gitea.sh repo-set <owner>/<repo> <description> [website] # 設定 repo 描述與網頁
|
gitea.sh repo-set <owner>/<repo> <description> [website] # 設定 repo 描述與網頁
|
||||||
@@ -109,7 +111,7 @@ Gitea wiki 頁讀寫的統一入口:依頁面類型(QUESTION / PLAN / ANALYZ
|
|||||||
|
|
||||||
### `repo-sync`
|
### `repo-sync`
|
||||||
|
|
||||||
存取庫批次同步:列出 owner → 使用者選擇 → 逐 repo(sub agent)呼叫 `tools/repo-sync.sh` clone 或更新;回報 `dirty {分支}` 的存取庫交給 `jsc-git:pr`,base 直接用腳本帶出來的那個分支。
|
存取庫批次同步:列出 owner → 使用者選擇 → 逐 repo(sub agent)呼叫 `tools/repo-sync.sh` clone 或更新;回報 `dirty {分支}` 的存取庫交給 `jsc-git:pr`,base 直接用腳本帶出來的那個分支;PR 依 `jsc-meta/references/pr-report.md` 集中成表。
|
||||||
|
|
||||||
### `html-export`
|
### `html-export`
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "jsc-gitea",
|
"name": "jsc-gitea",
|
||||||
"version": "0.1.6",
|
"version": "0.1.7",
|
||||||
"description": "Gitea API 工具、Wiki 讀寫、議題轉換、HTML 匯出與存取庫批次同步",
|
"description": "Gitea API 工具、Wiki 讀寫、議題轉換、HTML 匯出與存取庫批次同步",
|
||||||
"skills": "./skills/"
|
"skills": "./skills/"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,5 +13,5 @@ description: Batch-sync all readable repos of a chosen Gitea owner into the work
|
|||||||
4. Run `tools/gitea.sh repos {owner}` to list every readable `{repo}` under that owner. Done when the command has printed the full `{owner}/{repo}` list for the chosen owner.
|
4. Run `tools/gitea.sh repos {owner}` to list every readable `{repo}` under that owner. Done when the command has printed the full `{owner}/{repo}` list for the chosen owner.
|
||||||
5. Sync each `{repo}` one by one. This step **MUST run as a sub agent** (one sub agent per repo):
|
5. Sync each `{repo}` one by one. This step **MUST run as a sub agent** (one sub agent per repo):
|
||||||
1. Run `tools/repo-sync.sh {owner}/{repo}`. The script owns the clone-versus-pull decision and the base-branch precedence, so run no `git clone`, `git checkout` or `git pull` by hand, and derive no branch name yourself. Route on its single line of output: `cloned` or `updated` → this repo is done; `dirty {branch}` → go to substep 2; `failed {reason}` → record that reason and stop this repo. Done when exactly one of those four outcomes is recorded for this repo.
|
1. Run `tools/repo-sync.sh {owner}/{repo}`. The script owns the clone-versus-pull decision and the base-branch precedence, so run no `git clone`, `git checkout` or `git pull` by hand, and derive no branch name yourself. Route on its single line of output: `cloned` or `updated` → this repo is done; `dirty {branch}` → go to substep 2; `failed {reason}` → record that reason and stop this repo. Done when exactly one of those four outcomes is recorded for this repo.
|
||||||
2. `dirty {branch}` → call `jsc-git:pr` with `{branch}` from that same output line as the base, passed through verbatim. It commits, branches, pushes and opens the PR itself, so add none of those steps. Done when `jsc-git:pr` returns the PR URL.
|
2. `dirty {branch}` → call `jsc-git:pr` with `{branch}` from that same output line as the base, passed through verbatim. It commits, branches, pushes and opens the PR itself, so add none of those steps. Done when `jsc-git:pr` returns the PR URL and reports it with the table format in `jsc-meta/references/pr-report.md`.
|
||||||
6. Report the sync result for every repo: cloned, updated, PR URL, or the failure reason. Done when every `{repo}` from step 4 carries one of those four results.
|
6. Report the sync result for every repo: cloned, updated, PR table row, or the failure reason. Done when every `{repo}` from step 4 carries one of those four results, and all PR rows share one table when more than one PR exists.
|
||||||
|
|||||||
+29
-5
@@ -17,7 +17,9 @@
|
|||||||
# gitea.sh pr-status <owner>/<repo> <pr-index> # 印出「{state} {merged} {mergeable}」
|
# gitea.sh pr-status <owner>/<repo> <pr-index> # 印出「{state} {merged} {mergeable}」
|
||||||
# gitea.sh pr-get <owner>/<repo> <pr-index> # 印出 PR 的標題、base 分支與描述,供比對用
|
# gitea.sh pr-get <owner>/<repo> <pr-index> # 印出 PR 的標題、base 分支與描述,供比對用
|
||||||
# gitea.sh pr-edit <owner>/<repo> <pr-index> <title> <body-file> # 更新 PR 的標題與描述
|
# gitea.sh pr-edit <owner>/<repo> <pr-index> <title> <body-file> # 更新 PR 的標題與描述
|
||||||
# gitea.sh pr-comments <owner>/<repo> <pr-index> # 印出所有留言(issue 留言、審查評語、行內留言),依時間排序
|
# gitea.sh pr-comments <owner>/<repo> <pr-index> # 印出所有留言(issue 留言、審查評語、行內留言),第三欄帶 #id
|
||||||
|
# gitea.sh comment-reply <owner>/<repo> <pr-index> <issue|review|inline> <comment-id> <body-file>
|
||||||
|
# 回覆本輪處理過的 PR 留言;inline 走 review comment reply,其餘補一則 PR 留言
|
||||||
# gitea.sh pr-depend <owner>/<repo> <pr-index> <dep-owner>/<dep-repo> <dep-index>
|
# gitea.sh pr-depend <owner>/<repo> <pr-index> <dep-owner>/<dep-repo> <dep-index>
|
||||||
# 把 PR 掛上前置 PR 依賴;依賴未關閉前 Gitea 會阻擋合併
|
# 把 PR 掛上前置 PR 依賴;依賴未關閉前 Gitea 會阻擋合併
|
||||||
# gitea.sh repo-set <owner>/<repo> <description> [website] # 設定 repo 描述與網頁
|
# gitea.sh repo-set <owner>/<repo> <description> [website] # 設定 repo 描述與網頁
|
||||||
@@ -258,15 +260,16 @@ print(json.dumps({"title":sys.argv[1],"body":open(sys.argv[2],encoding="utf-8").
|
|||||||
rm -f "$tmp"
|
rm -f "$tmp"
|
||||||
echo "OK $or#$idx" ;;
|
echo "OK $or#$idx" ;;
|
||||||
pr-comments)
|
pr-comments)
|
||||||
# 印出 PR 的所有留言,每行「{時間}<TAB>{作者}<TAB>{類型}<TAB>{內容單行化}」。
|
# 印出 PR 的所有留言,每行「{時間}<TAB>{作者}<TAB>{類型}#{id}<TAB>{內容單行化}」。
|
||||||
# 三個來源都要讀:issue 留言、review 本體的評語、review 內逐行的程式碼留言。
|
# 三個來源都要讀:issue 留言、review 本體的評語、review 內逐行的程式碼留言。
|
||||||
# 只讀 issue 留言會漏掉真正的審查意見,那正是需要修正的部分。
|
# 只讀 issue 留言會漏掉真正的審查意見,那正是需要修正的部分。
|
||||||
|
# 類型欄保留在第三欄,僅追加 id;呼叫端用第一欄做 since 比對時不受影響。
|
||||||
or="${1:?owner/repo required}"; idx="${2:?pr index required}"
|
or="${1:?owner/repo required}"; idx="${2:?pr index required}"
|
||||||
{ req GET "/repos/$or/issues/$idx/comments?limit=100" | python3 -c '
|
{ req GET "/repos/$or/issues/$idx/comments?limit=100" | python3 -c '
|
||||||
import json,sys
|
import json,sys
|
||||||
for c in json.load(sys.stdin):
|
for c in json.load(sys.stdin):
|
||||||
body=" ".join((c.get("body") or "").split())
|
body=" ".join((c.get("body") or "").split())
|
||||||
if body: print("%s\t%s\t留言\t%s" % (c.get("created_at",""), (c.get("user") or {}).get("login","?"), body))
|
if body: print("%s\t%s\t留言#%s\t%s" % (c.get("created_at",""), (c.get("user") or {}).get("login","?"), c.get("id","?"), body))
|
||||||
'
|
'
|
||||||
reviews=$(req GET "/repos/$or/pulls/$idx/reviews?limit=100")
|
reviews=$(req GET "/repos/$or/pulls/$idx/reviews?limit=100")
|
||||||
printf '%s' "$reviews" | python3 -c '
|
printf '%s' "$reviews" | python3 -c '
|
||||||
@@ -276,7 +279,7 @@ for r in json.load(sys.stdin):
|
|||||||
st=r.get("state","")
|
st=r.get("state","")
|
||||||
# 沒有評語的審查照樣要印:APPROVED 代表可以合併,REQUEST_CHANGES 代表被要求修改,
|
# 沒有評語的審查照樣要印:APPROVED 代表可以合併,REQUEST_CHANGES 代表被要求修改,
|
||||||
# 兩者都是呼叫端要據以決策的事實,過濾掉會看不見 PR 真正的狀態。
|
# 兩者都是呼叫端要據以決策的事實,過濾掉會看不見 PR 真正的狀態。
|
||||||
print("%s\t%s\t審查(%s)\t%s" % (r.get("submitted_at",""), (r.get("user") or {}).get("login","?"), st, body or "(無評語)"))
|
print("%s\t%s\t審查#%s(%s)\t%s" % (r.get("submitted_at",""), (r.get("user") or {}).get("login","?"), r.get("id","?"), st, body or "(無評語)"))
|
||||||
'
|
'
|
||||||
for rid in $(printf '%s' "$reviews" | python3 -c '
|
for rid in $(printf '%s' "$reviews" | python3 -c '
|
||||||
import json,sys
|
import json,sys
|
||||||
@@ -289,10 +292,31 @@ try: d=json.load(sys.stdin)
|
|||||||
except Exception: raise SystemExit
|
except Exception: raise SystemExit
|
||||||
for c in d:
|
for c in d:
|
||||||
body=" ".join((c.get("body") or "").split())
|
body=" ".join((c.get("body") or "").split())
|
||||||
if body: print("%s\t%s\t行內(%s:%s)\t%s" % (c.get("created_at",""), (c.get("user") or {}).get("login","?"), c.get("path",""), c.get("original_position") or c.get("position") or "", body))
|
if body: print("%s\t%s\t行內#%s(%s:%s)\t%s" % (c.get("created_at",""), (c.get("user") or {}).get("login","?"), c.get("id","?"), c.get("path",""), c.get("original_position") or c.get("position") or "", body))
|
||||||
' || true
|
' || true
|
||||||
done
|
done
|
||||||
} | sort ;;
|
} | sort ;;
|
||||||
|
comment-reply)
|
||||||
|
or="${1:?owner/repo required}"; idx="${2:?pr index required}"
|
||||||
|
kind="${3:?kind required}"; cid="${4:?comment id required}"; body_file="${5:?body file required}"
|
||||||
|
[ -f "$body_file" ] || { echo "找不到回覆檔: $body_file" >&2; exit 2; }
|
||||||
|
case "$kind" in issue|review|inline) ;; *) echo "kind must be issue, review, or inline" >&2; exit 2 ;; esac
|
||||||
|
tmp=$(mktemp)
|
||||||
|
python3 -c '
|
||||||
|
import json,sys
|
||||||
|
print(json.dumps({"body":open(sys.argv[1],encoding="utf-8").read()}))
|
||||||
|
' "$body_file" > "$tmp"
|
||||||
|
case "$kind" in
|
||||||
|
inline)
|
||||||
|
path="/repos/$or/pulls/$idx/comments/$cid/replies" ;;
|
||||||
|
issue|review)
|
||||||
|
path="/repos/$or/issues/$idx/comments" ;;
|
||||||
|
esac
|
||||||
|
if ! out=$(req POST "$path" "$tmp"); then
|
||||||
|
rm -f "$tmp"; printf '%s\n' "$out" >&2; exit 4
|
||||||
|
fi
|
||||||
|
rm -f "$tmp"
|
||||||
|
printf '%s' "$out" | json_field html_url ;;
|
||||||
pr-depend)
|
pr-depend)
|
||||||
or="${1:?owner/repo required}"; idx="${2:?pr index required}"
|
or="${1:?owner/repo required}"; idx="${2:?pr index required}"
|
||||||
dep_or="${3:?dep owner/repo required}"; dep_idx="${4:?dep index required}"
|
dep_or="${3:?dep owner/repo required}"; dep_idx="${4:?dep index required}"
|
||||||
|
|||||||
Reference in New Issue
Block a user