diff --git a/ci/src/main.rs b/ci/src/main.rs index 6d5f8d5..55b0c0c 100644 --- a/ci/src/main.rs +++ b/ci/src/main.rs @@ -7,9 +7,8 @@ use clap::Parser; use clap::Subcommand; use clap::ValueEnum; -use dagger_sdk::Platform; -use dagger_sdk::QueryContainerOpts; -use futures::StreamExt; +use dagger_rust::build::RustVersion; +use dagger_rust::build::SlimImage; use crate::please_release::run_release_please; @@ -31,10 +30,6 @@ pub enum Commands { command: LocalCommands, }, PullRequest { - #[arg(long)] - image: String, - #[arg(long)] - tag: String, #[arg(long)] bin_name: String, }, @@ -46,7 +41,14 @@ pub enum Commands { #[arg(long)] bin_name: String, }, - Release, + Release { + #[arg(long)] + image: String, + #[arg(long)] + tag: String, + #[arg(long)] + bin_name: String, + }, } #[derive(Subcommand, Clone)] @@ -112,48 +114,65 @@ async fn main() -> eyre::Result<()> { let cli = Command::parse(); + let crates = &["crates/*", "ci"]; + let debian_deps = &["libssl-dev", "pkg-config", "openssl", "git", "jq"]; + let debian_image = "debian:bullseye".to_string(); + match &cli.commands { Commands::Local { command } => match command { LocalCommands::Build { profile: _, bin_name, } => { - let base_image = base_rust_image( - client.clone(), - &cli.global, - &None, - &bin_name.clone(), - &"release".into(), - ) - .await?; - let prod_image = get_base_debian_image(client.clone(), &cli.global, None).await?; - build::execute( - client, - &cli.global, - &base_image, - &prod_image, - bin_name, - &None, - ) - .await?; + dagger_rust::build::RustBuild::new(client.clone()) + .build_release( + None::, + RustVersion::Nightly, + crates, + debian_deps, + vec![SlimImage::Debian { + image: debian_image, + deps: debian_deps + .iter() + .map(|s| s.to_string()) + .collect::>(), + architecture: dagger_rust::build::BuildArchitecture::Amd64, + }], + &bin_name, + ) + .await?; } LocalCommands::Test => { - let base_image = base_rust_image( - client.clone(), - &cli.global, - &None, - &"cuddle-please".into(), - &"debug".into(), - ) - .await?; - test::execute(client, &cli.global, base_image).await?; + dagger_rust::test::RustTest::new(client.clone()) + .test(None::, RustVersion::Nightly, crates, debian_deps) + .await?; } LocalCommands::DockerImage { tag, image, bin_name, } => { - build::build_and_deploy(client, &cli.global, bin_name, image, tag).await?; + let images = dagger_rust::build::RustBuild::new(client.clone()) + .build_release( + None::, + RustVersion::Nightly, + crates, + debian_deps, + vec![SlimImage::Debian { + image: debian_image, + deps: debian_deps + .iter() + .map(|s| s.to_string()) + .collect::>(), + architecture: dagger_rust::build::BuildArchitecture::Amd64, + }], + &bin_name, + ) + .await?; + + dagger_rust::publish::RustPublish::new(client.clone()) + .publish(image, tag, images) + .await?; } LocalCommands::PleaseRelease => todo!(), LocalCommands::BuildDocs {} => { @@ -165,69 +184,90 @@ async fn main() -> eyre::Result<()> { .await?; } }, - Commands::PullRequest { - image, - tag, - bin_name, - } => { - async fn test(client: Arc, cli: &Command, bin_name: &String) { - let args = &cli.global; + Commands::PullRequest { bin_name } => { + async fn test(client: Arc) { + let crates = &["crates/*", "ci"]; + let debian_deps = &["libssl-dev", "pkg-config", "openssl", "git", "jq"]; - let base_image = - base_rust_image(client.clone(), args, &None, bin_name, &"debug".into()) - .await - .unwrap(); - test::execute(client.clone(), args, base_image) + dagger_rust::test::RustTest::new(client.clone()) + .test(None::, RustVersion::Nightly, crates, debian_deps) .await - .unwrap(); + .expect("rust to test crates"); } - async fn build( - client: Arc, - cli: &Command, - bin_name: &String, - image: &String, - tag: &String, - ) { - let args = &cli.global; + async fn build(client: Arc, bin_name: &String) { + let crates = &["crates/*", "ci"]; + let debian_deps = &["libssl-dev", "pkg-config", "openssl", "git", "jq"]; + let debian_image = "debian:bullseye".to_string(); - build::build(client.clone(), args, bin_name, image, tag) + dagger_rust::build::RustBuild::new(client.clone()) + .build_release( + None::, + RustVersion::Nightly, + crates, + debian_deps, + vec![SlimImage::Debian { + image: debian_image, + deps: debian_deps + .iter() + .map(|s| s.to_string()) + .collect::>(), + architecture: dagger_rust::build::BuildArchitecture::Amd64, + }], + &bin_name, + ) .await - .unwrap(); + .expect("dagger rust to build crates"); } - tokio::join!( - test(client.clone(), &cli, bin_name), - build(client.clone(), &cli, bin_name, image, tag), - ); + tokio::join!(test(client.clone()), build(client.clone(), bin_name),); } Commands::Main { image, tag, bin_name, } => { - async fn test(client: Arc, cli: &Command, bin_name: &String) { - let args = &cli.global; + async fn test(client: Arc) { + let crates = &["crates/*", "ci"]; + let debian_deps = &["libssl-dev", "pkg-config", "openssl", "git", "jq"]; - let base_image = - base_rust_image(client.clone(), args, &None, bin_name, &"debug".into()) - .await - .unwrap(); - test::execute(client.clone(), args, base_image) + dagger_rust::test::RustTest::new(client.clone()) + .test(None::, RustVersion::Nightly, crates, debian_deps) .await - .unwrap(); + .expect("rust to test crates"); } async fn build( client: Arc, - cli: &Command, bin_name: &String, image: &String, tag: &String, ) { - let args = &cli.global; + let crates = &["crates/*", "ci"]; + let debian_deps = &["libssl-dev", "pkg-config", "openssl", "git", "jq"]; + let debian_image = "debian:bullseye".to_string(); - build::build_and_deploy(client.clone(), args, bin_name, image, tag) + let images = dagger_rust::build::RustBuild::new(client.clone()) + .build_release( + None::, + RustVersion::Nightly, + crates, + debian_deps, + vec![SlimImage::Debian { + image: debian_image, + deps: debian_deps + .iter() + .map(|s| s.to_string()) + .collect::>(), + architecture: dagger_rust::build::BuildArchitecture::Amd64, + }], + &bin_name, + ) .await - .unwrap(); + .expect("rust build to build release crates"); + + dagger_rust::publish::RustPublish::new(client.clone()) + .publish(image, tag, images) + .await + .expect("rust publish to publish crates"); } async fn cuddle_please(client: Arc, cli: &Command) { @@ -237,12 +277,53 @@ async fn main() -> eyre::Result<()> { } tokio::join!( - test(client.clone(), &cli, bin_name), - build(client.clone(), &cli, bin_name, image, tag), + test(client.clone()), + build(client.clone(), bin_name, image, tag), cuddle_please(client.clone(), &cli) ); } - Commands::Release => todo!(), + Commands::Release { + image, + tag, + bin_name, + } => { + async fn build( + client: Arc, + bin_name: &String, + image: &String, + tag: &String, + ) { + let crates = &["crates/*", "ci"]; + let debian_deps = &["libssl-dev", "pkg-config", "openssl", "git", "jq"]; + let debian_image = "debian:bullseye".to_string(); + + let images = dagger_rust::build::RustBuild::new(client.clone()) + .build_release( + None::, + RustVersion::Nightly, + crates, + debian_deps, + vec![SlimImage::Debian { + image: debian_image, + deps: debian_deps + .iter() + .map(|s| s.to_string()) + .collect::>(), + architecture: dagger_rust::build::BuildArchitecture::Amd64, + }], + &bin_name, + ) + .await + .expect("rust build to build release crates"); + + dagger_rust::publish::RustPublish::new(client.clone()) + .publish(image, tag, images) + .await + .expect("rust publish to publish crates"); + } + + build(client.clone(), bin_name, image, tag).await; + } } Ok(()) @@ -378,231 +459,6 @@ mod docs { Ok(dep_image) } - - pub async fn publish( - client: Arc, - args: &GlobalArgs, - containers: &Vec, - ) -> eyre::Result<()> { - let container_ids = - futures::future::join_all(containers.iter().map(|c| c.id()).collect::>()).await; - - let container_ids = container_ids - .into_iter() - .collect::>>()?; - - client - .container() - .publish_opts( - format!( - "{}:{}", - args.docs_image.as_ref().expect("--docs-image to be set"), - args.docs_image_tag - .as_ref() - .expect("--docs-image-tag to be set") - ), - dagger_sdk::ContainerPublishOpts { - platform_variants: Some(container_ids), - }, - ) - .await?; - - Ok(()) - } -} - -mod build { - use std::sync::Arc; - - use dagger_sdk::Container; - - use crate::{base_rust_image, get_base_debian_image, GlobalArgs}; - - pub async fn build_and_deploy( - client: Arc, - args: &GlobalArgs, - bin_name: &String, - image: &String, - tag: &String, - ) -> eyre::Result<()> { - // let containers = vec!["linux/amd64", "linux/arm64"]; - - let base_image = get_base_debian_image( - client.clone(), - &args.clone(), - Some("linux/amd64".to_string()), - ) - .await?; - - let container = base_rust_image( - client.clone(), - args, - &Some("linux/amd64".to_string()), - &bin_name.clone(), - &"release".into(), - ) - .await?; - let build_image = execute( - client.clone(), - args, - &container, - &base_image, - bin_name, - &Some("linux/amd64".to_string()), - ) - .await?; - - let build_id = build_image.id().await?; - - let _container = client - .clone() - .container() - .publish_opts( - format!("{image}:{tag}"), - dagger_sdk::ContainerPublishOpts { - platform_variants: Some(vec![build_id]), - }, - ) - .await?; - Ok(()) - } - pub async fn build( - client: Arc, - args: &GlobalArgs, - bin_name: &String, - _image: &String, - _tag: &String, - ) -> eyre::Result<()> { - // let containers = vec!["linux/amd64", "linux/arm64"]; - - let base_image = get_base_debian_image( - client.clone(), - &args.clone(), - Some("linux/amd64".to_string()), - ) - .await?; - - let container = base_rust_image( - client.clone(), - args, - &Some("linux/amd64".to_string()), - &bin_name.clone(), - &"release".into(), - ) - .await?; - let build_image = execute( - client.clone(), - args, - &container, - &base_image, - bin_name, - &Some("linux/amd64".to_string()), - ) - .await?; - - build_image.exit_code().await?; - - Ok(()) - } - pub async fn execute( - _client: Arc, - _args: &GlobalArgs, - container: &dagger_sdk::Container, - base_image: &dagger_sdk::Container, - bin_name: &String, - platform: &Option, - ) -> eyre::Result { - let rust_target = match platform - .clone() - .unwrap_or("linux/amd64".to_string()) - .as_str() - { - "linux/amd64" => "x86_64-unknown-linux-gnu", - "linux/arm64" => "aarch64-unknown-linux-gnu", - _ => eyre::bail!("architecture not supported"), - }; - let build_image = container.with_exec(vec![ - "cargo", - "build", - "--target", - rust_target, - "--release", - "-p", - bin_name, - ]); - - let final_image = base_image - .with_file( - format!("/usr/local/bin/{}", &bin_name), - build_image - .file(format!("target/{}/release/{}", rust_target, &bin_name)) - .id() - .await?, - ) - .with_exec(vec![bin_name, "--help"]); - - let output = final_image.stdout().await?; - println!("{output}"); - - //.with_entrypoint(vec![&bin_name, "--log-level=debug"]); - - Ok(final_image) - } -} - -mod test { - use std::sync::Arc; - - use crate::GlobalArgs; - - pub async fn execute( - _client: Arc, - _args: &GlobalArgs, - container: dagger_sdk::Container, - ) -> eyre::Result<()> { - let test_image = container - .pipeline("rust:test") - .with_exec(vec!["apt", "update"]) - .with_exec(vec!["apt", "install", "-y", "git"]) - .with_exec(vec!["cargo", "test"]); - - test_image.exit_code().await?; - - Ok(()) - } -} - -pub async fn get_base_debian_image( - client: Arc, - args: &GlobalArgs, - platform: Option, -) -> eyre::Result { - let default_platform = client.default_platform().await?; - let platform = platform.map(Platform).unwrap_or(default_platform); - - let image = client - .container_opts(QueryContainerOpts { - id: None, - platform: Some(platform), - }) - .from( - args.production_image - .clone() - .unwrap_or("debian:bullseye".to_string()), - ); - - let base_image = image.with_exec(vec!["apt", "update"]).with_exec(vec![ - "apt", - "install", - "-y", - "libssl-dev", - "pkg-config", - "openssl", - "git", - "jq", - ]); - - Ok(base_image) } pub fn get_src( diff --git a/scripts/ci:release.sh b/scripts/ci:release.sh new file mode 100755 index 0000000..7805cfd --- /dev/null +++ b/scripts/ci:release.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +set -e + +CMD_PREFIX="cargo run -p ci --" + +if [[ -n "$CI_PREFIX" ]]; then + CMD_PREFIX="$CI_PREFIX" +fi + + +$CMD_PREFIX release \ + --mkdocs-image "$MKDOCS_IMAGE" \ + --caddy-image "$CADDY_IMAGE" \ + --image "$REGISTRY/$SERVICE" \ + --tag "$DRONE_TAG" \ + --bin-name "$SERVICE" \ No newline at end of file