Skip to content

Commit 4966835

Browse files
committed
Merge pull request 'Fix #2850: raise list_open_prs limit from 50 to 300' (#2854) from task/2850-list-open-prs-limit-300 into main
2 parents 6ad30bc + d795843 commit 4966835

2 files changed

Lines changed: 63 additions & 2 deletions

File tree

crates/terraphim_merge_coordinator/src/evaluator.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,4 +165,24 @@ mod tests {
165165
assert_eq!(e.verdict, EvalVerdict::Merge);
166166
assert!(e.fixes_issues.is_empty());
167167
}
168+
169+
#[test]
170+
fn evaluate_one_processes_51_prs_without_truncation() {
171+
// Regression test for issue #2850: ensure the evaluation loop does not
172+
// impose an artificial cap at position 50. With list_open_prs returning
173+
// up to OPEN_PRS_LIMIT (300) items, all PRs must receive a verdict.
174+
let prs: Vec<PrSummary> = (1u64..=51)
175+
.map(|n| pr(n, &format!("Fixes #{n}"), true))
176+
.collect();
177+
let evaluations: Vec<_> = prs.iter().map(evaluate_one).collect();
178+
assert_eq!(
179+
evaluations.len(),
180+
51,
181+
"all 51 PRs must receive an evaluation verdict"
182+
);
183+
// Spot-check: the PR at position 51 gets Merge (it is mergeable, clean)
184+
let last = &evaluations[50];
185+
assert_eq!(last.pr_index, 51);
186+
assert_eq!(last.verdict, EvalVerdict::Merge);
187+
}
168188
}

crates/terraphim_merge_coordinator/src/gitea.rs

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ use crate::types::MergeCoordinatorError;
1313

1414
const RETRY_DELAYS_SECS: &[u64] = &[1, 2, 4];
1515

16+
/// Maximum number of open PRs fetched per `list_open_prs` call.
17+
///
18+
/// Gitea's hard cap is 50 when no explicit limit is set; the API accepts up
19+
/// to 300. Using 300 ensures PRs beyond position 50 are not silently skipped
20+
/// by the evaluation loop (issue #2850).
21+
const OPEN_PRS_LIMIT: u32 = 300;
22+
1623
/// Minimal Gitea API client. Caller supplies the API token via env or
1724
/// secure storage; it is never written to logs.
1825
pub struct GiteaClient {
@@ -57,8 +64,8 @@ impl GiteaClient {
5764
repo: &str,
5865
) -> Result<Vec<PrSummary>, MergeCoordinatorError> {
5966
let url = format!(
60-
"{}/api/v1/repos/{}/{}/pulls?state=open&limit=50",
61-
self.base_url, owner, repo
67+
"{}/api/v1/repos/{}/{}/pulls?state=open&limit={}",
68+
self.base_url, owner, repo, OPEN_PRS_LIMIT
6269
);
6370
let resp = self.get_with_retry(&url).await?;
6471
let prs = resp
@@ -202,4 +209,38 @@ mod tests {
202209
fn retry_delays_are_one_two_four_seconds() {
203210
assert_eq!(RETRY_DELAYS_SECS, &[1u64, 2, 4]);
204211
}
212+
213+
#[test]
214+
fn open_prs_limit_exceeds_gitea_default_of_50() {
215+
assert!(
216+
OPEN_PRS_LIMIT > 50,
217+
"OPEN_PRS_LIMIT must exceed 50 so PRs beyond position 50 are not silently dropped"
218+
);
219+
}
220+
221+
#[test]
222+
fn open_prs_limit_within_gitea_max_page_size() {
223+
assert!(
224+
OPEN_PRS_LIMIT <= 300,
225+
"Gitea max page size is 300; limit must not exceed it"
226+
);
227+
}
228+
229+
#[test]
230+
fn pr_summary_vec_of_51_items_deserialises() {
231+
// Construct JSON array with 51 items to verify no artificial truncation
232+
// happens at the deserialization layer.
233+
let items: String = (1u64..=51)
234+
.map(|n| format!(r#"{{"number":{n},"title":"PR {n}","state":"open"}}"#))
235+
.collect::<Vec<_>>()
236+
.join(",");
237+
let json = format!("[{items}]");
238+
let prs: Vec<PrSummary> = serde_json::from_str(&json).unwrap();
239+
assert_eq!(
240+
prs.len(),
241+
51,
242+
"all 51 PRs must be present after deserialisation"
243+
);
244+
assert_eq!(prs[50].number, 51, "PR at position 51 must be present");
245+
}
205246
}

0 commit comments

Comments
 (0)