Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- The contributor-lane automerge sweep now treats a PR with more changed files than GitHub's files API returns (3000) as a standing `files-evidence` skip instead of re-warning every sweep.
7 changes: 7 additions & 0 deletions src/pkg/github/automerge/automerge_contributor_lane.go
Original file line number Diff line number Diff line change
Expand Up @@ -1405,6 +1405,13 @@ func (c *Engine) evaluateContributorLanePR(ctx context.Context, displayRepo, own
c.info("contributor-lane admitted", "repo", displayRepo, "pr", number, "author", author, "reason", "contributor-lane:auto-promoted", "merged_prs", claim.AutoPromoted, "scope", contributorAutoPromotionScopeName(claim.AutoPromotedHiveWide), "repos", claim.AutoPromotedRepos)
}
files, err := ListChangedFiles(caller, c.gh, owner, repo, pr)
if errors.Is(err, hgithub.ErrIncompletePRFileList) {
// More changed files than GitHub's files API will ever return: the
// diff fences cannot be read on any tick, so this is a standing
// verdict (fail closed, nil error) like adoptionDiffRefusal's, not a
// transient fault re-WARNed every sweep (hivecommons/hive#18121).
return eval, contributorLaneReasonFilesEvidence, nil
}
if err != nil {
return eval, contributorLaneReasonFilesEvidence, err
}
Expand Down
7 changes: 7 additions & 0 deletions src/pkg/github/automerge/automerge_contributor_lane_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ type contributorLaneFixture struct {
omitAssociation bool
files []map[string]any
filesStatus int
changedFiles int // changed_files on the PR payload; 0 omits it
listStatus int
getStatus int
recheckHeadSHA string
Expand Down Expand Up @@ -219,6 +220,9 @@ func newContributorLaneAPI(t *testing.T, fx *contributorLaneFixture) *httptest.S
if !fx.omitAssociation {
p["author_association"] = association
}
if fx.changedFiles != 0 {
p["changed_files"] = fx.changedFiles
}
if fx.headCommittedAt != "" {
p["updated_at"] = fx.headCommittedAt
}
Expand Down Expand Up @@ -760,6 +764,9 @@ func TestTrySweepContributorLanePRSkipReasons(t *testing.T) {
wantMerges: 1,
},
{name: "files fetch error", mutate: func(fx *contributorLaneFixture) { fx.filesStatus = http.StatusInternalServerError }, wantReason: contributorLaneReasonFilesEvidence, wantErr: true},
// More changed files than the files API returns is a standing
// verdict, not a transient error re-WARNed every sweep (#18121).
{name: "incomplete files list", mutate: func(fx *contributorLaneFixture) { fx.changedFiles = 5204 }, wantReason: contributorLaneReasonFilesEvidence},
{name: "claim comments fetch error", mutate: func(fx *contributorLaneFixture) { fx.issueCommentsSt = http.StatusInternalServerError }, wantReason: "claim-comments-fetch", wantErr: true},
{
name: "reporter-trust hold",
Expand Down
9 changes: 9 additions & 0 deletions src/pkg/github/automerge/automerge_relay_gate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,15 @@ func TestRelayMergeRefusalFailsClosed(t *testing.T) {
t.Fatalf("err = %v, want lane evidence error", err)
}
})
t.Run("incomplete files list refuses", func(t *testing.T) {
fx := validContributorFixture()
fx.changedFiles = 5204
engine, _ := relayGateEngine(t, &fx, defaultContributorLanePolicy(), Options{})
refusal, err := engine.RelayMergeRefusal(context.Background(), "widget", 7, "sha7")
if err != nil || !strings.Contains(refusal, contributorLaneReasonFilesEvidence) {
t.Fatalf("refusal=%q err=%v, want standing files-evidence refusal", refusal, err)
}
})
}

func TestRelayMergeRefusalText(t *testing.T) {
Expand Down
Loading