Require git proof before prune deletes a branch
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful

A merged or closed PR no longer authorises a delete on its own: HEAD must
be contained in the PR's head commit or in origin/<branch>, otherwise the
worktree goes and the branch stays. Branch deletion runs `git branch -d`
first and falls back to -D only for a proven branch.

Reword the cherry check to say patches reached the default branch's
history, print the verdict --keep-branches will actually perform, and warn
when a PR listing hits the pagination cap instead of reading it as "no PR".
This commit is contained in:
2026-09-10 00:00:22 +10:00
parent 4bbeaae8f0
commit c1c02c01cf
7 changed files with 249 additions and 47 deletions
+24
View File
@@ -290,6 +290,30 @@ func TestListPRsPaginates(t *testing.T) {
}
}
// A listing that fills every page is truncated: the caller must be told rather
// than treating a partial view as the whole repo.
func TestListPRsReportsTruncation(t *testing.T) {
mux := http.NewServeMux()
mux.HandleFunc("/api/v1/repos/unkin/repo/pulls", func(w http.ResponseWriter, r *http.Request) {
full := make([]string, 0, prPageSize)
for i := 0; i < prPageSize; i++ {
full = append(full, fmt.Sprintf(`{"number":%s,"state":"open"}`, r.URL.Query().Get("page")))
}
_, _ = io.WriteString(w, "["+strings.Join(full, ",")+"]")
})
srv := httptest.NewServer(mux)
defer srv.Close()
c := &GiteaClient{BaseURL: srv.URL, HTTP: srv.Client()}
prs, err := c.ListPRs("unkin/repo", "all")
if !errors.Is(err, ErrPRListTruncated) {
t.Fatalf("ListPRs err = %v, want ErrPRListTruncated", err)
}
if len(prs) != maxPRPages*prPageSize {
t.Errorf("got %d PRs, want %d", len(prs), maxPRPages*prPageSize)
}
}
func TestGiteaAPIError(t *testing.T) {
mux := http.NewServeMux()
mux.HandleFunc("/api/v1/repos/unkin/repo/pulls", func(w http.ResponseWriter, r *http.Request) {
+8 -3
View File
@@ -150,8 +150,13 @@ const (
maxPRPages = 20
)
// ErrPRListTruncated reports that a listing hit the page cap, so the returned
// pull requests are only the most recent ones and older PRs went unseen.
var ErrPRListTruncated = errors.New("pull request listing truncated at the page cap")
// ListPRs lists a repo's pull requests in the given state ("open", "closed" or
// "all"), following pagination.
// "all"), following pagination. A repo with more PRs than the page cap returns
// the PRs it did read alongside ErrPRListTruncated.
func (c *GiteaClient) ListPRs(repoPath, state string) ([]PullRequest, error) {
if state == "" {
state = "all"
@@ -165,10 +170,10 @@ func (c *GiteaClient) ListPRs(repoPath, state string) ([]PullRequest, error) {
}
all = append(all, batch...)
if len(batch) < prPageSize {
break
return all, nil
}
}
return all, nil
return all, fmt.Errorf("%s: %w after %d pull requests", repoPath, ErrPRListTruncated, len(all))
}
// PRHeadBranch returns the branch a PR was opened from. Gitea rewrites head.ref