feat: Clone repo when starting repo
Some checks failed
ci/woodpecker/push/tag-created Pipeline was successful
ci/woodpecker/push/cron-docker-builder Pipeline was successful
ci/woodpecker/push/push-next Pipeline failed

This commit is contained in:
Paul Campbell 2024-04-23 07:09:30 +01:00
parent fc1c79620c
commit 17f5f62e61
6 changed files with 71 additions and 17 deletions

View file

@ -1,6 +1,9 @@
[webhook] [webhook]
url = "https://localhost:8080/webhook" url = "https://localhost:8080/webhook"
[storage]
path = "./data"
[forge.default] [forge.default]
forge_type = "ForgeJo" forge_type = "ForgeJo"
hostname = "git.example.net" hostname = "git.example.net"

View file

@ -68,11 +68,26 @@ impl Actor for RepoActor {
#[derive(Message)] #[derive(Message)]
#[rtype(result = "()")] #[rtype(result = "()")]
pub struct StartRepo; pub struct CloneRepo;
impl Handler<StartRepo> for RepoActor { impl Handler<CloneRepo> for RepoActor {
type Result = (); type Result = ();
fn handle(&mut self, _msg: StartRepo, ctx: &mut Self::Context) -> Self::Result { fn handle(&mut self, _msg: CloneRepo, ctx: &mut Self::Context) -> Self::Result {
info!(%self.details, "Starting Repo"); info!(%self.details, "Clone/Update Repo");
let gitdir = self.details.gitdir.clone();
match self.forge.repo_clone(gitdir) {
Ok(_) => ctx.address().do_send(LoadConfigFromRepo),
Err(err) => warn!(?err, "Could not Clone repo"),
}
}
}
#[derive(Message)]
#[rtype(result = "()")]
pub struct LoadConfigFromRepo;
impl Handler<LoadConfigFromRepo> for RepoActor {
type Result = ();
fn handle(&mut self, _msg: LoadConfigFromRepo, ctx: &mut Self::Context) -> Self::Result {
info!(%self.details, "Loading .git-next.toml from repo");
let details = self.details.clone(); let details = self.details.clone();
let addr = ctx.address(); let addr = ctx.address();
let forge = self.forge.clone(); let forge = self.forge.clone();

View file

@ -31,6 +31,10 @@ impl ServerConfig {
.map(|(name, forge)| (ForgeName(name.clone()), forge)) .map(|(name, forge)| (ForgeName(name.clone()), forge))
} }
pub const fn storage(&self) -> &ServerStorage {
&self.storage
}
pub const fn webhook(&self) -> &Webhook { pub const fn webhook(&self) -> &Webhook {
&self.webhook &self.webhook
} }
@ -199,9 +203,6 @@ impl ServerRepoConfig {
_ => None, _ => None,
} }
} }
pub fn gitdir(&self) -> Option<GitDir> {
self.gitdir.clone().map(GitDir)
}
} }
#[cfg(test)] #[cfg(test)]
impl AsRef<Self> for ServerRepoConfig { impl AsRef<Self> for ServerRepoConfig {
@ -327,7 +328,7 @@ pub struct RepoDetails {
pub branch: BranchName, pub branch: BranchName,
pub forge: ForgeDetails, pub forge: ForgeDetails,
pub repo_config: Option<RepoConfig>, pub repo_config: Option<RepoConfig>,
pub gitdir: Option<GitDir>, pub gitdir: GitDir,
} }
impl RepoDetails { impl RepoDetails {
pub fn new( pub fn new(
@ -335,13 +336,19 @@ impl RepoDetails {
server_repo_config: &ServerRepoConfig, server_repo_config: &ServerRepoConfig,
forge_name: &ForgeName, forge_name: &ForgeName,
forge: &ForgeConfig, forge: &ForgeConfig,
server_storage: &ServerStorage,
) -> Self { ) -> Self {
Self { Self {
repo_alias: name.clone(), repo_alias: name.clone(),
repo_path: RepoPath(server_repo_config.repo.clone()), repo_path: RepoPath(server_repo_config.repo.clone()),
repo_config: server_repo_config.repo_config(), repo_config: server_repo_config.repo_config(),
branch: BranchName(server_repo_config.branch.clone()), branch: BranchName(server_repo_config.branch.clone()),
gitdir: server_repo_config.gitdir(), gitdir: GitDir(
server_storage
.path
.join(forge_name.to_string())
.join(name.to_string()),
),
forge: ForgeDetails { forge: ForgeDetails {
forge_name: forge_name.clone(), forge_name: forge_name.clone(),
forge_type: forge.forge_type.clone(), forge_type: forge.forge_type.clone(),
@ -400,6 +407,10 @@ impl Display for ForgeType {
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
pub struct GitDir(PathBuf); pub struct GitDir(PathBuf);
impl GitDir { impl GitDir {
#[cfg(test)]
pub(crate) fn new(pathbuf: &std::path::Path) -> Self {
Self(pathbuf.to_path_buf())
}
#[allow(dead_code)] // TODO: #[allow(dead_code)] // TODO:
pub const fn pathbuf(&self) -> &PathBuf { pub const fn pathbuf(&self) -> &PathBuf {
&self.0 &self.0

View file

@ -32,7 +32,7 @@ pub fn repo_details(
n: u32, n: u32,
forge: ForgeDetails, forge: ForgeDetails,
repo_config: Option<RepoConfig>, repo_config: Option<RepoConfig>,
gitdir: Option<GitDir>, gitdir: GitDir,
) -> RepoDetails { ) -> RepoDetails {
RepoDetails { RepoDetails {
repo_alias: repo_alias(n), repo_alias: repo_alias(n),

View file

@ -8,12 +8,15 @@ use super::*;
#[test] #[test]
fn test_name() { fn test_name() {
let Ok(fs) = kxio::filesystem::FileSystem::new_temp() else {
panic!("fs")
};
let net = Network::new_mock(); let net = Network::new_mock();
let repo_details = common::repo_details( let repo_details = common::repo_details(
1, 1,
common::forge_details(1, ForgeType::MockForge), common::forge_details(1, ForgeType::MockForge),
Some(common::repo_config(1)), Some(common::repo_config(1)),
None, GitDir::new(fs.cwd()),
); );
let forge = Forge::new_forgejo(repo_details, net); let forge = Forge::new_forgejo(repo_details, net);
assert_eq!(forge.name(), "forgejo"); assert_eq!(forge.name(), "forgejo");
@ -21,6 +24,9 @@ fn test_name() {
#[test_log::test(tokio::test)] #[test_log::test(tokio::test)]
async fn test_branches_get() { async fn test_branches_get() {
let Ok(fs) = kxio::filesystem::FileSystem::new_temp() else {
panic!("fs")
};
let mut net = MockNetwork::new(); let mut net = MockNetwork::new();
let hostname = common::hostname(1); let hostname = common::hostname(1);
let path = common::repo_path(1); let path = common::repo_path(1);
@ -36,7 +42,7 @@ async fn test_branches_get() {
1, 1,
common::forge_details(1, ForgeType::MockForge), common::forge_details(1, ForgeType::MockForge),
Some(common::repo_config(1)), Some(common::repo_config(1)),
None, GitDir::new(fs.cwd()),
); );
let forge = Forge::new_forgejo(repo_details, net.clone()); let forge = Forge::new_forgejo(repo_details, net.clone());

View file

@ -15,7 +15,7 @@ use crate::{
filesystem::FileSystem, filesystem::FileSystem,
server::{ server::{
actors::webhook, actors::webhook,
config::{ForgeConfig, ForgeName, RepoAlias, Webhook}, config::{ForgeConfig, ForgeName, RepoAlias, ServerStorage, Webhook},
}, },
}; };
@ -55,9 +55,13 @@ pub async fn start(fs: FileSystem, net: Network) {
let webhook_router = webhook::WebhookRouter::new().start(); let webhook_router = webhook::WebhookRouter::new().start();
let webhook = server_config.webhook(); let webhook = server_config.webhook();
let server_storage = server_config.storage();
server_config server_config
.forges() .forges()
.flat_map(|(forge_name, forge)| create_forge_repos(forge, forge_name, webhook, &net)) .flat_map(|(forge_name, forge)| {
create_forge_repos(forge, forge_name, server_storage, webhook, &net)
})
.map(start_actor) .map(start_actor)
.map(|(alias, addr)| webhook::AddWebhookRecipient(alias, addr.recipient())) .map(|(alias, addr)| webhook::AddWebhookRecipient(alias, addr.recipient()))
.for_each(|msg| webhook_router.do_send(msg)); .for_each(|msg| webhook_router.do_send(msg));
@ -70,6 +74,7 @@ pub async fn start(fs: FileSystem, net: Network) {
fn create_forge_repos( fn create_forge_repos(
forge: &ForgeConfig, forge: &ForgeConfig,
forge_name: ForgeName, forge_name: ForgeName,
server_storage: &ServerStorage,
webhook: &Webhook, webhook: &Webhook,
net: &Network, net: &Network,
) -> Vec<(ForgeName, RepoAlias, RepoActor)> { ) -> Vec<(ForgeName, RepoAlias, RepoActor)> {
@ -79,16 +84,24 @@ fn create_forge_repos(
info!("Creating Forge"); info!("Creating Forge");
forge forge
.repos() .repos()
.map(create_actor(forge_name, forge.clone(), webhook, net)) .map(create_actor(
forge_name,
forge.clone(),
server_storage,
webhook,
net,
))
.collect::<Vec<_>>() .collect::<Vec<_>>()
} }
fn create_actor( fn create_actor(
forge_name: ForgeName, forge_name: ForgeName,
forge: config::ForgeConfig, forge: config::ForgeConfig,
server_storage: &ServerStorage,
webhook: &Webhook, webhook: &Webhook,
net: &Network, net: &Network,
) -> impl Fn((RepoAlias, &ServerRepoConfig)) -> (ForgeName, RepoAlias, RepoActor) { ) -> impl Fn((RepoAlias, &ServerRepoConfig)) -> (ForgeName, RepoAlias, RepoActor) {
let server_storage = server_storage.clone();
let webhook = webhook.clone(); let webhook = webhook.clone();
let net = net.clone(); let net = net.clone();
move |(repo_name, server_repo_config)| { move |(repo_name, server_repo_config)| {
@ -96,7 +109,13 @@ fn create_actor(
let _guard = span.enter(); let _guard = span.enter();
info!("Creating Repo"); info!("Creating Repo");
let actor = actors::repo::RepoActor::new( let actor = actors::repo::RepoActor::new(
config::RepoDetails::new(&repo_name, server_repo_config, &forge_name, &forge), config::RepoDetails::new(
&repo_name,
server_repo_config,
&forge_name,
&forge,
&server_storage,
),
webhook.clone(), webhook.clone(),
net.clone(), net.clone(),
); );
@ -113,7 +132,7 @@ fn start_actor(
let _guard = span.enter(); let _guard = span.enter();
info!("Starting"); info!("Starting");
let addr = actor.start(); let addr = actor.start();
addr.do_send(actors::repo::StartRepo); addr.do_send(actors::repo::CloneRepo);
info!("Started"); info!("Started");
(repo_alias, addr) (repo_alias, addr)
} }