Files
kasperhermansen-blog/ci/src/main.rs
kjuulh 4bb6b0228a
Some checks failed
continuous-integration/drone/push Build is failing
feat: add blog contents
2025-07-31 11:01:22 +02:00

167 lines
5.1 KiB
Rust

use cuddle_ci::{Context, MainAction, PullRequestAction};
use dagger_sdk::{
Container, HostDirectoryOptsBuilder, PortForward, QueryContainerOptsBuilder,
ServiceUpOptsBuilder,
};
const UPDATE_DEPLOYMENT_IMAGE: &str = "docker.io/kasperhermansen/update-deployment:1690401410";
const ZOLA_VERSION: &str = "0.17.2-1";
const DEBIAN_EDITION: &str = "bullseye";
const DEBIAN_PLATFORM: &str = "amd64";
#[derive(Clone)]
pub struct BlogComponent {
client: dagger_sdk::Query,
}
impl BlogComponent {
pub async fn run(&self) -> eyre::Result<()> {
let (_, container) = build(self.client.clone()).await?;
container
.as_service()
.up_opts(
ServiceUpOptsBuilder::default()
.ports(vec![PortForward {
backend: 8000,
frontend: 8000,
protocol: dagger_sdk::NetworkProtocol::Tcp,
}])
.build()?,
)
.await?;
Ok(())
}
}
#[async_trait::async_trait]
impl PullRequestAction for BlogComponent {
async fn execute_pull_request(&self, _ctx: &mut Context) -> eyre::Result<()> {
let (tag, container) = build(self.client.clone()).await?;
deploy(self.client.clone(), tag, container).await?;
Ok(())
}
}
#[async_trait::async_trait]
impl MainAction for BlogComponent {
async fn execute_main(&self, _ctx: &mut Context) -> eyre::Result<()> {
let (tag, container) = build(self.client.clone()).await?;
deploy(self.client.clone(), tag, container).await?;
Ok(())
}
}
async fn build(client: dagger_sdk::Query) -> eyre::Result<(i64, Container)> {
let src = client.host().directory_opts(
".",
HostDirectoryOptsBuilder::default()
.exclude(vec![".git", "node_modules", "public", "ci", "target"])
.build()?,
);
let github_zola_download: String = format!("https://github.com/barnumbirr/zola-debian/releases/download/v{ZOLA_VERSION}/zola_{ZOLA_VERSION}_{DEBIAN_PLATFORM}_{DEBIAN_EDITION}.deb");
let node_cache = client.cache_volume("node_cache");
let debian_cache = client.cache_volume("debian_cache");
let styles_file = client
.container()
.from("node:16")
.with_workdir("/app")
.with_directory(".", src.id().await?)
.with_mounted_cache("node_modules", node_cache.id().await?)
.with_exec(vec!["yarn"])
.with_exec(vec!["yarn", "compile"])
.file("static/styles/styles.css");
let tag = chrono::Utc::now().timestamp();
let dist_dir = client
.container_opts(
dagger_sdk::QueryContainerOptsBuilder::default()
.platform(format!("linux/{DEBIAN_PLATFORM}"))
.build()?,
)
.from(format!("debian:{DEBIAN_EDITION}"))
.with_exec(vec!["apt", "update"])
.with_exec(vec!["apt", "install", "wget", "-y"])
.with_workdir("/mnt")
.with_mounted_cache("/mnt", debian_cache.id().await?)
.with_exec(vec!["wget", &github_zola_download])
.with_exec(vec![
"dpkg",
"-i",
format!("zola_{ZOLA_VERSION}_{DEBIAN_PLATFORM}_{DEBIAN_EDITION}.deb").as_str(),
])
.with_workdir("/app")
.with_directory(".", src.id().await?)
.with_file("static/styles/styles.css", styles_file.id().await?)
.with_exec(vec!["zola", "build"])
.directory("public");
let caddy_file = client.host().directory("deployment").file("Caddyfile");
let dep_image = client
.container_opts(QueryContainerOptsBuilder::default().build().unwrap())
.from("caddy")
.with_directory("/usr/share/caddy", dist_dir.id().await.unwrap())
.with_file("/etc/caddy/Caddyfile", caddy_file.id().await.unwrap());
Ok((tag, dep_image))
}
async fn deploy(client: dagger_sdk::Query, tag: i64, container: Container) -> eyre::Result<()> {
container
.publish(format!("kasperhermansen/kasperhermansen-blog:{tag}"))
.await?;
client
.container()
.from(UPDATE_DEPLOYMENT_IMAGE)
.with_env_variable("GIT_USERNAME", "kjuulh")
.with_env_variable("GIT_PASSWORD", std::env::var("GIT_PASSWORD").unwrap())
.with_exec(vec![
"update-deployment",
"--repo",
"https://git.front.kjuulh.io/kjuulh/blog-deployment.git",
"--service",
"blog",
"--image",
&format!("kasperhermansen/kasperhermansen-blog:{tag}"),
])
.exit_code()
.await?;
Ok(())
}
#[tokio::main]
async fn main() -> eyre::Result<()> {
let _ = dotenvy::dotenv();
dagger_sdk::connect(|client| async move {
let blog_component = &BlogComponent { client };
let run = std::env::var("RUN").unwrap_or_default();
if !run.is_empty() {
blog_component.run().await?;
return Ok(());
}
cuddle_ci::CuddleCI::default()
.with_main(blog_component)
.execute(std::env::args())
.await?;
Ok(())
})
.await?;
Ok(())
}