Watch
0
0
Fork
You've already forked hyperhive
0

skip empty agent-config repos in the config-pr scan

This commit is contained in:
atlas 2026-11-01 19:01:55 +01:00 • committed by mara
commit ee591b0546

View file

@ -900,6 +900,9 @@ impl Client {
/// ///
/// A single repo's list failing does not fail the whole scan — logged and /// A single repo's list failing does not fail the whole scan — logged and
/// skipped, so one flaky repo can't blank out every other agent's status. /// skipped, so one flaky repo can't blank out every other agent's status.
/// Repos the listing marks `empty` are skipped without a PR call: forgejo
/// answers 404 for the PR list of a repo with no branches, and such a repo
/// cannot carry a PR.
pub async fn list_open_config_prs( pub async fn list_open_config_prs(
&self, &self,
) -> Result<std::collections::HashMap<String, ConfigPrStatus>> { ) -> Result<std::collections::HashMap<String, ConfigPrStatus>> {
@ -914,6 +917,9 @@ impl Client {
let Some(agent) = repo.name.as_deref() else { let Some(agent) = repo.name.as_deref() else {
continue; continue;
}; };
if repo.empty.unwrap_or(false) {
continue;
}
let query = RepoListPullRequestsQuery { let query = RepoListPullRequestsQuery {
state: Some(RepoListPullRequestsQueryState::Open), state: Some(RepoListPullRequestsQueryState::Open),
sort: None, sort: None,
@ -2771,6 +2777,58 @@ mod tests {
(Client { api, url }, seen) (Client { api, url }, seen)
} }
#[tokio::test]
async fn the_config_pr_scan_skips_empty_repos_without_a_pr_call() {
use axum::http::{StatusCode, Uri};
let seen = Arc::new(std::sync::Mutex::new(Vec::new()));
let recorded = Arc::clone(&seen);
let app = axum::Router::new().fallback(move |uri: Uri| {
recorded.lock().unwrap().push(uri.path().to_owned());
let (status, count, body) = match uri.path() {
"/api/v1/orgs/agent-configs/repos" => (
200,
"2",
r#"[{"name":"bare","empty":true},{"name":"full","empty":false}]"#,
),
"/api/v1/repos/agent-configs/full/pulls" => (
200,
"1",
r#"[{"number":4,"requested_reviewers":[],"html_url":"http://forge/agent-configs/full/pulls/4"}]"#,
),
_ => (404, "0", r#"{"message":"not found"}"#),
};
async move {
(
StatusCode::from_u16(status).unwrap(),
[("x-total-count", count)],
body,
)
}
});
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
let url = url::Url::parse(&format!("http://{}/", listener.local_addr().unwrap())).unwrap();
tokio::spawn(async move { axum::serve(listener, app).await });
let api = crate::forge::api::tests::fixed(url.clone(), "stub-token");
let client = Client { api, url };
let out = client.list_open_config_prs().await.unwrap();
assert_eq!(out.keys().collect::<Vec<_>>(), ["full"]);
assert_eq!(out["full"].pr_number, 4);
let paths = seen.lock().unwrap();
assert!(
paths
.iter()
.any(|p| p.ends_with("/repos/agent-configs/full/pulls"))
);
assert!(
!paths
.iter()
.any(|p| p.contains("/repos/agent-configs/bare/"))
);
}
/// One PR commit whose parent is `mb`. /// One PR commit whose parent is `mb`.
const ON_MB: &str = r#"[{"sha":"c1","parents":[{"sha":"mb"}]}]"#; const ON_MB: &str = r#"[{"sha":"c1","parents":[{"sha":"mb"}]}]"#;