fix(server): Doesn't properly detect when dev or next are ahead
All checks were successful
ci/woodpecker/push/cron-docker-builder Pipeline was successful
ci/woodpecker/push/push-next Pipeline was successful
ci/woodpecker/push/tag-created Pipeline was successful

Closes kemitix/git-next#23
This commit is contained in:
Paul Campbell 2024-04-10 18:02:04 +01:00
parent 3a761b5b21
commit 50a56aadee
4 changed files with 83 additions and 35 deletions

View file

@ -44,7 +44,10 @@ pub async fn validate_positions(
); );
return; return;
} }
let next = next_commits[0].clone(); let Some(next) = next_commits.first().cloned() else {
warn!("No commits on next branch '{}'", config.branches().next());
return;
};
let dev_has_next = commit_histories let dev_has_next = commit_histories
.dev .dev
.iter() .iter()
@ -66,7 +69,10 @@ pub async fn validate_positions(
); );
return; return;
} }
let dev = commit_histories.dev[0].clone(); let Some(dev) = commit_histories.dev.first().cloned() else {
warn!("No commits on dev branch '{}'", config.branches().dev());
return;
};
addr.do_send(StartMonitoring { addr.do_send(StartMonitoring {
main, main,
next, next,

View file

@ -80,7 +80,7 @@ impl Handler<LoadedConfig> for RepoActor {
} }
} }
#[derive(Message)] #[derive(Debug, Message)]
#[rtype(result = "()")] #[rtype(result = "()")]
pub struct StartMonitoring { pub struct StartMonitoring {
pub main: forge::Commit, pub main: forge::Commit,
@ -90,6 +90,7 @@ pub struct StartMonitoring {
} }
impl Handler<StartMonitoring> for RepoActor { impl Handler<StartMonitoring> for RepoActor {
type Result = (); type Result = ();
#[allow(clippy::cognitive_complexity)] // TODO: (#25) this function is complex
fn handle(&mut self, msg: StartMonitoring, ctx: &mut Self::Context) -> Self::Result { fn handle(&mut self, msg: StartMonitoring, ctx: &mut Self::Context) -> Self::Result {
info!("Monitoring started"); info!("Monitoring started");
let Some(repo_config) = self.config.clone() else { let Some(repo_config) = self.config.clone() else {
@ -101,13 +102,21 @@ impl Handler<StartMonitoring> for RepoActor {
let addr = ctx.address(); let addr = ctx.address();
let net = self.net.clone(); let net = self.net.clone();
info!(%msg.main, %msg.next, %msg.dev, "Checking positions");
let next_ahead_of_main = msg.main != msg.next; let next_ahead_of_main = msg.main != msg.next;
let dev_ahead_of_next = msg.next != msg.dev; let dev_ahead_of_next = msg.next != msg.dev;
info!(
?next_ahead_of_main,
?dev_ahead_of_next,
"Checking positions"
);
if next_ahead_of_main { if next_ahead_of_main {
info!("Next is ahead of main");
status::check_next(msg.next, repo_details, addr, net) status::check_next(msg.next, repo_details, addr, net)
.into_actor(self) .into_actor(self)
.wait(ctx); .wait(ctx);
} else if dev_ahead_of_next { } else if dev_ahead_of_next {
info!("Dev is ahead of next");
branch::advance_next( branch::advance_next(
msg.next, msg.next,
msg.dev_commit_history, msg.dev_commit_history,
@ -118,6 +127,7 @@ impl Handler<StartMonitoring> for RepoActor {
.into_actor(self) .into_actor(self)
.wait(ctx); .wait(ctx);
} else if self.webhook_id.is_none() { } else if self.webhook_id.is_none() {
info!("No webhook registered");
webhook::register(repo_details, addr, net) webhook::register(repo_details, addr, net)
.into_actor(self) .into_actor(self)
.wait(ctx) .wait(ctx)

View file

@ -1,4 +1,5 @@
use actix::prelude::*; use actix::prelude::*;
use gix::trace::warn;
use tracing::info; use tracing::info;
use crate::server::{ use crate::server::{
@ -25,10 +26,14 @@ pub async fn check_next(
Status::Pass => { Status::Pass => {
addr.do_send(AdvanceMainTo(next)); addr.do_send(AdvanceMainTo(next));
} }
Status::Pending => (), // TODO: (#22) wait and try again OR can webhook tell us when it's done, in Status::Pending => {
info!("Checks are pending");
} // TODO: (#22) wait and try again OR can webhook tell us when it's done, in
// which case we can do nothing here and wait for the webhook to trigger // which case we can do nothing here and wait for the webhook to trigger
Status::Fail => (), // TODO: (#21) reset next and wait for dev to be updated and this Status::Fail => {
// commit removed from the commit history before trying again warn!("Check have failed");
} // TODO: (#21) reset next and wait for dev to be updated and this
// commit removed from the commit history before trying again
} }
} }

View file

@ -1,6 +1,6 @@
use kxio::network; use kxio::network;
use terrors::OneOf; use terrors::OneOf;
use tracing::{debug, error, info, warn}; use tracing::{error, info, warn};
use crate::server::{actors::repo::status::Status, config::BranchName, forge}; use crate::server::{actors::repo::status::Status, config::BranchName, forge};
@ -13,9 +13,17 @@ pub async fn get_commit_histories(
config: &crate::server::config::RepoConfig, config: &crate::server::config::RepoConfig,
net: &kxio::network::Network, net: &kxio::network::Network,
) -> Result<CommitHistories, OneOf<(network::NetworkError,)>> { ) -> Result<CommitHistories, OneOf<(network::NetworkError,)>> {
let main = (get_commit_history(repo_details, &config.branches().main(), net).await)?; let main = (get_commit_history(repo_details, &config.branches().main(), None, net).await)?;
let next = (get_commit_history(repo_details, &config.branches().next(), net).await)?; let next =
let dev = (get_commit_history(repo_details, &config.branches().dev(), net).await)?; (get_commit_history(repo_details, &config.branches().next(), Some(&main[0]), net).await)?;
let dev =
(get_commit_history(repo_details, &config.branches().dev(), Some(&next[0]), net).await)?;
info!(
main = main.len(),
next = next.len(),
dev = dev.len(),
"Commit histories"
);
let histories = CommitHistories { main, next, dev }; let histories = CommitHistories { main, next, dev };
Ok(histories) Ok(histories)
} }
@ -24,39 +32,58 @@ pub async fn get_commit_histories(
async fn get_commit_history( async fn get_commit_history(
repo_details: &crate::server::config::RepoDetails, repo_details: &crate::server::config::RepoDetails,
branch_name: &BranchName, branch_name: &BranchName,
find_commit: Option<&forge::Commit>, // INFO: (#23) if [None] then get only one commit, if [Some] then get all commits up to this one or return an error
net: &kxio::network::Network, net: &kxio::network::Network,
) -> Result<Vec<forge::Commit>, OneOf<(network::NetworkError,)>> { ) -> Result<Vec<forge::Commit>, OneOf<(network::NetworkError,)>> {
let hostname = &repo_details.forge.hostname; let hostname = &repo_details.forge.hostname;
let path = &repo_details.repo; let path = &repo_details.repo;
let token = &repo_details.forge.token; let token = &repo_details.forge.token;
let url = network::NetUrl::new(format!( let mut page = 1;
"https://{hostname}/api/v1/repos/{path}/commits?sha={branch_name}&stat=false&files=false&token={token}" let limit = match find_commit {
Some(_) => 100,
None => 1,
};
let mut all_commits = Vec::new();
loop {
let url = network::NetUrl::new(format!(
"https://{hostname}/api/v1/repos/{path}/commits?sha={branch_name}&stat=false&verification=false&files=false&token={token}&page={page}&limit={limit}"
)); ));
debug!(%url, "Fetching commits"); info!(%url, "Fetching commits");
let request = network::NetRequest::new( let request = network::NetRequest::new(
network::RequestMethod::Get, network::RequestMethod::Get,
url, url,
network::NetRequestHeaders::new(), network::NetRequestHeaders::new(),
network::RequestBody::None, network::RequestBody::None,
network::ResponseType::Json, network::ResponseType::Json,
None, None,
network::NetRequestLogging::None, network::NetRequestLogging::None,
); );
let result = net.get::<Vec<Commit>>(request).await; let result = net.get::<Vec<Commit>>(request).await;
let response = result.map_err(|e| { let response = result.map_err(|e| {
error!(?e, "Failed to get commit history"); error!(?e, "Failed to get commit history");
OneOf::new(e) OneOf::new(e)
})?; })?;
let commits = response let commits = response
.response_body() .response_body()
.unwrap_or_default() .unwrap_or_default()
.into_iter() .into_iter()
.map(|commit| commit.sha) .map(|commit| commit.sha)
.map(|sha| forge::Commit { sha }) .map(|sha| forge::Commit { sha })
.collect(); .collect::<Vec<_>>();
Ok(commits) let found = find_commit.map_or(true, |find_commit| {
commits.iter().any(|commit| commit == find_commit)
});
let at_end = commits.len() < limit;
all_commits.extend(commits);
if found || at_end {
break;
}
page += 1;
}
Ok(all_commits)
} }
#[allow(dead_code)] #[allow(dead_code)]