2024-05-03 17:50:50 +01:00
|
|
|
use std::time::Duration;
|
|
|
|
|
|
|
|
use actix::prelude::*;
|
|
|
|
|
2024-04-16 22:21:55 +01:00
|
|
|
use tracing::{info, warn};
|
2024-04-09 18:18:19 +01:00
|
|
|
|
2024-05-11 18:57:18 +01:00
|
|
|
use crate::{
|
2024-05-08 07:34:35 +01:00
|
|
|
actors::repo::{LoadConfigFromRepo, RepoActor, ValidateRepo},
|
|
|
|
config::{self, RepoConfigSource},
|
|
|
|
gitforge,
|
2024-05-03 17:50:50 +01:00
|
|
|
};
|
2024-04-09 16:16:01 +01:00
|
|
|
|
2024-04-09 22:43:23 +01:00
|
|
|
// advance next to the next commit towards the head of the dev branch
|
2024-04-11 17:58:30 +01:00
|
|
|
#[tracing::instrument(fields(next), skip_all)]
|
2024-04-09 19:30:05 +01:00
|
|
|
pub async fn advance_next(
|
2024-04-18 19:15:26 +01:00
|
|
|
next: gitforge::Commit,
|
|
|
|
dev_commit_history: Vec<gitforge::Commit>,
|
2024-04-10 15:18:48 +01:00
|
|
|
repo_config: config::RepoConfig,
|
2024-04-18 19:15:26 +01:00
|
|
|
forge: gitforge::Forge,
|
2024-05-09 21:53:50 +01:00
|
|
|
repository: gitforge::Repository,
|
2024-05-03 17:50:50 +01:00
|
|
|
addr: Addr<super::RepoActor>,
|
2024-05-05 08:17:32 +01:00
|
|
|
message_token: super::MessageToken,
|
2024-04-09 19:30:05 +01:00
|
|
|
) {
|
2024-04-10 15:18:48 +01:00
|
|
|
let next_commit = find_next_commit_on_dev(next, dev_commit_history);
|
|
|
|
let Some(commit) = next_commit else {
|
|
|
|
warn!("No commits to advance next to");
|
|
|
|
return;
|
|
|
|
};
|
2024-04-12 16:21:45 +01:00
|
|
|
if let Some(problem) = validate_commit_message(commit.message()) {
|
|
|
|
warn!("Can't advance next to commit '{}': {}", commit, problem);
|
|
|
|
return;
|
|
|
|
}
|
2024-04-12 17:41:09 +01:00
|
|
|
info!("Advancing next to commit '{}'", commit);
|
2024-04-18 19:15:26 +01:00
|
|
|
if let Err(err) = forge.branch_reset(
|
2024-05-09 21:53:50 +01:00
|
|
|
&repository,
|
2024-04-18 19:15:26 +01:00
|
|
|
repo_config.branches().next(),
|
|
|
|
commit.into(),
|
|
|
|
gitforge::Force::No,
|
|
|
|
) {
|
2024-04-13 16:22:49 +01:00
|
|
|
warn!(?err, "Failed")
|
2024-04-16 22:21:55 +01:00
|
|
|
}
|
2024-05-03 17:50:50 +01:00
|
|
|
tokio::time::sleep(Duration::from_secs(10)).await;
|
2024-05-05 08:17:32 +01:00
|
|
|
addr.do_send(ValidateRepo { message_token })
|
2024-04-10 15:18:48 +01:00
|
|
|
}
|
|
|
|
|
2024-04-12 16:21:45 +01:00
|
|
|
#[tracing::instrument]
|
2024-04-18 19:15:26 +01:00
|
|
|
fn validate_commit_message(message: &gitforge::Message) -> Option<String> {
|
2024-04-12 16:21:45 +01:00
|
|
|
let message = &message.to_string();
|
|
|
|
if message.to_ascii_lowercase().starts_with("wip") {
|
|
|
|
return Some("Is Work-In-Progress".to_string());
|
|
|
|
}
|
|
|
|
match git_conventional::Commit::parse(message) {
|
|
|
|
Ok(commit) => {
|
|
|
|
info!(?commit, "Pass");
|
|
|
|
None
|
|
|
|
}
|
|
|
|
Err(err) => {
|
|
|
|
warn!(?err, "Fail");
|
|
|
|
Some(err.kind().to_string())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-10 15:18:48 +01:00
|
|
|
fn find_next_commit_on_dev(
|
2024-04-18 19:15:26 +01:00
|
|
|
next: gitforge::Commit,
|
|
|
|
dev_commit_history: Vec<gitforge::Commit>,
|
|
|
|
) -> Option<gitforge::Commit> {
|
|
|
|
let mut next_commit: Option<gitforge::Commit> = None;
|
2024-04-10 15:18:48 +01:00
|
|
|
for commit in dev_commit_history.into_iter() {
|
|
|
|
if commit == next {
|
|
|
|
break;
|
|
|
|
};
|
|
|
|
next_commit.replace(commit);
|
|
|
|
}
|
|
|
|
next_commit
|
2024-04-09 22:43:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// advance main branch to the commit 'next'
|
2024-04-11 17:58:30 +01:00
|
|
|
#[tracing::instrument(fields(next), skip_all)]
|
2024-04-09 22:43:23 +01:00
|
|
|
pub async fn advance_main(
|
2024-04-18 19:15:26 +01:00
|
|
|
next: gitforge::Commit,
|
2024-04-10 17:36:08 +01:00
|
|
|
repo_config: config::RepoConfig,
|
2024-04-16 22:21:55 +01:00
|
|
|
forge: gitforge::Forge,
|
2024-05-09 21:53:50 +01:00
|
|
|
repository: gitforge::Repository,
|
2024-05-03 17:50:50 +01:00
|
|
|
addr: Addr<RepoActor>,
|
2024-05-05 08:17:32 +01:00
|
|
|
message_token: super::MessageToken,
|
2024-04-09 22:43:23 +01:00
|
|
|
) {
|
2024-04-12 17:41:09 +01:00
|
|
|
info!("Advancing main to next");
|
2024-04-18 19:15:26 +01:00
|
|
|
if let Err(err) = forge.branch_reset(
|
2024-05-09 21:53:50 +01:00
|
|
|
&repository,
|
2024-04-18 19:15:26 +01:00
|
|
|
repo_config.branches().main(),
|
|
|
|
next.into(),
|
|
|
|
gitforge::Force::No,
|
|
|
|
) {
|
2024-04-12 19:43:21 +01:00
|
|
|
warn!(?err, "Failed")
|
2024-04-10 17:36:08 +01:00
|
|
|
};
|
2024-05-08 07:34:35 +01:00
|
|
|
match repo_config.source() {
|
|
|
|
RepoConfigSource::Repo => addr.do_send(LoadConfigFromRepo),
|
|
|
|
RepoConfigSource::Server => addr.do_send(ValidateRepo { message_token }),
|
|
|
|
}
|
2024-04-09 19:30:05 +01:00
|
|
|
}
|
2024-04-10 15:18:48 +01:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[actix_rt::test]
|
|
|
|
async fn test_find_next_commit_on_dev() {
|
2024-04-18 19:15:26 +01:00
|
|
|
let next = gitforge::Commit::new("current-next", "foo");
|
|
|
|
let expected = gitforge::Commit::new("dev-next", "next-should-go-here");
|
2024-04-10 15:18:48 +01:00
|
|
|
let dev_commit_history = vec![
|
2024-04-18 19:15:26 +01:00
|
|
|
gitforge::Commit::new("dev", "future"),
|
2024-04-12 16:21:45 +01:00
|
|
|
expected.clone(),
|
|
|
|
next.clone(),
|
2024-04-18 19:15:26 +01:00
|
|
|
gitforge::Commit::new("current-main", "history"),
|
2024-04-10 15:18:48 +01:00
|
|
|
];
|
|
|
|
let next_commit = find_next_commit_on_dev(next, dev_commit_history);
|
2024-04-12 16:21:45 +01:00
|
|
|
assert_eq!(next_commit, Some(expected));
|
2024-04-10 15:18:48 +01:00
|
|
|
}
|
|
|
|
}
|