git-next/crates/forge-github/src/commit.rs

67 lines
2.6 KiB
Rust
Raw Normal View History

//
use crate::{self as github, GithubState};
use git::forge::commit::Status;
use git_next_git as git;
use github::GithubStatus;
use kxio::network;
/// Checks the results of any (e.g. CI) status checks for the commit.
///
/// GitHub: https://docs.github.com/en/rest/commits/statuses?apiVersion=2022-11-28#list-commit-statuses-for-a-reference
pub async fn status(github: &github::Github, commit: &git::Commit) -> git::forge::commit::Status {
let repo_details = &github.repo_details;
let hostname = repo_details.forge.hostname();
let repo_path = &repo_details.repo_path;
let api_token = &repo_details.forge.token();
use secrecy::ExposeSecret;
let token = api_token.expose_secret();
let url = network::NetUrl::new(format!(
"https://api.{hostname}/repos/{repo_path}/commits/{commit}/statuses"
));
let headers = network::NetRequestHeaders::new()
.with("X-GitHub-Api-Version", "2022-11-28")
.with("Authorization", format!("Bearer: {token}").as_str());
let request = network::NetRequest::new(
network::RequestMethod::Get,
url,
headers,
network::RequestBody::None,
network::ResponseType::Json,
None,
network::NetRequestLogging::None,
);
let result = github.net.get::<Vec<GithubStatus>>(request).await;
match result {
Ok(response) => response
.response_body()
.and_then(|statuses| {
statuses
.into_iter()
.map(|status| match status.state {
GithubState::Success => Status::Pass,
GithubState::Pending => Status::Pending,
GithubState::Failure => Status::Fail,
GithubState::Error => Status::Fail,
GithubState::Blank => Status::Pending,
})
.reduce(|l, r| match (l, r) {
(Status::Pass, Status::Pass) => Status::Pass,
(_, Status::Fail) => Status::Fail,
(Status::Fail, _) => Status::Fail,
(_, Status::Pending) => Status::Pending,
(Status::Pending, _) => Status::Pending,
})
})
.unwrap_or_else(|| {
tracing::warn!("No status checks configured for 'next' branch",);
Status::Pass
}),
Err(e) => {
tracing::warn!(?e, "Failed to get commit status");
Status::Pending // assume issue is transient and allow retry
}
}
}