feat: add blog contents
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
2025-07-31 11:01:22 +02:00
parent da0771ccb9
commit 4bb6b0228a
79 changed files with 18092 additions and 246 deletions

267
ci/Cargo.lock generated
View File

@@ -32,6 +32,56 @@ dependencies = [
"libc",
]
[[package]]
name = "anstream"
version = "0.6.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
[[package]]
name = "anstyle-parse"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882"
dependencies = [
"anstyle",
"once_cell_polyfill",
"windows-sys 0.59.0",
]
[[package]]
name = "anyhow"
version = "1.0.98"
@@ -142,15 +192,59 @@ dependencies = [
name = "ci"
version = "0.1.0"
dependencies = [
"async-trait",
"chrono",
"color-eyre",
"cuddle-ci",
"dagger-components",
"dagger-rust",
"dagger-sdk",
"dotenv",
"dotenvy",
"eyre",
"tokio",
"tokio-scoped",
]
[[package]]
name = "clap"
version = "4.5.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim 0.11.1",
]
[[package]]
name = "clap_derive"
version = "4.5.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491"
dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.104",
]
[[package]]
name = "clap_lex"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
[[package]]
name = "color-eyre"
version = "0.6.5"
@@ -178,6 +272,12 @@ dependencies = [
"tracing-error",
]
[[package]]
name = "colorchoice"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
[[package]]
name = "combine"
version = "4.6.7"
@@ -232,6 +332,53 @@ dependencies = [
"typenum",
]
[[package]]
name = "cuddle-ci"
version = "0.3.0"
source = "git+https://git.kjuulh.io/kjuulh/dagger-components?branch=main#e26e359d10792d0e2d4c0a23328ac0c74869407b"
dependencies = [
"async-trait",
"chrono",
"clap",
"dagger-cuddle-please",
"dagger-rust",
"dagger-sdk",
"eyre",
"futures",
"serde",
"serde_json",
"serde_yaml",
"tokio",
"toml",
"tracing",
]
[[package]]
name = "dagger-components"
version = "0.1.0"
source = "git+https://git.kjuulh.io/kjuulh/dagger-components?branch=main#e26e359d10792d0e2d4c0a23328ac0c74869407b"
[[package]]
name = "dagger-cuddle-please"
version = "0.3.0"
source = "git+https://git.kjuulh.io/kjuulh/dagger-components?branch=main#e26e359d10792d0e2d4c0a23328ac0c74869407b"
dependencies = [
"async-trait",
"dagger-sdk",
"eyre",
]
[[package]]
name = "dagger-rust"
version = "0.3.0"
source = "git+https://git.kjuulh.io/kjuulh/dagger-components?branch=main#e26e359d10792d0e2d4c0a23328ac0c74869407b"
dependencies = [
"async-trait",
"dagger-sdk",
"eyre",
"tokio",
]
[[package]]
name = "dagger-sdk"
version = "0.18.14"
@@ -282,7 +429,7 @@ dependencies = [
"ident_case",
"proc-macro2",
"quote",
"strsim",
"strsim 0.10.0",
"syn 1.0.109",
]
@@ -371,10 +518,10 @@ dependencies = [
]
[[package]]
name = "dotenv"
version = "0.15.0"
name = "dotenvy"
version = "0.15.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
[[package]]
name = "encoding_rs"
@@ -621,7 +768,7 @@ checksum = "a40f793251171991c4eb75bd84bc640afa8b68ff6907bc89d3b712a22f700506"
dependencies = [
"graphql-introspection-query",
"graphql-parser",
"heck",
"heck 0.4.1",
"lazy_static",
"proc-macro2",
"quote",
@@ -672,6 +819,12 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hex"
version = "0.4.3"
@@ -926,6 +1079,12 @@ version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "itoa"
version = "1.0.15"
@@ -1059,6 +1218,12 @@ version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "once_cell_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
[[package]]
name = "option-ext"
version = "0.2.0"
@@ -1361,6 +1526,15 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_spanned"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3"
dependencies = [
"serde",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
@@ -1373,6 +1547,19 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_yaml"
version = "0.9.34+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
dependencies = [
"indexmap",
"itoa",
"ryu",
"serde",
"unsafe-libyaml",
]
[[package]]
name = "sha2"
version = "0.10.9"
@@ -1452,6 +1639,12 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "1.0.109"
@@ -1650,6 +1843,47 @@ dependencies = [
"tokio",
]
[[package]]
name = "toml"
version = "0.8.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit",
]
[[package]]
name = "toml_datetime"
version = "0.6.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
version = "0.22.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
dependencies = [
"indexmap",
"serde",
"serde_spanned",
"toml_datetime",
"toml_write",
"winnow",
]
[[package]]
name = "toml_write"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
[[package]]
name = "tower-service"
version = "0.3.3"
@@ -1743,6 +1977,12 @@ version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "unsafe-libyaml"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
[[package]]
name = "untrusted"
version = "0.9.0"
@@ -1766,6 +2006,12 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "valuable"
version = "0.1.1"
@@ -2204,6 +2450,15 @@ version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
[[package]]
name = "winnow"
version = "0.7.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95"
dependencies = [
"memchr",
]
[[package]]
name = "winreg"
version = "0.50.0"

View File

@@ -12,4 +12,9 @@ dagger-sdk = "0.18.3"
eyre = "0.6.8"
tokio = { version = "1.31.0", features = ["full"] }
tokio-scoped = "0.2.0"
dotenv = "0.15.0"
dotenvy = "0.15.0"
dagger-components = { git = "https://git.kjuulh.io/kjuulh/dagger-components", branch = "main" }
dagger-rust = { git = "https://git.kjuulh.io/kjuulh/dagger-components", branch = "main" }
cuddle-ci = { git = "https://git.kjuulh.io/kjuulh/dagger-components", branch = "main" }
async-trait = "0.1.88"

View File

@@ -1,20 +1,70 @@
use std::sync::Arc;
use cuddle_ci::{Context, MainAction, PullRequestAction};
use dagger_sdk::{
Container, HostDirectoryOptsBuilder, PortForward, QueryContainerOptsBuilder,
ServiceUpOptsBuilder,
};
use dagger_sdk::{HostDirectoryOptsBuilder, QueryContainerOptsBuilder};
use tokio::sync::Mutex;
const UPDATE_DEPLOYMENT_IMAGE: &str = "docker.io/kasperhermansen/update-deployment:1690401410";
#[tokio::main]
async fn main() -> eyre::Result<()> {
let _ = dotenv::dotenv();
dagger_sdk::connect(|client| async move {
const ZOLA_VERSION: &str = "0.17.2-1";
const DEBIAN_EDITION: &str = "bullseye";
const DEBIAN_PLATFORM: &str = "amd64";
let src = client.host().directory_opts(
#[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");
@@ -28,40 +78,15 @@ let src = client.host().directory_opts(
.with_exec(vec!["yarn", "compile"])
.file("static/styles/styles.css");
let zola_version = "0.17.2-1";
let debian_edition = "bullseye";
let debian_platform = "amd64";
let tag = chrono::Utc::now().timestamp();
let github_zola_download = format!("https://github.com/barnumbirr/zola-debian/releases/download/v{zola_version}/zola_{zola_version}_{debian_platform}_{debian_edition}.deb");
let pull_articles_docker_image = "docker.io/kasperhermansen/pull-articles:1690413158";
let update_deployments_docker_image = "docker.io/kasperhermansen/update-deployment:1690401410";
let pull_articles = client
.container()
.from(pull_articles_docker_image)
.with_exec(vec!["echo", &format!("{tag}")])
.with_env_variable("GIT_USERNAME", "kjuulh")
.with_env_variable("GIT_PASSWORD", std::env::var("GIT_PASSWORD").unwrap())
.with_exec(vec![
"pull-articles",
"--repo",
"https://git.front.kjuulh.io/kjuulh/obsidian.git",
"--path",
"areas/blog/posts",
"--out",
"/mnt/posts",
"--static-out=/mnt/static",
])
.directory("/mnt/");
let dist_dir = client
.container_opts(
dagger_sdk::QueryContainerOptsBuilder::default()
.platform(format!("linux/{debian_platform}"))
.platform(format!("linux/{DEBIAN_PLATFORM}"))
.build()?,
)
.from(format!("debian:{debian_edition}"))
.from(format!("debian:{DEBIAN_EDITION}"))
.with_exec(vec!["apt", "update"])
.with_exec(vec!["apt", "install", "wget", "-y"])
.with_workdir("/mnt")
@@ -70,75 +95,33 @@ let src = client.host().directory_opts(
.with_exec(vec![
"dpkg",
"-i",
format!("zola_{zola_version}_{debian_platform}_{debian_edition}.deb").as_str(),
format!("zola_{ZOLA_VERSION}_{DEBIAN_PLATFORM}_{DEBIAN_EDITION}.deb").as_str(),
])
.with_workdir("/app")
.with_directory(".", src.id().await?)
.with_directory(
"content/posts",
pull_articles.directory("posts").id().await?,
)
.with_directory(
"static/assets",
pull_articles.directory("static").id().await?,
)
.with_file(
"content/posts/_index.md",
src.file("content/posts/_index.md").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 variants = vec!["linux/amd64", "linux/arm64"];
let platform_variants = Arc::new(Mutex::new(Vec::new()));
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());
tokio_scoped::scope(|s| {
for platform in variants {
let caddy_file = caddy_file.clone();
let client = client.clone();
let dist_dir = dist_dir.clone();
let platform_variants = platform_variants.clone();
Ok((tag, dep_image))
}
s.spawn(async move {
let dep_image = client
.container_opts(
QueryContainerOptsBuilder::default()
.platform(platform)
.build()
.unwrap(),
)
.from("caddy")
.with_directory("/usr/share/caddy", dist_dir.id().await.unwrap())
.with_file("/etc/caddy/Caddyfile", caddy_file.id().await.unwrap());
let mut platform_variants = platform_variants.lock().await;
platform_variants.push(dep_image.id().await.unwrap())
});
}
});
let variants = platform_variants
.lock()
.await
.iter().cloned()
.collect::<Vec<_>>();
client
.container()
.publish_opts(
format!("kasperhermansen/kasperhermansen-blog:{tag}"),
dagger_sdk::ContainerPublishOptsBuilder::default()
.platform_variants(variants)
.build()?,
)
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_deployments_docker_image)
.from(UPDATE_DEPLOYMENT_IMAGE)
.with_env_variable("GIT_USERNAME", "kjuulh")
.with_env_variable("GIT_PASSWORD", std::env::var("GIT_PASSWORD").unwrap())
.with_exec(vec![
@@ -153,7 +136,31 @@ let src = client.host().directory_opts(
.exit_code()
.await?;
Ok(()) }).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(())
}