2024-04-09 15:31:59 +01:00
|
|
|
mod branch;
|
2024-04-09 10:44:01 +01:00
|
|
|
mod config;
|
2024-04-10 09:16:42 +01:00
|
|
|
pub mod status;
|
2024-04-09 19:30:05 +01:00
|
|
|
mod webhook;
|
2024-04-09 10:44:01 +01:00
|
|
|
|
|
|
|
use actix::prelude::*;
|
|
|
|
use kxio::network::Network;
|
2024-04-10 15:18:48 +01:00
|
|
|
use tracing::{info, warn};
|
2024-04-09 10:44:01 +01:00
|
|
|
|
2024-04-09 18:18:19 +01:00
|
|
|
use crate::server::{
|
2024-04-14 06:48:26 +01:00
|
|
|
config::{RepoConfig, RepoDetails, Webhook},
|
2024-04-09 18:18:19 +01:00
|
|
|
forge,
|
2024-04-12 18:45:32 +01:00
|
|
|
git::Git,
|
2024-04-09 18:18:19 +01:00
|
|
|
};
|
2024-04-09 10:44:01 +01:00
|
|
|
|
2024-04-09 19:30:05 +01:00
|
|
|
use self::webhook::WebhookId;
|
|
|
|
|
2024-04-09 10:44:01 +01:00
|
|
|
pub struct RepoActor {
|
|
|
|
details: RepoDetails,
|
2024-04-14 06:48:26 +01:00
|
|
|
webhook: Webhook,
|
2024-04-09 19:30:05 +01:00
|
|
|
webhook_id: Option<WebhookId>, // INFO: if [None] then no webhook is configured
|
2024-04-14 06:48:26 +01:00
|
|
|
webhook_auth: Option<ulid::Ulid>,
|
2024-04-09 10:44:01 +01:00
|
|
|
net: Network,
|
2024-04-12 18:45:32 +01:00
|
|
|
git: Git,
|
2024-04-09 10:44:01 +01:00
|
|
|
}
|
|
|
|
impl RepoActor {
|
2024-04-14 06:48:26 +01:00
|
|
|
pub(crate) const fn new(
|
|
|
|
details: RepoDetails,
|
|
|
|
webhook: Webhook,
|
|
|
|
net: Network,
|
|
|
|
git: Git,
|
|
|
|
) -> Self {
|
2024-04-09 10:44:01 +01:00
|
|
|
Self {
|
|
|
|
details,
|
2024-04-14 06:48:26 +01:00
|
|
|
webhook,
|
2024-04-09 19:30:05 +01:00
|
|
|
webhook_id: None,
|
2024-04-14 06:48:26 +01:00
|
|
|
webhook_auth: None,
|
2024-04-09 10:44:01 +01:00
|
|
|
net,
|
2024-04-12 18:45:32 +01:00
|
|
|
git,
|
2024-04-09 10:44:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
impl Actor for RepoActor {
|
|
|
|
type Context = Context<Self>;
|
2024-04-09 19:30:05 +01:00
|
|
|
fn stopping(&mut self, ctx: &mut Self::Context) -> Running {
|
|
|
|
match self.webhook_id.take() {
|
|
|
|
Some(webhook_id) => {
|
|
|
|
let repo_details = self.details.clone();
|
|
|
|
let net = self.net.clone();
|
2024-04-13 20:59:57 +01:00
|
|
|
webhook::unregister(webhook_id, repo_details, net)
|
2024-04-09 19:30:05 +01:00
|
|
|
.into_actor(self)
|
|
|
|
.wait(ctx);
|
|
|
|
Running::Continue
|
|
|
|
}
|
|
|
|
None => Running::Stop,
|
|
|
|
}
|
|
|
|
}
|
2024-04-09 10:44:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Message)]
|
|
|
|
#[rtype(result = "()")]
|
|
|
|
pub struct StartRepo;
|
|
|
|
impl Handler<StartRepo> for RepoActor {
|
|
|
|
type Result = ();
|
|
|
|
fn handle(&mut self, _msg: StartRepo, ctx: &mut Self::Context) -> Self::Result {
|
|
|
|
info!(%self.details, "Starting Repo");
|
|
|
|
let details = self.details.clone();
|
|
|
|
let addr = ctx.address();
|
|
|
|
let net = self.net.clone();
|
|
|
|
config::load(details, addr, net).into_actor(self).wait(ctx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Message)]
|
|
|
|
#[rtype(result = "()")]
|
|
|
|
struct LoadedConfig(pub RepoConfig);
|
|
|
|
impl Handler<LoadedConfig> for RepoActor {
|
|
|
|
type Result = ();
|
2024-04-09 15:31:59 +01:00
|
|
|
fn handle(&mut self, msg: LoadedConfig, ctx: &mut Self::Context) -> Self::Result {
|
2024-04-09 10:44:01 +01:00
|
|
|
let config = msg.0;
|
|
|
|
info!(%self.details, %config, "Config loaded");
|
2024-04-14 06:48:26 +01:00
|
|
|
self.details.config.replace(config);
|
|
|
|
if self.webhook_id.is_none() {
|
|
|
|
info!("lets register the webhook...");
|
|
|
|
webhook::register(
|
|
|
|
self.details.clone(),
|
|
|
|
self.webhook.clone(),
|
|
|
|
ctx.address(),
|
|
|
|
self.net.clone(),
|
|
|
|
)
|
|
|
|
.into_actor(self)
|
|
|
|
.wait(ctx);
|
|
|
|
}
|
2024-04-11 15:43:02 +01:00
|
|
|
ctx.address().do_send(ValidateRepo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Message)]
|
|
|
|
#[rtype(result = "()")]
|
|
|
|
pub struct ValidateRepo;
|
|
|
|
impl Handler<ValidateRepo> for RepoActor {
|
|
|
|
type Result = ();
|
|
|
|
fn handle(&mut self, _msg: ValidateRepo, ctx: &mut Self::Context) -> Self::Result {
|
2024-04-14 06:48:26 +01:00
|
|
|
if let Some(repo_config) = self.details.config.clone() {
|
2024-04-11 15:43:02 +01:00
|
|
|
let repo_details = self.details.clone();
|
|
|
|
let addr = ctx.address();
|
|
|
|
let net = self.net.clone();
|
2024-04-12 18:45:32 +01:00
|
|
|
let git = self.git.clone();
|
|
|
|
branch::validate_positions(repo_details, repo_config, addr, git, net)
|
2024-04-11 15:43:02 +01:00
|
|
|
.into_actor(self)
|
|
|
|
.wait(ctx);
|
|
|
|
}
|
2024-04-09 10:44:01 +01:00
|
|
|
}
|
|
|
|
}
|
2024-04-09 18:18:19 +01:00
|
|
|
|
2024-04-10 18:02:04 +01:00
|
|
|
#[derive(Debug, Message)]
|
2024-04-09 18:18:19 +01:00
|
|
|
#[rtype(result = "()")]
|
|
|
|
pub struct StartMonitoring {
|
|
|
|
pub main: forge::Commit,
|
|
|
|
pub next: forge::Commit,
|
|
|
|
pub dev: forge::Commit,
|
2024-04-10 15:18:48 +01:00
|
|
|
pub dev_commit_history: Vec<forge::Commit>,
|
2024-04-09 18:18:19 +01:00
|
|
|
}
|
|
|
|
impl Handler<StartMonitoring> for RepoActor {
|
|
|
|
type Result = ();
|
2024-04-09 19:30:05 +01:00
|
|
|
fn handle(&mut self, msg: StartMonitoring, ctx: &mut Self::Context) -> Self::Result {
|
2024-04-14 06:48:26 +01:00
|
|
|
let Some(repo_config) = self.details.config.clone() else {
|
2024-04-10 15:18:48 +01:00
|
|
|
warn!("No config loaded");
|
|
|
|
return;
|
|
|
|
};
|
|
|
|
|
2024-04-11 07:15:19 +01:00
|
|
|
let next_ahead_of_main = msg.main != msg.next;
|
|
|
|
let dev_ahead_of_next = msg.next != msg.dev;
|
|
|
|
info!(%msg.main, %msg.next, %msg.dev, next_ahead_of_main, dev_ahead_of_next, "StartMonitoring");
|
|
|
|
|
2024-04-09 19:30:05 +01:00
|
|
|
let repo_details = self.details.clone();
|
2024-04-14 06:48:26 +01:00
|
|
|
let webhook = self.webhook.clone();
|
2024-04-09 19:30:05 +01:00
|
|
|
let addr = ctx.address();
|
|
|
|
let net = self.net.clone();
|
2024-04-12 18:45:32 +01:00
|
|
|
let git = self.git.clone();
|
2024-04-10 15:18:48 +01:00
|
|
|
|
2024-04-09 19:30:05 +01:00
|
|
|
if next_ahead_of_main {
|
|
|
|
status::check_next(msg.next, repo_details, addr, net)
|
|
|
|
.into_actor(self)
|
|
|
|
.wait(ctx);
|
|
|
|
} else if dev_ahead_of_next {
|
2024-04-10 15:18:48 +01:00
|
|
|
branch::advance_next(
|
|
|
|
msg.next,
|
|
|
|
msg.dev_commit_history,
|
|
|
|
repo_details,
|
|
|
|
repo_config,
|
2024-04-12 18:45:32 +01:00
|
|
|
git,
|
2024-04-10 15:18:48 +01:00
|
|
|
)
|
|
|
|
.into_actor(self)
|
|
|
|
.wait(ctx);
|
2024-04-09 19:30:05 +01:00
|
|
|
} else if self.webhook_id.is_none() {
|
2024-04-14 06:48:26 +01:00
|
|
|
webhook::register(repo_details, webhook, addr, net)
|
2024-04-09 19:30:05 +01:00
|
|
|
.into_actor(self)
|
2024-04-11 18:30:36 +01:00
|
|
|
.wait(ctx);
|
2024-04-09 19:30:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Message)]
|
|
|
|
#[rtype(result = "()")]
|
2024-04-14 06:48:26 +01:00
|
|
|
pub struct WebhookRegistered(pub WebhookId, pub ulid::Ulid);
|
2024-04-09 19:30:05 +01:00
|
|
|
impl Handler<WebhookRegistered> for RepoActor {
|
|
|
|
type Result = ();
|
|
|
|
fn handle(&mut self, msg: WebhookRegistered, _ctx: &mut Self::Context) -> Self::Result {
|
|
|
|
self.webhook_id.replace(msg.0);
|
2024-04-14 06:48:26 +01:00
|
|
|
self.webhook_auth.replace(msg.1);
|
2024-04-09 18:18:19 +01:00
|
|
|
}
|
|
|
|
}
|
2024-04-09 22:43:54 +01:00
|
|
|
|
|
|
|
#[derive(Message)]
|
|
|
|
#[rtype(result = "()")]
|
|
|
|
pub struct AdvanceMainTo(pub forge::Commit);
|
|
|
|
impl Handler<AdvanceMainTo> for RepoActor {
|
|
|
|
type Result = ();
|
|
|
|
fn handle(&mut self, msg: AdvanceMainTo, ctx: &mut Self::Context) -> Self::Result {
|
|
|
|
let repo_details = self.details.clone();
|
2024-04-14 06:48:26 +01:00
|
|
|
let Some(repo_config) = self.details.config.clone() else {
|
2024-04-10 17:36:08 +01:00
|
|
|
warn!("No config loaded");
|
|
|
|
return;
|
|
|
|
};
|
2024-04-12 18:45:32 +01:00
|
|
|
let git = self.git.clone();
|
|
|
|
branch::advance_main(msg.0, repo_details, repo_config, git)
|
2024-04-09 22:43:54 +01:00
|
|
|
.into_actor(self)
|
|
|
|
.wait(ctx);
|
|
|
|
}
|
|
|
|
}
|