use std::{collections::BTreeMap, path::PathBuf, time::UNIX_EPOCH}; const DRONE_TEMPLATER_IMAGE: &str = "kasperhermansen/drone-templater:main-1711807810"; use async_trait::async_trait; use eyre::{Context, OptionExt}; use crate::{rust_service::RustServiceContext, MainAction}; #[derive(Clone)] pub struct DroneTemplater { client: dagger_sdk::Query, template: PathBuf, variables: BTreeMap, } impl DroneTemplater { pub fn new(client: dagger_sdk::Query, template: impl Into) -> Self { Self { client, template: template.into(), variables: BTreeMap::default(), } } pub fn with_variable( &mut self, name: impl Into, value: impl Into, ) -> &mut Self { self.variables.insert(name.into(), value.into()); self } } #[async_trait] impl MainAction for DroneTemplater { async fn execute_main(&self, ctx: &mut crate::Context) -> eyre::Result<()> { let image_tag = ctx .get_image_tag()? .ok_or_eyre(eyre::eyre!("failed to find image tag"))?; let src = self.client.host().directory(".cuddle/tmp/"); let drone_host = std::env::var("DRONE_HOST").context("DRONE_HOST is missing")?; let drone_user = std::env::var("DRONE_USER").context("DRONE_USER is missing")?; let drone_token = std::env::var("DRONE_TOKEN").context("DRONE_TOKEN is missing")?; let drone_token_secret = self.client.set_secret("DRONE_TOKEN", drone_token); let now = std::time::SystemTime::now() .duration_since(UNIX_EPOCH) .context("failed to get system time")?; let template_name = self.template.display().to_string(); let cmd = vec!["drone-templater", "upload", "--template", &template_name] .into_iter() .map(|v| v.to_string()) .chain( self.variables .iter() .map(|(name, value)| format!(r#"--variable={name}={value}"#)), ) .chain(vec![format!("--variable=image_tag={}", image_tag)]) .collect::>(); self.client .container() .from(DRONE_TEMPLATER_IMAGE) .with_env_variable("RUST_LOG", "drone_templater=trace") .with_exec(vec!["echo", &format!("{}", now.as_secs())]) .with_directory("/src/templates", src) .with_workdir("/src") .with_env_variable("DRONE_HOST", drone_host) .with_env_variable("DRONE_USER", drone_user) .with_secret_variable("DRONE_TOKEN", drone_token_secret) .with_exec(cmd) .sync() .await .context("failed to upload drone templates with error")?; Ok(()) } }