fix: stalled PR 作者已交棒審核改判 reviewer-idle(agents #51)
considerPull 的 author-idle 分支缺少 #47 的交棒檢查,且既有 IsDeliveryReport 訊號為 issue 交付報告設計,PR 端「已就緒,可審閱+ @審核者」形態無對應訊號——fox#60 作者留言交棒後仍被誤判 author-idle。 新增 IsReviewHandoff(@目前審核者帳號 ∧ 就緒語,mention 邊界感知 避免 @chenyunda218 誤命中 chenyunda),considerPull 在判 author-idle 前檢查,命中改判 reviewer-idle,讓既有 48 小時改派規則自然適用。 gitea.py 側 _consider pull 分支以 _is_review_handoff 同步(另 PR)。
This commit is contained in:
@@ -201,3 +201,75 @@ func IsDeliveryReport(issueBody string, last *Comment) bool {
|
||||
}
|
||||
return deliveryHandoffRe.MatchString(body)
|
||||
}
|
||||
|
||||
// ── 審核交棒判定(agents #51,同步 gitea.py _is_review_handoff)──────────
|
||||
//
|
||||
// PR 作者的最後一則留言已把審核交棒給審核者(@審核者帳號+就緒語)時,
|
||||
// 停滯點不在作者:stalled 分類由 author-idle 改判 reviewer-idle,既有
|
||||
// 48 小時改派規則自然適用。案例:fox#60 作者留言「PR 已就緒,可審閱」
|
||||
// 並 @chenyunda218,teai stalled 仍判 author-idle——作者已無待辦。
|
||||
|
||||
var (
|
||||
// reviewReadyRe 對應 gitea.py _REVIEW_READY_RE:PR 端就緒語。
|
||||
reviewReadyRe = regexp.MustCompile(`已就緒|可審閱|請審閱`)
|
||||
)
|
||||
|
||||
// IsReviewHandoff 判定 PR 作者的最後一則留言是否已把審核交棒給審核者
|
||||
// (agents #51;gitea.py _is_review_handoff 的同語義實作)。
|
||||
//
|
||||
// 審核交棒=「@審核者帳號」∧「就緒語」同時命中:作者已表明 PR 就緒、
|
||||
// 明確點名目前指定的審核者,球在審核者——author-idle 改判 reviewer-idle。
|
||||
//
|
||||
// 只命中就緒語不算:進度回報(「快好了,即將就緒」)沒有點名對象,作者
|
||||
// 仍可能有待辦——保持 author-idle,修正不製造「丟一句已就緒就永不被催」
|
||||
// 的新死角。@的帳號不在目前審核者清單也不算:交棒對象需為實際審核者。
|
||||
func IsReviewHandoff(last *Comment, reviewers []string) bool {
|
||||
if last == nil {
|
||||
return false
|
||||
}
|
||||
body := last.Body
|
||||
if body == "" || len(reviewers) == 0 {
|
||||
return false
|
||||
}
|
||||
if !reviewReadyRe.MatchString(body) {
|
||||
return false
|
||||
}
|
||||
for _, r := range reviewers {
|
||||
if mentionsUser(body, r) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// mentionsUser 判定 body 是否 @ 了指定帳號(agents #51)。
|
||||
// 帳號字元後需為非帳號字元或文末,避免前綴碰撞——如 @chenyunda218
|
||||
// 被誤判為提及帳號 chenyunda(兩者可在同一組織並存)。
|
||||
func mentionsUser(body, name string) bool {
|
||||
if name == "" {
|
||||
return false
|
||||
}
|
||||
mention := "@" + name
|
||||
for from := 0; ; {
|
||||
idx := strings.Index(body[from:], mention)
|
||||
if idx < 0 {
|
||||
return false
|
||||
}
|
||||
end := from + idx + len(mention)
|
||||
if end >= len(body) || !isUsernameByte(body[end]) {
|
||||
return true
|
||||
}
|
||||
from = from + idx + 1
|
||||
}
|
||||
}
|
||||
|
||||
// isUsernameByte 判定位元組是否屬於 Gitea 帳號字元(字母數字與 _ . -)。
|
||||
func isUsernameByte(b byte) bool {
|
||||
switch {
|
||||
case b >= 'a' && b <= 'z', b >= 'A' && b <= 'Z', b >= '0' && b <= '9':
|
||||
return true
|
||||
case b == '_' || b == '.' || b == '-':
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user