From 068ad654774d9b30cd3fe7fb917f8867eab3c237 Mon Sep 17 00:00:00 2001 From: Jason Hall Date: Sat, 7 Jun 2025 22:58:06 -0400 Subject: [PATCH] Improve platform detection and add multi-arch run test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Updated get_test_platform() to detect runtime architecture in CI - CI tests use native platform (linux/amd64 on x86_64, linux/arm64 on aarch64) - Local development always uses linux/amd64 for consistency - Added test_multi_arch_build_and_run() test - Builds multi-arch image and pushes to ttl.sh - Verifies the image runs correctly on the current architecture - Gracefully handles missing toolchain scenarios - Updated CI integration test to verify multi-arch images can run - Builds for both linux/amd64 and linux/arm64 - Runs the image to ensure Docker selects the correct architecture This ensures we properly test both single and multi-arch scenarios. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .github/workflows/ci.yml | 9 +++-- tests/integration_test.rs | 74 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 78 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b22691e..0b55490 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -162,10 +162,15 @@ jobs: run: | cd example/hello-krust krust build --no-push --image local.test/hello:latest ./ - - name: Test multi-arch build + - name: Test multi-arch build and run run: | cd example/hello-krust - krust build --no-push --platform linux/amd64,linux/arm64 --image local.test/multiarch:latest ./ + # Build for both platforms and push + export KRUST_REPO=ttl.sh/${{ github.run_id }}-multiarch + IMAGE_REF=$(krust build --platform linux/amd64,linux/arm64 ./) + echo "Built multi-arch image: $IMAGE_REF" + # Run the image - should automatically select the right architecture + docker run --rm $IMAGE_REF # Takes too long to run on CI, so it's commented out for now. # coverage: diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 9ca5cf3..5416d1a 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -4,10 +4,21 @@ use predicates::prelude::*; use std::env; use std::process::Command as StdCommand; -// Helper to get the appropriate test platform based on architecture +// Helper to get the appropriate test platform based on runtime architecture fn get_test_platform() -> &'static str { - // Always test linux/amd64 as it's universally available in our CI - "linux/amd64" + // In CI, test the native platform + if env::var("CI").is_ok() { + if cfg!(target_arch = "x86_64") { + "linux/amd64" + } else if cfg!(target_arch = "aarch64") { + "linux/arm64" + } else { + "linux/amd64" + } + } else { + // For local development, always use amd64 as it's most commonly available + "linux/amd64" + } } #[test] @@ -257,3 +268,60 @@ fn test_multi_platform_build() -> Result<()> { } Ok(()) } + +#[test] +fn test_multi_arch_build_and_run() -> Result<()> { + // This test requires Docker + let docker_check = StdCommand::new("docker").arg("version").output(); + match docker_check { + Ok(output) if output.status.success() => { + // Docker is available, proceed with test + } + _ => { + eprintln!("Docker is required for this test but is not available"); + return Ok(()); + } + } + + let example_dir = env::current_dir()?.join("example").join("hello-krust"); + + // Build multi-arch image and push to ttl.sh + let mut cmd = Command::cargo_bin("krust")?; + let output = cmd + .arg("build") + .arg("--platform") + .arg("linux/amd64,linux/arm64") + .arg(".") + .env("KRUST_REPO", "ttl.sh/krust-multiarch-test") + .current_dir(&example_dir) + .output()?; + + if !output.status.success() { + let stderr = String::from_utf8_lossy(&output.stderr); + // If it fails due to missing targets, that's expected in some environments + if stderr.contains("target may not be installed") + || stderr.contains("linker") + || stderr.contains("cross-compilation") + || stderr.contains("not found") + { + eprintln!("Skipping multi-arch run test - build failed due to missing toolchain"); + return Ok(()); + } + panic!("Build failed unexpectedly: {}", stderr); + } + + // Get the image reference from stdout + let image_ref = String::from_utf8_lossy(&output.stdout).trim().to_string(); + assert!(image_ref.starts_with("ttl.sh/krust-multiarch-test/hello-krust")); + + // Try to run the image - it should work on the current architecture + let docker_output = StdCommand::new("docker") + .args(&["run", "--rm", &image_ref]) + .output()?; + + assert!(docker_output.status.success(), "Docker run failed"); + let docker_stdout = String::from_utf8_lossy(&docker_output.stdout); + assert!(docker_stdout.contains("Hello from krust example!")); + + Ok(()) +}