Compare commits

..

2 commits

Author SHA1 Message Date
0622e6092b feat(repo/branch): update next branch when not based on main
All checks were successful
ci/woodpecker/push/push-next Pipeline was successful
ci/woodpecker/push/tag-created Pipeline was successful
ci/woodpecker/push/cron-docker-builder Pipeline was successful
Closes kemitix/git-next#41
2024-04-13 15:26:45 +01:00
2055421067 refactor(repo/branch): extract get_commit_histories
All checks were successful
ci/woodpecker/push/tag-created Pipeline was successful
ci/woodpecker/push/push-next Pipeline was successful
ci/woodpecker/push/cron-docker-builder Pipeline was successful
2024-04-13 15:22:23 +01:00

View file

@ -1,9 +1,15 @@
use actix::prelude::*; use actix::prelude::*;
use kxio::network; use kxio::network::{self, Network};
use tracing::{error, info, warn}; use tracing::{error, info, warn};
use crate::server::{actors::repo::ValidateRepo, config, forge, git::Git, types::ResetForce}; use crate::server::{
actors::repo::ValidateRepo,
config::{self, RepoConfig, RepoDetails},
forge::{self, CommitHistories},
git::Git,
types::ResetForce,
};
use super::{RepoActor, StartMonitoring}; use super::{RepoActor, StartMonitoring};
@ -15,16 +21,8 @@ pub async fn validate_positions(
git: Git, git: Git,
net: network::Network, net: network::Network,
) { ) {
let commit_histories = match repo_details.forge.forge_type { // Collect Commit Histories for `main`, `next` and `dev` branches
#[cfg(feature = "forgejo")] let commit_histories = get_commit_histories(&repo_details, &config, &net).await;
config::ForgeType::ForgeJo => {
forge::forgejo::get_commit_histories(&repo_details, &config, &net).await
}
#[cfg(test)]
config::ForgeType::MockForge => {
forge::mock::get_commit_histories(&repo_details, &config, &net).await
}
};
let commit_histories = match commit_histories { let commit_histories = match commit_histories {
Ok(commit_histories) => commit_histories, Ok(commit_histories) => commit_histories,
Err(err) => { Err(err) => {
@ -33,6 +31,8 @@ pub async fn validate_positions(
return; return;
} }
}; };
// Validations
let Some(main) = commit_histories.main.first().cloned() else { let Some(main) = commit_histories.main.first().cloned() else {
warn!("No commits on main branch '{}'", config.branches().main()); warn!("No commits on main branch '{}'", config.branches().main());
revalidate_positions(addr).await; revalidate_positions(addr).await;
@ -47,15 +47,7 @@ pub async fn validate_positions(
let next_is_ancestor_of_dev = commit_histories.dev.iter().any(|dev| dev == &next); let next_is_ancestor_of_dev = commit_histories.dev.iter().any(|dev| dev == &next);
if !next_is_ancestor_of_dev { if !next_is_ancestor_of_dev {
info!("Next is not an ancestor of dev - resetting next to main"); info!("Next is not an ancestor of dev - resetting next to main");
let reset = git.reset( reset_next_to_main(next, main, &repo_details, &config, &git);
&config.branches().next(),
main.into(),
ResetForce::Force(next.into()),
&repo_details,
);
if let Err(err) = reset {
warn!(?err, "Failed");
}
revalidate_positions(addr).await; revalidate_positions(addr).await;
return; return;
} }
@ -67,10 +59,11 @@ pub async fn validate_positions(
.collect::<Vec<_>>(); .collect::<Vec<_>>();
if !next_commits.contains(&main) { if !next_commits.contains(&main) {
warn!( warn!(
"Main branch '{}' is not on the same commit as next branch '{}', or it's parent", "Main branch '{}' is not on the same commit as next branch '{}', or it's parent - resetting next to main",
config.branches().main(), config.branches().main(),
config.branches().next() config.branches().next()
); );
reset_next_to_main(next, main, &repo_details, &config, &git);
revalidate_positions(addr).await; revalidate_positions(addr).await;
return; return;
} }
@ -85,7 +78,7 @@ pub async fn validate_positions(
.any(|commit| commit == &next_commits[0]); .any(|commit| commit == &next_commits[0]);
if !dev_has_next { if !dev_has_next {
warn!( warn!(
"Dev branch '{}' is not based on next branch '{}'", "Dev branch '{}' is not based on next branch '{}' - next branch will be updated shortly",
config.branches().dev(), config.branches().dev(),
config.branches().next() config.branches().next()
); );
@ -95,9 +88,10 @@ pub async fn validate_positions(
let dev_has_main = commit_histories.dev.iter().any(|commit| commit == &main); let dev_has_main = commit_histories.dev.iter().any(|commit| commit == &main);
if !dev_has_main { if !dev_has_main {
warn!( warn!(
"Dev branch '{}' is not based on main branch '{}'", "Dev branch '{}' is not based on main branch '{}' - user should rebase onto main branch '{}'",
config.branches().dev(), config.branches().dev(),
config.branches().main() config.branches().main(),
config.branches().main(),
); );
revalidate_positions(addr).await; revalidate_positions(addr).await;
return; return;
@ -115,6 +109,41 @@ pub async fn validate_positions(
}); });
} }
async fn get_commit_histories(
repo_details: &RepoDetails,
config: &RepoConfig,
net: &Network,
) -> Result<CommitHistories, network::NetworkError> {
match repo_details.forge.forge_type {
#[cfg(feature = "forgejo")]
config::ForgeType::ForgeJo => {
forge::forgejo::get_commit_histories(repo_details, config, net).await
}
#[cfg(test)]
config::ForgeType::MockForge => {
forge::mock::get_commit_histories(repo_details, config, net).await
}
}
}
fn reset_next_to_main(
next: forge::Commit,
main: forge::Commit,
repo_details: &RepoDetails,
repo_config: &RepoConfig,
git: &Git,
) {
let reset = git.reset(
&repo_config.branches().next(),
main.into(),
ResetForce::Force(next.into()),
repo_details,
);
if let Err(err) = reset {
warn!(?err, "Failed");
}
}
async fn revalidate_positions(addr: Addr<RepoActor>) { async fn revalidate_positions(addr: Addr<RepoActor>) {
// TODO : (#18) sleep and restart while we don't have webhooks // TODO : (#18) sleep and restart while we don't have webhooks
tokio::time::sleep(std::time::Duration::from_secs(10)).await; tokio::time::sleep(std::time::Duration::from_secs(10)).await;