use crate::{self as github, GithubState};
use git_next_core::git::{self, forge::commit::Status};
use github::GithubStatus;
pub async fn status(
github: &github::Github,
commit: &git::Commit,
) -> git::forge::webhook::Result<git::forge::commit::Status> {
let repo_details = &github.repo_details;
let hostname = repo_details.forge.hostname();
let repo_path = &repo_details.repo_path;
let url = format!("https://api.{hostname}/repos/{repo_path}/commits/{commit}/statuses");
let Ok(response) = github
.net
.get(url)
.headers(github::webhook::headers(repo_details.forge.token()))
.body("")
.send()
.await
else {
return Ok(Status::Pending);
};
let statuses = response.json::<Vec<GithubStatus>>().await?;
let result = statuses
.into_iter()
.map(|status| match status.state {
GithubState::Success => Status::Pass,
GithubState::Pending | GithubState::Blank => Status::Pending,
GithubState::Failure | GithubState::Error => Status::Fail,
})
.reduce(|l, r| match (l, r) {
(Status::Pass, Status::Pass) => Status::Pass,
(_, Status::Fail) | (Status::Fail, _) => Status::Fail,
(_, Status::Pending) | (Status::Pending, _) => Status::Pending,
(Status::Error(e1), Status::Error(e2)) => Status::Error(format!("{e1} / {e2}")),
(_, Status::Error(err)) | (Status::Error(err), _) => Status::Error(err),
})
.unwrap_or_else(|| {
tracing::warn!("No status checks configured for 'next' branch",);
Status::Pass
});
Ok(result)
}