From 74708c6698598583b8b016e327f75a70c6fe2a37 Mon Sep 17 00:00:00 2001 From: Ed Morley <501702+edmorley@users.noreply.github.com> Date: Thu, 17 Aug 2023 14:54:15 +0000 Subject: [PATCH 01/11] libcnb-test: Implement `fmt::Display` for `LogOutput` (#635) Since: - There was already duplication of formatting stderr/stdout output, which was otherwise going to get worse after #636. - It may also be useful for end users when debugging, to save them having to manually print both stderr and stdout manually. Prep for #482. GUS-W-13966399. --- CHANGELOG.md | 1 + libcnb-test/src/log.rs | 9 +++++++++ libcnb-test/src/test_runner.rs | 12 +++++------- libcnb-test/src/util.rs | 19 +++++++++---------- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63731b73..413ba5ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ separate changelogs for each crate were used. If you need to refer to these old ### Added - `libcnb-package`: Add cross-compilation assistance for Linux `aarch64-unknown-linux-musl`. ([#577](https://github.com/heroku/libcnb.rs/pull/577)) +- `libcnb-test`: `LogOutput` now implements `std::fmt::Display`. ([#635](https://github.com/heroku/libcnb.rs/pull/635)) ### Changed diff --git a/libcnb-test/src/log.rs b/libcnb-test/src/log.rs index 519b6717..6bb93726 100644 --- a/libcnb-test/src/log.rs +++ b/libcnb-test/src/log.rs @@ -1,6 +1,15 @@ +use std::fmt::Display; + /// Log output from a command. #[derive(Debug, Default)] pub struct LogOutput { pub stdout: String, pub stderr: String, } + +impl Display for LogOutput { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let LogOutput { stdout, stderr } = self; + write!(f, "## stderr:\n\n{stderr}\n## stdout:\n\n{stdout}\n") + } +} diff --git a/libcnb-test/src/test_runner.rs b/libcnb-test/src/test_runner.rs index d88c9c2d..67284e71 100644 --- a/libcnb-test/src/test_runner.rs +++ b/libcnb-test/src/test_runner.rs @@ -1,9 +1,7 @@ use crate::docker::DockerRemoveImageCommand; use crate::pack::PackBuildCommand; use crate::util::CommandError; -use crate::{ - app, build, util, BuildConfig, BuildpackReference, LogOutput, PackResult, TestContext, -}; +use crate::{app, build, util, BuildConfig, BuildpackReference, PackResult, TestContext}; use std::borrow::Borrow; use std::env; use std::path::PathBuf; @@ -119,10 +117,10 @@ impl TestRunner { let output = match (&config.expected_pack_result, pack_result) { (PackResult::Success, Ok(output)) => output, - (PackResult::Failure, Err(CommandError::NonZeroExitCode { stdout, stderr, .. })) => { - LogOutput { stdout, stderr } + (PackResult::Failure, Err(CommandError::NonZeroExitCode { log_output, .. })) => { + log_output } - (PackResult::Failure, Ok(LogOutput { stdout, stderr })) => { + (PackResult::Failure, Ok(log_output)) => { // Ordinarily the Docker image created by `pack build` will either be cleaned up by // `TestContext::Drop` later on, or will not have been created in the first place, // if the `pack build` was not successful. However, in the case of an unexpectedly @@ -130,7 +128,7 @@ impl TestRunner { util::run_command(DockerRemoveImageCommand::new(image_name)).unwrap_or_else( |command_err| panic!("Error removing Docker image:\n\n{command_err}"), ); - panic!("The pack build was expected to fail, but did not:\n\n## stderr:\n\n{stderr}\n## stdout:\n\n{stdout}\n"); + panic!("The pack build was expected to fail, but did not:\n\n{log_output}"); } (_, Err(command_err)) => { panic!("Error performing pack build:\n\n{command_err}"); diff --git a/libcnb-test/src/util.rs b/libcnb-test/src/util.rs index e0dd8eef..5c629269 100644 --- a/libcnb-test/src/util.rs +++ b/libcnb-test/src/util.rs @@ -40,17 +40,18 @@ pub(crate) fn run_command(command: impl Into) -> Result, program: String, - stdout: String, - stderr: String, + log_output: LogOutput, }, } @@ -89,11 +89,10 @@ impl Display for CommandError { CommandError::NonZeroExitCode { program, exit_code, - stdout, - stderr, + log_output, } => write!( f, - "{program} command failed with exit code {}!\n\n## stderr:\n\n{stderr}\n## stdout:\n\n{stdout}\n", + "{program} command failed with exit code {}!\n\n{log_output}", exit_code.map_or(String::from(""), |exit_code| exit_code.to_string()) ), } From e99e3aaab211b202dc5aecbd41e311b150174b64 Mon Sep 17 00:00:00 2001 From: Ed Morley <501702+edmorley@users.noreply.github.com> Date: Thu, 17 Aug 2023 14:59:46 +0000 Subject: [PATCH 02/11] libcnb-test: Improve error messages for `address_for_port` (#636) Improves the debugging UX for several `ContainerContext::address_for_port` failure modes. In particular, if containers crash after startup then the container logs are now included in the panic error message, rather than only the potentially confusing "No public port X published" message from Docker. Fixes #482. GUS-W-13966399. --- CHANGELOG.md | 6 +++-- libcnb-test/src/container_config.rs | 2 +- libcnb-test/src/container_context.rs | 35 ++++++++++++++++++++------- libcnb-test/src/test_context.rs | 5 +++- libcnb-test/tests/integration_test.rs | 28 ++++++++++----------- 5 files changed, 49 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 413ba5ff..b3392f50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,12 +9,14 @@ separate changelogs for each crate were used. If you need to refer to these old ### Added - `libcnb-package`: Add cross-compilation assistance for Linux `aarch64-unknown-linux-musl`. ([#577](https://github.com/heroku/libcnb.rs/pull/577)) -- `libcnb-test`: `LogOutput` now implements `std::fmt::Display`. ([#635](https://github.com/heroku/libcnb.rs/pull/635)) +- `libcnb-test`: + - `LogOutput` now implements `std::fmt::Display`. ([#635](https://github.com/heroku/libcnb.rs/pull/635)) + - `ContainerConfig` now implements `Clone`. ([#636](https://github.com/heroku/libcnb.rs/pull/636)) ### Changed - `libcnb-test`: - - `ContainerContext::address_for_port` now returns `SocketAddr` directly instead of `Option`. ([#605](https://github.com/heroku/libcnb.rs/pull/605)) + - `ContainerContext::address_for_port` will now panic for all failure modes rather than just some, and so now returns `SocketAddr` directly instead of `Option`. This reduces test boilerplate due to the caller no longer needing to `.unwrap()` and improves debugging UX when containers crash after startup. ([#605](https://github.com/heroku/libcnb.rs/pull/605) and [#636](https://github.com/heroku/libcnb.rs/pull/636)) - Docker commands are now run using the Docker CLI instead of Bollard and the Docker daemon API. ([#620](https://github.com/heroku/libcnb.rs/pull/620)) - `ContainerConfig::entrypoint` now accepts a String rather than a vector of strings. Any arguments to the entrypoint should be moved to `ContainerConfig::command`. ([#620](https://github.com/heroku/libcnb.rs/pull/620)) - `TestRunner::new` has been removed, since its only purpose was for advanced configuration that's no longer applicable. Use `TestRunner::default` instead. ([#620](https://github.com/heroku/libcnb.rs/pull/620)) diff --git a/libcnb-test/src/container_config.rs b/libcnb-test/src/container_config.rs index c3828db4..f98f8b48 100644 --- a/libcnb-test/src/container_config.rs +++ b/libcnb-test/src/container_config.rs @@ -25,7 +25,7 @@ use std::collections::{HashMap, HashSet}; /// }, /// ); /// ``` -#[derive(Default)] +#[derive(Clone, Default)] pub struct ContainerConfig { pub(crate) entrypoint: Option, pub(crate) command: Option>, diff --git a/libcnb-test/src/container_context.rs b/libcnb-test/src/container_context.rs index 882968a1..5fa2146f 100644 --- a/libcnb-test/src/container_context.rs +++ b/libcnb-test/src/container_context.rs @@ -2,13 +2,15 @@ use crate::docker::{ DockerExecCommand, DockerLogsCommand, DockerPortCommand, DockerRemoveContainerCommand, }; use crate::log::LogOutput; -use crate::util; +use crate::util::CommandError; +use crate::{util, ContainerConfig}; use std::net::SocketAddr; /// Context of a launched container. pub struct ContainerContext { /// The randomly generated name of this container. pub container_name: String, + pub(crate) config: ContainerConfig, } impl ContainerContext { @@ -111,15 +113,30 @@ impl ContainerContext { /// was not exposed using [`ContainerConfig::expose_port`](crate::ContainerConfig::expose_port). #[must_use] pub fn address_for_port(&self, port: u16) -> SocketAddr { + assert!( + self.config.exposed_ports.contains(&port), + "Unknown port: Port {port} needs to be exposed first using `ContainerConfig::expose_port`" + ); + let docker_port_command = DockerPortCommand::new(&self.container_name, port); - util::run_command(docker_port_command) - .unwrap_or_else(|command_err| { - panic!("Error obtaining container port mapping:\n\n{command_err}") - }) - .stdout - .trim() - .parse() - .expect("Couldn't parse `docker port` output") + + match util::run_command(docker_port_command) { + Ok(output) => output + .stdout + .trim() + .parse() + .expect("Couldn't parse `docker port` output"), + Err(CommandError::NonZeroExitCode { log_output, .. }) => { + panic!( + "Error obtaining container port mapping:\n{}\nThis normally means that the container crashed. Container logs:\n\n{}", + log_output.stderr, + self.logs_now() + ); + } + Err(command_err) => { + panic!("Error obtaining container port mapping:\n\n{command_err}"); + } + } } /// Executes a shell command inside an already running container. diff --git a/libcnb-test/src/test_context.rs b/libcnb-test/src/test_context.rs index e838516d..bc08deb6 100644 --- a/libcnb-test/src/test_context.rs +++ b/libcnb-test/src/test_context.rs @@ -109,7 +109,10 @@ impl<'a> TestContext<'a> { util::run_command(docker_run_command) .unwrap_or_else(|command_err| panic!("Error starting container:\n\n{command_err}")); - f(ContainerContext { container_name }); + f(ContainerContext { + container_name, + config: config.clone(), + }); } /// Run the provided shell command. diff --git a/libcnb-test/tests/integration_test.rs b/libcnb-test/tests/integration_test.rs index 36e8bc85..76bfaedc 100644 --- a/libcnb-test/tests/integration_test.rs +++ b/libcnb-test/tests/integration_test.rs @@ -475,13 +475,9 @@ fn expose_port_invalid_port() { #[test] #[ignore = "integration test"] -#[should_panic(expected = "Error obtaining container port mapping: - -docker command failed with exit code 1! - -## stderr: - -Error: No public port '12345")] +#[should_panic( + expected = "Unknown port: Port 12345 needs to be exposed first using `ContainerConfig::expose_port`" +)] fn address_for_port_when_port_not_exposed() { TestRunner::default().build( BuildConfig::new("heroku/builder:22", "test-fixtures/procfile") @@ -496,14 +492,17 @@ fn address_for_port_when_port_not_exposed() { #[test] #[ignore = "integration test"] -// TODO: Improve the UX here: https://github.com/heroku/libcnb.rs/issues/482 -#[should_panic(expected = "Error obtaining container port mapping: - -docker command failed with exit code 1! +#[should_panic(expected = " +This normally means that the container crashed. Container logs: ## stderr: -Error: No public port '12345")] +some stderr + +## stdout: + +some stdout +")] fn address_for_port_when_container_crashed() { TestRunner::default().build( BuildConfig::new("heroku/builder:22", "test-fixtures/procfile") @@ -512,11 +511,12 @@ fn address_for_port_when_container_crashed() { context.start_container( ContainerConfig::new() .entrypoint("launcher") - .command(["exit 1"]) + .command(["echo 'some stdout'; echo 'some stderr' >&2; exit 1"]) .expose_port(TEST_PORT), |container| { + // Wait for the container to actually exit, otherwise `address_for_port()` will succeed. thread::sleep(Duration::from_secs(1)); - let _ = container.address_for_port(12345); + let _ = container.address_for_port(TEST_PORT); }, ); }, From e3a3da8fecfd08b4815a782ba2dc449d71e8f6e9 Mon Sep 17 00:00:00 2001 From: Manuel Fuchs Date: Thu, 17 Aug 2023 18:27:53 +0200 Subject: [PATCH 03/11] Refactor libcnb-cargo integration tests (#637) --- libcnb-cargo/Cargo.toml | 1 - libcnb-cargo/src/main.rs | 2 - libcnb-cargo/tests/test.rs | 509 +++++++++++++++++++------------------ 3 files changed, 268 insertions(+), 244 deletions(-) diff --git a/libcnb-cargo/Cargo.toml b/libcnb-cargo/Cargo.toml index a39d1832..d5eefe23 100644 --- a/libcnb-cargo/Cargo.toml +++ b/libcnb-cargo/Cargo.toml @@ -31,5 +31,4 @@ thiserror = "1.0.41" toml.workspace = true [dev-dependencies] -fs_extra = "1.3.0" tempfile = "3.6.0" diff --git a/libcnb-cargo/src/main.rs b/libcnb-cargo/src/main.rs index ed2b1003..82df916e 100644 --- a/libcnb-cargo/src/main.rs +++ b/libcnb-cargo/src/main.rs @@ -9,8 +9,6 @@ mod package; // Suppress warnings due to the `unused_crate_dependencies` lint not handling integration tests well. #[cfg(test)] -use fs_extra as _; -#[cfg(test)] use tempfile as _; use crate::cli::{Cli, LibcnbSubcommand}; diff --git a/libcnb-cargo/tests/test.rs b/libcnb-cargo/tests/test.rs index 378f3ce6..10c9c9db 100644 --- a/libcnb-cargo/tests/test.rs +++ b/libcnb-cargo/tests/test.rs @@ -1,307 +1,334 @@ -use fs_extra::dir::{copy, CopyOptions}; -use libcnb_data::buildpack::{BuildpackDescriptor, BuildpackId}; +// Enable Clippy lints that are disabled by default. +// https://rust-lang.github.io/rust-clippy/stable/index.html +#![warn(clippy::pedantic)] + +use libcnb_data::buildpack::BuildpackId; use libcnb_data::buildpack_id; -use libcnb_package::{get_buildpack_target_dir, read_buildpack_data, read_buildpackage_data}; -use std::env; -use std::io::Read; -use std::path::PathBuf; -use std::process::{Command, Stdio}; -use tempfile::{tempdir, TempDir}; +use libcnb_data::buildpackage::BuildpackageDependency; +use libcnb_package::{read_buildpack_data, read_buildpackage_data}; +use std::io::ErrorKind; +use std::path::{Path, PathBuf}; +use std::process::Command; +use std::{env, fs}; +use tempfile::{tempdir_in, TempDir}; #[test] #[ignore = "integration test"] fn package_buildpack_in_single_buildpack_project() { - let packaging_test = BuildpackPackagingTest::new("single_buildpack", X86_64_UNKNOWN_LINUX_MUSL); - let output = packaging_test.run_libcnb_package(); + let fixture_dir = copy_fixture_to_temp_dir("single_buildpack").unwrap(); + let buildpack_id = buildpack_id!("single-buildpack"); + + let output = Command::new(CARGO_LIBCNB_BINARY_UNDER_TEST) + .args(["libcnb", "package", "--release"]) + .current_dir(&fixture_dir) + .output() + .unwrap(); + + let packaged_buildpack_dir = create_packaged_buildpack_dir_resolver( + &fixture_dir.path().join(TARGET_DIR_NAME), + true, + X86_64_UNKNOWN_LINUX_MUSL, + )(&buildpack_id); + assert_eq!( - output.stdout.trim(), - [packaging_test.target_dir_name(buildpack_id!("single-buildpack"))].join("\n") + String::from_utf8_lossy(&output.stdout), + format!("{}\n", packaged_buildpack_dir.to_string_lossy()) ); - assert_compiled_buildpack(&packaging_test, buildpack_id!("single-buildpack")); + + validate_packaged_buildpack(&packaged_buildpack_dir, &buildpack_id); } #[test] #[ignore = "integration test"] fn package_single_meta_buildpack_in_monorepo_buildpack_project() { - let packaging_test = - BuildpackPackagingTest::new("multiple_buildpacks", X86_64_UNKNOWN_LINUX_MUSL); - let output = packaging_test.run_libcnb_package_from("meta-buildpacks/meta-one"); - assert_eq!( - output.stdout.trim(), - [packaging_test.target_dir_name(buildpack_id!("multiple-buildpacks/meta-one"))].join("\n") + let fixture_dir = copy_fixture_to_temp_dir("multiple_buildpacks").unwrap(); + + let output = Command::new(CARGO_LIBCNB_BINARY_UNDER_TEST) + .args(["libcnb", "package", "--release"]) + .current_dir(fixture_dir.path().join("meta-buildpacks").join("meta-one")) + .output() + .unwrap(); + + let packaged_buildpack_dir_resolver = create_packaged_buildpack_dir_resolver( + &fixture_dir.path().join(TARGET_DIR_NAME), + true, + X86_64_UNKNOWN_LINUX_MUSL, ); - assert_compiled_buildpack(&packaging_test, buildpack_id!("multiple-buildpacks/one")); - assert_compiled_buildpack(&packaging_test, buildpack_id!("multiple-buildpacks/two")); - assert_compiled_meta_buildpack( - &packaging_test, - buildpack_id!("multiple-buildpacks/meta-one"), - vec![ - packaging_test.target_dir_name(buildpack_id!("multiple-buildpacks/one")), - packaging_test.target_dir_name(buildpack_id!("multiple-buildpacks/two")), - packaging_test - .dir() - .join("meta-buildpacks/meta-one/../../buildpacks/not_libcnb") + + assert_eq!( + String::from_utf8_lossy(&output.stdout), + format!( + "{}\n", + packaged_buildpack_dir_resolver(&buildpack_id!("multiple-buildpacks/meta-one")) .to_string_lossy() - .to_string(), - String::from("docker://docker.io/heroku/procfile-cnb:2.0.0"), - ], + ) + ); + + validate_packaged_meta_buildpack( + &packaged_buildpack_dir_resolver(&buildpack_id!("multiple-buildpacks/meta-one")), + &buildpack_id!("multiple-buildpacks/meta-one"), + &[ + BuildpackageDependency::try_from(packaged_buildpack_dir_resolver(&buildpack_id!( + "multiple-buildpacks/one" + ))), + BuildpackageDependency::try_from(packaged_buildpack_dir_resolver(&buildpack_id!( + "multiple-buildpacks/two" + ))), + BuildpackageDependency::try_from( + fixture_dir + .path() + .join("meta-buildpacks/meta-one/../../buildpacks/not_libcnb"), + ), + BuildpackageDependency::try_from("docker://docker.io/heroku/procfile-cnb:2.0.0"), + ] + .into_iter() + .collect::, _>>() + .unwrap(), ); + + for buildpack_id in [ + buildpack_id!("multiple-buildpacks/one"), + buildpack_id!("multiple-buildpacks/two"), + ] { + validate_packaged_buildpack( + &packaged_buildpack_dir_resolver(&buildpack_id), + &buildpack_id, + ); + } } #[test] #[ignore = "integration test"] fn package_single_buildpack_in_monorepo_buildpack_project() { - let packaging_test = - BuildpackPackagingTest::new("multiple_buildpacks", X86_64_UNKNOWN_LINUX_MUSL); - let output = packaging_test.run_libcnb_package_from("buildpacks/one"); + let fixture_dir = copy_fixture_to_temp_dir("multiple_buildpacks").unwrap(); + let buildpack_id = buildpack_id!("multiple-buildpacks/one"); + + let output = Command::new(CARGO_LIBCNB_BINARY_UNDER_TEST) + .args(["libcnb", "package", "--release"]) + .current_dir(fixture_dir.path().join("buildpacks/one")) + .output() + .unwrap(); + + let packaged_buildpack_dir = create_packaged_buildpack_dir_resolver( + &fixture_dir.path().join(TARGET_DIR_NAME), + true, + X86_64_UNKNOWN_LINUX_MUSL, + )(&buildpack_id); + assert_eq!( - output.stdout.trim(), - [packaging_test.target_dir_name(buildpack_id!("multiple-buildpacks/one"))].join("\n") + String::from_utf8_lossy(&output.stdout), + format!("{}\n", packaged_buildpack_dir.to_string_lossy()) ); - assert_compiled_buildpack(&packaging_test, buildpack_id!("multiple-buildpacks/one")); - assert!(!packaging_test - .target_dir(buildpack_id!("multiple-buildpacks/two")) - .exists()); - assert!(!packaging_test - .target_dir(buildpack_id!("multiple-buildpacks/meta-one")) - .exists()); + + validate_packaged_buildpack(&packaged_buildpack_dir, &buildpack_id); } #[test] #[ignore = "integration test"] fn package_all_buildpacks_in_monorepo_buildpack_project() { - let packaging_test = - BuildpackPackagingTest::new("multiple_buildpacks", X86_64_UNKNOWN_LINUX_MUSL); - let output = packaging_test.run_libcnb_package(); + let fixture_dir = copy_fixture_to_temp_dir("multiple_buildpacks").unwrap(); + + let dependent_buildpack_ids = [ + buildpack_id!("multiple-buildpacks/one"), + buildpack_id!("multiple-buildpacks/two"), + ]; + + let output = Command::new(CARGO_LIBCNB_BINARY_UNDER_TEST) + .args(["libcnb", "package", "--release"]) + .current_dir(&fixture_dir) + .output() + .unwrap(); + + let packaged_buildpack_dir_resolver = create_packaged_buildpack_dir_resolver( + &fixture_dir.path().join(TARGET_DIR_NAME), + true, + X86_64_UNKNOWN_LINUX_MUSL, + ); + assert_eq!( - output.stdout.trim(), - [ - packaging_test - .dir() - .join("buildpacks/not_libcnb") - .to_string_lossy() - .to_string(), - packaging_test.target_dir_name(buildpack_id!("multiple-buildpacks/meta-one")), - packaging_test.target_dir_name(buildpack_id!("multiple-buildpacks/one")), - packaging_test.target_dir_name(buildpack_id!("multiple-buildpacks/two")), - ] - .join("\n") + String::from_utf8_lossy(&output.stdout), + format!( + "{}\n", + [ + fixture_dir.path().join("buildpacks/not_libcnb"), + packaged_buildpack_dir_resolver(&buildpack_id!("multiple-buildpacks/meta-one")), + packaged_buildpack_dir_resolver(&buildpack_id!("multiple-buildpacks/one")), + packaged_buildpack_dir_resolver(&buildpack_id!("multiple-buildpacks/two")) + ] + .map(|path| path.to_string_lossy().into_owned()) + .join("\n") + ) ); - assert_compiled_buildpack(&packaging_test, buildpack_id!("multiple-buildpacks/one")); - assert_compiled_buildpack(&packaging_test, buildpack_id!("multiple-buildpacks/two")); - assert_compiled_meta_buildpack( - &packaging_test, - buildpack_id!("multiple-buildpacks/meta-one"), - vec![ - packaging_test.target_dir_name(buildpack_id!("multiple-buildpacks/one")), - packaging_test.target_dir_name(buildpack_id!("multiple-buildpacks/two")), - packaging_test - .dir() - .join("meta-buildpacks/meta-one/../../buildpacks/not_libcnb") - .to_string_lossy() - .to_string(), - String::from("docker://docker.io/heroku/procfile-cnb:2.0.0"), - ], + + validate_packaged_meta_buildpack( + &packaged_buildpack_dir_resolver(&buildpack_id!("multiple-buildpacks/meta-one")), + &buildpack_id!("multiple-buildpacks/meta-one"), + &[ + BuildpackageDependency::try_from(packaged_buildpack_dir_resolver(&buildpack_id!( + "multiple-buildpacks/one" + ))), + BuildpackageDependency::try_from(packaged_buildpack_dir_resolver(&buildpack_id!( + "multiple-buildpacks/two" + ))), + BuildpackageDependency::try_from( + fixture_dir + .path() + .join("meta-buildpacks/meta-one/../../buildpacks/not_libcnb"), + ), + BuildpackageDependency::try_from("docker://docker.io/heroku/procfile-cnb:2.0.0"), + ] + .into_iter() + .collect::, _>>() + .unwrap(), ); + + for buildpack_id in dependent_buildpack_ids { + validate_packaged_buildpack( + &packaged_buildpack_dir_resolver(&buildpack_id), + &buildpack_id, + ); + } } #[test] #[ignore = "integration test"] fn package_non_libcnb_buildpack_in_meta_buildpack_project() { - let packaging_test = - BuildpackPackagingTest::new("multiple_buildpacks", X86_64_UNKNOWN_LINUX_MUSL); - let output = packaging_test.run_libcnb_package_from("buildpacks/not_libcnb"); + let fixture_dir = copy_fixture_to_temp_dir("multiple_buildpacks").unwrap(); + + let output = Command::new(CARGO_LIBCNB_BINARY_UNDER_TEST) + .args(["libcnb", "package", "--release"]) + .current_dir(fixture_dir.path().join("buildpacks/not_libcnb")) + .output() + .unwrap(); + assert_eq!( - output.stdout.trim(), - [packaging_test - .dir() - .join("buildpacks/not_libcnb") - .to_string_lossy() - .to_string()] - .join("\n") + String::from_utf8_lossy(&output.stdout), + format!( + "{}\n", + fixture_dir + .path() + .join("buildpacks/not_libcnb") + .to_string_lossy() + ) ); - assert!(!packaging_test - .target_dir(buildpack_id!("multiple-buildpacks/one")) - .exists()); - assert!(!packaging_test - .target_dir(buildpack_id!("multiple-buildpacks/two")) - .exists()); - assert!(!packaging_test - .target_dir(buildpack_id!("multiple-buildpacks/meta-one")) - .exists()); } #[test] #[ignore = "integration test"] fn package_command_error_when_run_in_project_with_no_buildpacks() { - let packaging_test = BuildpackPackagingTest::new("no_buildpacks", X86_64_UNKNOWN_LINUX_MUSL); - let output = packaging_test.run_libcnb_package(); - assert_ne!(output.code, Some(0)); + let fixture_dir = copy_fixture_to_temp_dir("no_buildpacks").unwrap(); + + let output = Command::new(CARGO_LIBCNB_BINARY_UNDER_TEST) + .args(["libcnb", "package", "--release"]) + .current_dir(&fixture_dir) + .output() + .unwrap(); + + assert_ne!(output.status.code(), Some(0)); assert_eq!( - output.stderr, + String::from_utf8_lossy(&output.stderr), "šŸ” Locating buildpacks...\nāŒ No buildpacks found!\n" ); } -fn assert_compiled_buildpack(packaging_test: &BuildpackPackagingTest, buildpack_id: BuildpackId) { - let buildpack_target_dir = PathBuf::from(packaging_test.target_dir_name(buildpack_id.clone())); - - assert!(buildpack_target_dir.exists()); - assert!(buildpack_target_dir.join("buildpack.toml").exists()); - assert!(buildpack_target_dir.join("package.toml").exists()); - assert!(buildpack_target_dir.join("bin").join("build").exists()); - assert!(buildpack_target_dir.join("bin").join("detect").exists()); - - let buildpack_data = read_buildpack_data(&buildpack_target_dir).unwrap(); - let id = match buildpack_data.buildpack_descriptor { - BuildpackDescriptor::Single(descriptor) => descriptor.buildpack.id, - BuildpackDescriptor::Meta(descriptor) => descriptor.buildpack.id, - }; - assert_eq!(id, buildpack_id); +fn validate_packaged_buildpack(packaged_buildpack_dir: &Path, buildpack_id: &BuildpackId) { + assert!(packaged_buildpack_dir.join("buildpack.toml").exists()); + assert!(packaged_buildpack_dir.join("package.toml").exists()); + assert!(packaged_buildpack_dir.join("bin").join("build").exists()); + assert!(packaged_buildpack_dir.join("bin").join("detect").exists()); + + assert_eq!( + &read_buildpack_data(packaged_buildpack_dir) + .unwrap() + .buildpack_descriptor + .buildpack() + .id, + buildpack_id + ); } -fn assert_compiled_meta_buildpack( - packaging_test: &BuildpackPackagingTest, - buildpack_id: BuildpackId, - dependencies: Vec, +fn validate_packaged_meta_buildpack( + packaged_buildpack_dir: &Path, + buildpack_id: &BuildpackId, + expected_buildpackage_dependencies: &[BuildpackageDependency], ) { - let buildpack_target_dir = PathBuf::from(packaging_test.target_dir_name(buildpack_id.clone())); - - assert!(buildpack_target_dir.exists()); - assert!(buildpack_target_dir.join("buildpack.toml").exists()); - assert!(buildpack_target_dir.join("package.toml").exists()); - - let buildpack_data = read_buildpack_data(&buildpack_target_dir).unwrap(); - let id = match buildpack_data.buildpack_descriptor { - BuildpackDescriptor::Single(descriptor) => descriptor.buildpack.id, - BuildpackDescriptor::Meta(descriptor) => descriptor.buildpack.id, - }; - assert_eq!(id, buildpack_id); - - let buildpackage_data = read_buildpackage_data(buildpack_target_dir) - .unwrap() - .unwrap(); - let compiled_uris: Vec<_> = buildpackage_data - .buildpackage_descriptor - .dependencies - .iter() - .map(|buildpackage_uri| buildpackage_uri.uri.to_string()) - .collect(); - assert_eq!(compiled_uris, dependencies); -} + assert!(packaged_buildpack_dir.join("buildpack.toml").exists()); + assert!(packaged_buildpack_dir.join("package.toml").exists()); -struct BuildpackPackagingTest { - fixture_name: String, - temp_dir: TempDir, - release_build: bool, - target_triple: String, -} + assert_eq!( + &read_buildpack_data(packaged_buildpack_dir) + .unwrap() + .buildpack_descriptor + .buildpack() + .id, + buildpack_id + ); -struct TestOutput { - stdout: String, - stderr: String, - code: Option, + assert_eq!( + read_buildpackage_data(packaged_buildpack_dir) + .unwrap() + .unwrap() + .buildpackage_descriptor + .dependencies, + expected_buildpackage_dependencies + ); } -impl BuildpackPackagingTest { - fn new(fixture_name: &str, target_triple: &str) -> Self { - let source_directory = env::current_dir() - .unwrap() - .join("fixtures") - .join(fixture_name); - let target_directory = tempdir().unwrap(); - let copy_options = CopyOptions::new(); - copy(source_directory, &target_directory, ©_options).unwrap(); - BuildpackPackagingTest { - fixture_name: fixture_name.to_string(), - temp_dir: target_directory, - release_build: true, - target_triple: String::from(target_triple), - } - } +fn create_packaged_buildpack_dir_resolver( + cargo_target_dir: &Path, + release: bool, + target_triple: &str, +) -> impl Fn(&BuildpackId) -> PathBuf { + let cargo_target_dir = PathBuf::from(cargo_target_dir); + let target_triple = target_triple.to_string(); - fn dir(&self) -> PathBuf { - self.temp_dir - .path() - .canonicalize() - .unwrap() - .join(&self.fixture_name) + move |buildpack_id| { + cargo_target_dir + .join("buildpack") + .join(&target_triple) + .join(if release { "release" } else { "debug" }) + .join(buildpack_id.as_str().replace('/', "_")) } +} - fn target_dir_name(&self, buildpack_id: BuildpackId) -> String { - self.target_dir(buildpack_id) - .canonicalize() - .unwrap() - .to_string_lossy() - .to_string() - } +fn copy_fixture_to_temp_dir(name: &str) -> Result { + let fixture_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("fixtures") + .join(name); - fn target_dir(&self, buildpack_id: BuildpackId) -> PathBuf { - get_buildpack_target_dir( - &buildpack_id, - &self.dir().join("target"), - self.release_build, - &self.target_triple, - ) - } + // Instead of using `tempfile::tempdir` directly, we get the temporary directory ourselves and + // canonicalize it before creating a temporary directory inside. We do this since on some + // operating systems (macOS specifically, see: https://github.com/rust-lang/rust/issues/99608), + // `env::temp_dir` will return a path with symlinks in it and `TempDir` doesn't allow + // canonicalization after the fact. + // + // Since libcnb-cargo itself also canonicalizes, we need to do the same so we can compare + // paths when they're output as strings. + env::temp_dir() + .canonicalize() + .and_then(tempdir_in) + .and_then(|temp_dir| copy_dir_recursively(&fixture_dir, temp_dir.path()).map(|_| temp_dir)) +} - fn run_libcnb_package(&self) -> TestOutput { - self.run_libcnb_package_from(".") - } +fn copy_dir_recursively(source: &Path, destination: &Path) -> std::io::Result<()> { + match fs::create_dir(destination) { + Err(io_error) if io_error.kind() == ErrorKind::AlreadyExists => Ok(()), + other => other, + }?; - fn run_libcnb_package_from(&self, from_dir: &str) -> TestOutput { - // borrowed from assert_cmd - let suffix = env::consts::EXE_SUFFIX; - - let target_dir = env::current_exe() - .ok() - .map(|mut path| { - path.pop(); - if path.ends_with("deps") { - path.pop(); - } - path - }) - .unwrap(); - - let name = "cargo-libcnb"; - - let cargo_libcnb = env::var_os(format!("CARGO_BIN_EXE_{name}")) - .map(|p| p.into()) - .unwrap_or_else(|| target_dir.join(format!("{name}{suffix}"))); - - let mut cmd = Command::new(cargo_libcnb) - .args(["libcnb", "package", "--release"]) - .current_dir(self.dir().join(from_dir)) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .spawn() - .unwrap(); - - let status = cmd.wait().unwrap(); - - let mut stdout = String::new(); - cmd.stdout - .take() - .unwrap() - .read_to_string(&mut stdout) - .unwrap(); - println!("STDOUT:\n{stdout}"); + for entry in fs::read_dir(source)? { + let dir_entry = entry?; - let mut stderr = String::new(); - cmd.stderr - .take() - .unwrap() - .read_to_string(&mut stderr) - .unwrap(); - println!("STDERR:\n{stderr}"); - - TestOutput { - stdout: String::from_utf8_lossy(stdout.as_bytes()).to_string(), - stderr: String::from_utf8_lossy(stderr.as_bytes()).to_string(), - code: status.code(), + if dir_entry.file_type()?.is_dir() { + copy_dir_recursively(&dir_entry.path(), &destination.join(dir_entry.file_name()))?; + } else { + fs::copy(dir_entry.path(), destination.join(dir_entry.file_name()))?; } } + + Ok(()) } const X86_64_UNKNOWN_LINUX_MUSL: &str = "x86_64-unknown-linux-musl"; +const TARGET_DIR_NAME: &str = "target"; +const CARGO_LIBCNB_BINARY_UNDER_TEST: &str = env!("CARGO_BIN_EXE_cargo-libcnb"); From ec90a43d322715dccc4f0b04ddac15373364b3ef Mon Sep 17 00:00:00 2001 From: Manuel Fuchs Date: Fri, 18 Aug 2023 10:44:16 +0200 Subject: [PATCH 04/11] Move packaged buildpack directory out of `target/` (#583) --- .github/workflows/ci.yml | 2 +- .gitignore | 2 ++ CHANGELOG.md | 6 +++++- libcnb-cargo/src/cli.rs | 4 ++++ libcnb-cargo/src/package/command.rs | 27 ++++++++++++++++++--------- libcnb-cargo/src/package/error.rs | 3 +++ libcnb-cargo/tests/test.rs | 17 ++++++++--------- libcnb-package/src/lib.rs | 23 +++++++++-------------- 8 files changed, 50 insertions(+), 34 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 999261db..0093d899 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,4 +73,4 @@ jobs: # Uses a non-libc image to validate the static musl cross-compilation. # TODO: Switch this back to using the `alpine` tag once the stable Pack CLI release supports # image extensions (currently newer sample alpine images fail to build with stable Pack). - run: pack build example-basics --builder cnbs/sample-builder@sha256:da5ff69191919f1ff30d5e28859affff8e39f23038137c7751e24a42e919c1ab --trust-builder --buildpack target/buildpack/x86_64-unknown-linux-musl/debug/libcnb-examples_basics --path examples/ + run: pack build example-basics --builder cnbs/sample-builder@sha256:da5ff69191919f1ff30d5e28859affff8e39f23038137c7751e24a42e919c1ab --trust-builder --buildpack packaged/x86_64-unknown-linux-musl/debug/libcnb-examples_basics --path examples/ diff --git a/.gitignore b/.gitignore index c0f3e140..6addfe54 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ /target/ +/packaged/ .DS_Store .idea Cargo.lock **/fixtures/*/target/ +**/fixtures/*/packaged/ diff --git a/CHANGELOG.md b/CHANGELOG.md index b3392f50..7c7f7346 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ separate changelogs for each crate were used. If you need to refer to these old ### Added - `libcnb-package`: Add cross-compilation assistance for Linux `aarch64-unknown-linux-musl`. ([#577](https://github.com/heroku/libcnb.rs/pull/577)) +- `libcnb-cargo`: Add `--package-dir` command line option to control where packaged buildpacks are written to. ([#583](https://github.com/heroku/libcnb.rs/pull/583)) - `libcnb-test`: - `LogOutput` now implements `std::fmt::Display`. ([#635](https://github.com/heroku/libcnb.rs/pull/635)) - `ContainerConfig` now implements `Clone`. ([#636](https://github.com/heroku/libcnb.rs/pull/636)) @@ -22,9 +23,12 @@ separate changelogs for each crate were used. If you need to refer to these old - `TestRunner::new` has been removed, since its only purpose was for advanced configuration that's no longer applicable. Use `TestRunner::default` instead. ([#620](https://github.com/heroku/libcnb.rs/pull/620)) - `LogOutput` no longer exposes `stdout_raw` and `stderr_raw`. ([#607](https://github.com/heroku/libcnb.rs/pull/607)) - Improved wording of panic error messages. ([#619](https://github.com/heroku/libcnb.rs/pull/619) and [#620](https://github.com/heroku/libcnb.rs/pull/620)) -- `libcnb-package`: buildpack target directory now contains the target triple. Users that implicitly rely on the output directory need to adapt. The output of `cargo libcnb package` will refer to the new locations. ([#580](https://github.com/heroku/libcnb.rs/pull/580)) +- `libcnb-package`: + - buildpack target directory now contains the target triple. Users that implicitly rely on the output directory need to adapt. The output of `cargo libcnb package` will refer to the new locations. ([#580](https://github.com/heroku/libcnb.rs/pull/580)) + - `get_buildpack_target_dir` was renamed to `get_buildpack_package_dir` ([#583](https://github.com/heroku/libcnb.rs/pull/583)) - `libherokubuildpack`: Switch the `flate2` decompression backend from `miniz_oxide` to `zlib`. ([#593](https://github.com/heroku/libcnb.rs/pull/593)) - Bump minimum external dependency versions. ([#587](https://github.com/heroku/libcnb.rs/pull/587)) +- `libcnb-cargo`: Default location for packaged buildpacks moved from Cargo's `target` directory to `packaged` in the Cargo workspace root. This simplifies the path and stops modification of the `target` directory which previously might have caching implications when other tools didn't expect non-Cargo output in that directory. Users that implicitly rely on the output directory need to adapt. The output of `cargo libcnb package` will refer to the new locations. ([#583](https://github.com/heroku/libcnb.rs/pull/583)) ### Fixed diff --git a/libcnb-cargo/src/cli.rs b/libcnb-cargo/src/cli.rs index c6f7e64c..86290a0c 100644 --- a/libcnb-cargo/src/cli.rs +++ b/libcnb-cargo/src/cli.rs @@ -1,4 +1,5 @@ use clap::{Parser, Subcommand}; +use std::path::PathBuf; #[derive(Parser)] #[command(bin_name = "cargo")] @@ -25,6 +26,9 @@ pub(crate) struct PackageArgs { /// Build for the target triple #[arg(long, default_value = "x86_64-unknown-linux-musl")] pub target: String, + /// Directory for packaged buildpacks, defaults to 'packaged' in Cargo workspace root + #[arg(long)] + pub package_dir: Option, } #[cfg(test)] diff --git a/libcnb-cargo/src/package/command.rs b/libcnb-cargo/src/package/command.rs index 8cfc8523..d271861e 100644 --- a/libcnb-cargo/src/package/command.rs +++ b/libcnb-cargo/src/package/command.rs @@ -12,7 +12,7 @@ use libcnb_package::buildpack_package::{read_buildpack_package, BuildpackPackage use libcnb_package::cross_compile::{cross_compile_assistance, CrossCompileAssistance}; use libcnb_package::dependency_graph::{create_dependency_graph, get_dependencies}; use libcnb_package::{ - assemble_buildpack_directory, find_buildpack_dirs, get_buildpack_target_dir, CargoProfile, + assemble_buildpack_directory, find_buildpack_dirs, get_buildpack_package_dir, CargoProfile, }; use std::collections::HashMap; use std::path::{Path, PathBuf}; @@ -25,21 +25,30 @@ pub(crate) fn execute(args: &PackageArgs) -> Result<()> { let current_dir = std::env::current_dir().map_err(Error::GetCurrentDir)?; - let workspace = get_cargo_workspace_root(¤t_dir)?; + let workspace_root_path = get_cargo_workspace_root(¤t_dir)?; - let workspace_target_dir = MetadataCommand::new() - .manifest_path(&workspace.join("Cargo.toml")) + let cargo_metadata = MetadataCommand::new() + .manifest_path(&workspace_root_path.join("Cargo.toml")) .exec() - .map(|metadata| metadata.target_directory.into_std_path_buf()) .map_err(|e| Error::ReadCargoMetadata { - path: workspace.clone(), + path: workspace_root_path.clone(), source: e, })?; + let package_dir = args.package_dir.clone().unwrap_or_else(|| { + cargo_metadata + .workspace_root + .into_std_path_buf() + .join("packaged") + }); + + std::fs::create_dir_all(&package_dir) + .map_err(|e| Error::CreatePackageDirectory(package_dir.clone(), e))?; + let buildpack_packages = create_dependency_graph( - find_buildpack_dirs(&workspace, &[workspace_target_dir.clone()]) + find_buildpack_dirs(&workspace_root_path, &[package_dir.clone()]) .map_err(|e| Error::FindBuildpackDirs { - path: workspace_target_dir.clone(), + path: workspace_root_path, source: e, })? .into_iter() @@ -54,7 +63,7 @@ pub(crate) fn execute(args: &PackageArgs) -> Result<()> { let target_dir = if contains_buildpack_binaries(&buildpack_package.path) { buildpack_package.path.clone() } else { - get_buildpack_target_dir(id, &workspace_target_dir, args.release, &args.target) + get_buildpack_package_dir(id, &package_dir, args.release, &args.target) }; (id, target_dir) }) diff --git a/libcnb-cargo/src/package/error.rs b/libcnb-cargo/src/package/error.rs index 07939f8e..2013c823 100644 --- a/libcnb-cargo/src/package/error.rs +++ b/libcnb-cargo/src/package/error.rs @@ -27,6 +27,9 @@ pub(crate) enum Error { source: cargo_metadata::Error, }, + #[error("Could not create package directory: {0}\nError: {1}")] + CreatePackageDirectory(PathBuf, std::io::Error), + #[error("Could not determine a target directory for buildpack with id `{buildpack_id}`")] TargetDirectoryLookup { buildpack_id: BuildpackId }, diff --git a/libcnb-cargo/tests/test.rs b/libcnb-cargo/tests/test.rs index 10c9c9db..362531ea 100644 --- a/libcnb-cargo/tests/test.rs +++ b/libcnb-cargo/tests/test.rs @@ -25,7 +25,7 @@ fn package_buildpack_in_single_buildpack_project() { .unwrap(); let packaged_buildpack_dir = create_packaged_buildpack_dir_resolver( - &fixture_dir.path().join(TARGET_DIR_NAME), + &fixture_dir.path().join(DEFAULT_PACKAGE_DIR_NAME), true, X86_64_UNKNOWN_LINUX_MUSL, )(&buildpack_id); @@ -50,7 +50,7 @@ fn package_single_meta_buildpack_in_monorepo_buildpack_project() { .unwrap(); let packaged_buildpack_dir_resolver = create_packaged_buildpack_dir_resolver( - &fixture_dir.path().join(TARGET_DIR_NAME), + &fixture_dir.path().join(DEFAULT_PACKAGE_DIR_NAME), true, X86_64_UNKNOWN_LINUX_MUSL, ); @@ -110,7 +110,7 @@ fn package_single_buildpack_in_monorepo_buildpack_project() { .unwrap(); let packaged_buildpack_dir = create_packaged_buildpack_dir_resolver( - &fixture_dir.path().join(TARGET_DIR_NAME), + &fixture_dir.path().join(DEFAULT_PACKAGE_DIR_NAME), true, X86_64_UNKNOWN_LINUX_MUSL, )(&buildpack_id); @@ -140,7 +140,7 @@ fn package_all_buildpacks_in_monorepo_buildpack_project() { .unwrap(); let packaged_buildpack_dir_resolver = create_packaged_buildpack_dir_resolver( - &fixture_dir.path().join(TARGET_DIR_NAME), + &fixture_dir.path().join(DEFAULT_PACKAGE_DIR_NAME), true, X86_64_UNKNOWN_LINUX_MUSL, ); @@ -275,16 +275,15 @@ fn validate_packaged_meta_buildpack( } fn create_packaged_buildpack_dir_resolver( - cargo_target_dir: &Path, + package_dir: &Path, release: bool, target_triple: &str, ) -> impl Fn(&BuildpackId) -> PathBuf { - let cargo_target_dir = PathBuf::from(cargo_target_dir); + let package_dir = PathBuf::from(package_dir); let target_triple = target_triple.to_string(); move |buildpack_id| { - cargo_target_dir - .join("buildpack") + package_dir .join(&target_triple) .join(if release { "release" } else { "debug" }) .join(buildpack_id.as_str().replace('/', "_")) @@ -330,5 +329,5 @@ fn copy_dir_recursively(source: &Path, destination: &Path) -> std::io::Result<() } const X86_64_UNKNOWN_LINUX_MUSL: &str = "x86_64-unknown-linux-musl"; -const TARGET_DIR_NAME: &str = "target"; const CARGO_LIBCNB_BINARY_UNDER_TEST: &str = env!("CARGO_BIN_EXE_cargo-libcnb"); +const DEFAULT_PACKAGE_DIR_NAME: &str = "packaged"; diff --git a/libcnb-package/src/lib.rs b/libcnb-package/src/lib.rs index aafbe88b..07043606 100644 --- a/libcnb-package/src/lib.rs +++ b/libcnb-package/src/lib.rs @@ -255,14 +255,13 @@ pub fn find_buildpack_dirs(start_dir: &Path, ignore: &[PathBuf]) -> std::io::Res /// Provides a standard path to use for storing a compiled buildpack's artifacts. #[must_use] -pub fn get_buildpack_target_dir( +pub fn get_buildpack_package_dir( buildpack_id: &BuildpackId, - target_dir: &Path, + package_dir: &Path, is_release: bool, target_triple: &str, ) -> PathBuf { - target_dir - .join("buildpack") + package_dir .join(target_triple) .join(if is_release { "release" } else { "debug" }) .join(default_buildpack_directory_name(buildpack_id)) @@ -270,27 +269,23 @@ pub fn get_buildpack_target_dir( #[cfg(test)] mod tests { - use crate::get_buildpack_target_dir; + use crate::get_buildpack_package_dir; use libcnb_data::buildpack_id; use std::path::PathBuf; #[test] fn test_get_buildpack_target_dir() { let buildpack_id = buildpack_id!("some-org/with-buildpack"); - let target_dir = PathBuf::from("/target"); + let package_dir = PathBuf::from("/package"); let target_triple = "x86_64-unknown-linux-musl"; assert_eq!( - get_buildpack_target_dir(&buildpack_id, &target_dir, false, target_triple), - PathBuf::from( - "/target/buildpack/x86_64-unknown-linux-musl/debug/some-org_with-buildpack" - ) + get_buildpack_package_dir(&buildpack_id, &package_dir, false, target_triple), + PathBuf::from("/package/x86_64-unknown-linux-musl/debug/some-org_with-buildpack") ); assert_eq!( - get_buildpack_target_dir(&buildpack_id, &target_dir, true, target_triple), - PathBuf::from( - "/target/buildpack/x86_64-unknown-linux-musl/release/some-org_with-buildpack" - ) + get_buildpack_package_dir(&buildpack_id, &package_dir, true, target_triple), + PathBuf::from("/package/x86_64-unknown-linux-musl/release/some-org_with-buildpack") ); } } From 4644debb0eefe3fda39009372942f9b87d675184 Mon Sep 17 00:00:00 2001 From: Ed Morley <501702+edmorley@users.noreply.github.com> Date: Fri, 18 Aug 2023 09:07:29 +0000 Subject: [PATCH 05/11] Run `cargo upgrade` as part of preparing libcnb releases (#641) We've been previously doing these on an adhoc basis, but it makes sense to instead just do it as part of the release. Bumping the in-range versions ensures that consumers of libcnb get updated transitive dependencies (without having to manually refresh their own `Cargo.lock`s) that match the dependency versions tested in CI here (since this repo correctly doesn't use a lockfile, so will be using these latest in-range versions in CI etc). Eventually we can move all of these preparing release steps into a GitHub Actions workflow to reduce the toil of performing releases. --- RELEASING.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/RELEASING.md b/RELEASING.md index 18f878a6..adf63a24 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -12,7 +12,9 @@ easier to gauge cross-crate compatibility. 3. Update [CHANGELOG.md](./CHANGELOG.md) 1. Move all content under `## [Unreleased]` to a new section that follows this pattern: `## [VERSION] YYYY-MM-DD` 2. If appropriate, add a high-level summary of changes at the beginning of the new section -4. Commit the changes, push them and open a PR targeting `main` +4. Install the latest version of [cargo-edit](https://github.com/killercup/cargo-edit): `cargo install cargo-edit` +5. Bump in-range dependency versions using: `cargo upgrade` +6. Commit the changes, push them and open a PR targeting `main` ## Release From f892818e5656132a30ce1d764d292b955eabe51d Mon Sep 17 00:00:00 2001 From: Manuel Fuchs Date: Fri, 18 Aug 2023 11:56:37 +0200 Subject: [PATCH 06/11] Update Quick Start Guide (#640) --- README.md | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 6bbf3e15..e59be3b9 100644 --- a/README.md +++ b/README.md @@ -178,16 +178,22 @@ In your project directory, run `cargo libcnb package` to start packaging: ```shell $ cargo libcnb package -INFO - Reading buildpack metadata... -INFO - Found buildpack libcnb-examples/my-buildpack with version 0.1.0. -INFO - Determining automatic cross-compile settings... -INFO - Building binaries (x86_64-unknown-linux-musl)... +šŸ” Locating buildpacks... +šŸ“¦ [1/1] Building libcnb-examples/my-buildpack +Determining automatic cross-compile settings... +Building binaries (x86_64-unknown-linux-musl)... # Omitting compilation output... - Finished dev [unoptimized] target(s) in 8.51s -INFO - Writing buildpack directory... -INFO - Successfully wrote buildpack directory: target/buildpack/debug/libcnb-examples_my-buildpack (3.03 MiB) -INFO - Packaging successfully finished! -INFO - Hint: To test your buildpack locally with pack, run: pack build my-image --buildpack target/buildpack/debug/libcnb-examples_my-buildpack --path /path/to/application + Finished dev [unoptimized] target(s) in 8.92s +Writing buildpack directory... +Successfully wrote buildpack directory: packaged/x86_64-unknown-linux-musl/debug/libcnb-examples_my-buildpack (4.06 MiB) +āœØ Packaging successfully finished! + +šŸ’” To test your buildpack locally with pack, run: +pack build my-image-name \ + --buildpack /home/ponda.baba/my-buildpack/packaged/x86_64-unknown-linux-musl/debug/libcnb-examples_my-buildpack \ + --path /path/to/application + +/home/ponda.baba/my-buildpack/packaged/x86_64-unknown-linux-musl/debug/libcnb-examples_my-buildpack ``` If you get errors with hints about how to install required tools to cross-compile from your host platform to the @@ -202,10 +208,10 @@ application code at all, we just create an empty directory and use that as our a ```shell $ mkdir bogus-app -$ pack build my-image --buildpack target/buildpack/debug/libcnb-examples_my-buildpack --path bogus-app --builder heroku/builder:22 +$ pack build my-image --buildpack packaged/x86_64-unknown-linux-musl/debug/libcnb-examples_my-buildpack --path bogus-app --builder heroku/builder:22 ... ===> ANALYZING -Previous image with name "my-image" not found +Image with name "my-image" not found ===> DETECTING libcnb-examples/my-buildpack 0.1.0 ===> RESTORING @@ -213,17 +219,17 @@ libcnb-examples/my-buildpack 0.1.0 Hello World! Build runs on stack heroku-22! ===> EXPORTING -Adding layer 'launch.sbom' +Adding layer 'buildpacksio/lifecycle:launch.sbom' Adding 1/1 app layer(s) -Adding layer 'launcher' -Adding layer 'config' -Adding layer 'process-types' +Adding layer 'buildpacksio/lifecycle:launcher' +Adding layer 'buildpacksio/lifecycle:config' +Adding layer 'buildpacksio/lifecycle:process-types' Adding label 'io.buildpacks.lifecycle.metadata' Adding label 'io.buildpacks.build.metadata' Adding label 'io.buildpacks.project.metadata' Setting default process type 'web' Saving my-image... -*** Images (24eed75bb2e6): +*** Images (aa4695184718): my-image Successfully built image my-image ``` From 1db3a09f5bf42e7d061187399e4b12701db3a398 Mon Sep 17 00:00:00 2001 From: Ed Morley <501702+edmorley@users.noreply.github.com> Date: Fri, 18 Aug 2023 10:07:01 +0000 Subject: [PATCH 07/11] Add version links in the changelog (#643) And adjust style of headings. So that the changelog follows: https://keepachangelog.com/en/1.1.0/ --- CHANGELOG.md | 32 +++++++++++++++++++++++--------- RELEASING.md | 1 + 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c7f7346..347e4d60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ This is the new, unified, changelog that contains changes from across all libcnb separate changelogs for each crate were used. If you need to refer to these old changelogs, find them named `HISTORICAL_CHANGELOG.md` in their respective crate directories. +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + ## [Unreleased] ### Added @@ -37,7 +40,7 @@ separate changelogs for each crate were used. If you need to refer to these old - `ContainerContext::expose_port` now only exposes the port to localhost. ([#610](https://github.com/heroku/libcnb.rs/pull/610)) - If a test with an expected result of `PackResult::Failure` unexpectedly succeeds, the built app image is now correctly cleaned up. ([#625](https://github.com/heroku/libcnb.rs/pull/625)) -## [0.13.0] 2023-06-21 +## [0.13.0] - 2023-06-21 The highlight of this release is the `cargo libcnb package` changes to support compilation of both buildpacks and meta-buildpacks. @@ -76,7 +79,7 @@ The highlight of this release is the `cargo libcnb package` changes to support c `dependency_graph::get_dependencies` to support dependency ordering and resolution in libcnb.rs-based Rust packages. ([#575](https://github.com/heroku/libcnb.rs/pull/575)) -## [0.12.0] 2023-04-28 +## [0.12.0] - 2023-04-28 Highlight of this release is the bump to [Buildpack API 0.9](https://github.com/buildpacks/spec/releases/tag/buildpack%2Fv0.9). This release contains breaking changes, please refer to the items below for migration advice. @@ -92,26 +95,26 @@ Highlight of this release is the bump to [Buildpack API 0.9](https://github.com/ - `Env::get_string_lossy` as a convenience method to work with environment variables directly. Getting a value out of an `Env` and treating its contents as unicode is a common case. Using this new method can simplify buildpack code. ([#565](https://github.com/heroku/libcnb.rs/pull/565)) - `Clone` implementation for `libcnb::layer_env::Scope`. ([#566](https://github.com/heroku/libcnb.rs/pull/566)) -## [0.11.5] 2023-02-07 +## [0.11.5] - 2023-02-07 ### Changed - Update `toml` to `0.7.1`. If your buildpack interacts with TOML data directly, you probably want to bump the `toml` version in your buildpack as well. ([#556](https://github.com/heroku/libcnb.rs/pull/556)) -## [0.11.4] 2023-01-11 +## [0.11.4] - 2023-01-11 ### Added - libcnb-data: Store struct now supports `clone()` and `default()`. ([#547](https://github.com/heroku/libcnb.rs/pull/547)) -## [0.11.3] 2023-01-09 +## [0.11.3] - 2023-01-09 ### Added - libcnb: Add `store` field to `BuildContext`, exposing the contents of `store.toml` if present. ([#543](https://github.com/heroku/libcnb.rs/pull/543)) -## [0.11.2] 2022-12-15 +## [0.11.2] - 2022-12-15 ### Fixed @@ -126,7 +129,7 @@ the `toml` version in your buildpack as well. ([#556](https://github.com/heroku/ - libherokubuildpack: Add `command` and `write` modules for working with `std::process::Command` output streams. ([#535](https://github.com/heroku/libcnb.rs/pull/535)) -## [0.11.1] 2022-09-29 +## [0.11.1] - 2022-09-29 ### Fixed @@ -137,7 +140,7 @@ the `toml` version in your buildpack as well. ([#556](https://github.com/heroku/ - Improve the `libherokubuildpack` root module rustdocs. ([#503](https://github.com/heroku/libcnb.rs/pull/503)) -## [0.11.0] 2022-09-23 +## [0.11.0] - 2022-09-23 ### Changed @@ -148,7 +151,7 @@ the `toml` version in your buildpack as well. ([#556](https://github.com/heroku/ - Add new crate `libherokubuildpack` with common code that can be useful when implementing buildpacks with libcnb. Originally hosted in a separate, private, repository. Code from `libherokubuildpack` might eventually find its way into libcnb.rs proper. At this point, consider it an incubator. ([#495](https://github.com/heroku/libcnb.rs/pull/495)) -## [0.10.0] 2022-08-31 +## [0.10.0] - 2022-08-31 Highlight of this release is the bump to [Buildpack API 0.8](https://github.com/buildpacks/spec/releases/tag/buildpack%2Fv0.8) which brings support for SBOM to @@ -179,3 +182,14 @@ version number. See the changelog below for other changes. ### Removed - Remove support for legacy BOM. Remove `Launch::bom`, `Build::bom`, `bom::Bom`, `bom::Entry`. ([#489](https://github.com/heroku/libcnb.rs/pull/489)) + +[unreleased]: https://github.com/heroku/libcnb.rs/compare/v0.13.0...HEAD +[0.13.0]: https://github.com/heroku/libcnb.rs/compare/v0.12.0...v0.13.0 +[0.12.0]: https://github.com/heroku/libcnb.rs/compare/v0.11.5...v0.12.0 +[0.11.5]: https://github.com/heroku/libcnb.rs/compare/v0.11.4...v0.11.5 +[0.11.4]: https://github.com/heroku/libcnb.rs/compare/v0.11.3...v0.11.4 +[0.11.3]: https://github.com/heroku/libcnb.rs/compare/v0.11.2...v0.11.3 +[0.11.2]: https://github.com/heroku/libcnb.rs/compare/v0.11.1...v0.11.2 +[0.11.1]: https://github.com/heroku/libcnb.rs/compare/v0.11.0...v0.11.1 +[0.11.0]: https://github.com/heroku/libcnb.rs/compare/v0.10.0...v0.11.0 +[0.10.0]: https://github.com/heroku/libcnb.rs/compare/libcnb/v0.9.0...v0.10.0 diff --git a/RELEASING.md b/RELEASING.md index adf63a24..a8720475 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -12,6 +12,7 @@ easier to gauge cross-crate compatibility. 3. Update [CHANGELOG.md](./CHANGELOG.md) 1. Move all content under `## [Unreleased]` to a new section that follows this pattern: `## [VERSION] YYYY-MM-DD` 2. If appropriate, add a high-level summary of changes at the beginning of the new section + 3. Update the version compare links at the bottom of the file to both add the new version, and update the "unreleased" link's "from" version. 4. Install the latest version of [cargo-edit](https://github.com/killercup/cargo-edit): `cargo install cargo-edit` 5. Bump in-range dependency versions using: `cargo upgrade` 6. Commit the changes, push them and open a PR targeting `main` From cce17cf3e98730c25e056142692526bc561c5ef5 Mon Sep 17 00:00:00 2001 From: Ed Morley <501702+edmorley@users.noreply.github.com> Date: Fri, 18 Aug 2023 11:26:39 +0000 Subject: [PATCH 08/11] Rename libcnb-cargo integration test file (#645) For consistency with all of the other integration tests in this repo: ``` examples/execd/tests/integration_test.rs examples/ruby-sample/tests/integration_test.rs test-buildpacks/readonly-layer-files/tests/integration_test.rs test-buildpacks/sbom/tests/integration_test.rs test-buildpacks/store/tests/integration_test.rs libcnb-test/tests/integration_test.rs ``` And also with the naming that the Rust docs use: https://doc.rust-lang.org/book/ch11-03-test-organization.html#integration-tests --- libcnb-cargo/tests/{test.rs => integration_test.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename libcnb-cargo/tests/{test.rs => integration_test.rs} (100%) diff --git a/libcnb-cargo/tests/test.rs b/libcnb-cargo/tests/integration_test.rs similarity index 100% rename from libcnb-cargo/tests/test.rs rename to libcnb-cargo/tests/integration_test.rs From 2b935dbb59cf56be9370f84431ce6994f7c97e24 Mon Sep 17 00:00:00 2001 From: Ed Morley <501702+edmorley@users.noreply.github.com> Date: Fri, 18 Aug 2023 11:27:27 +0000 Subject: [PATCH 09/11] Pin intra-libcnb* crate dependencies to exact versions (#644) Cargo treats dependency version specifiers of form `X.Y.Z` the same as `^X.Y.Z`: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#caret-requirements As such, previously if an end user of libcnb tried pinning to say `libcnb` 0.14.0, then its previous dependency on `libcnb-data` `0.14.0` would mean any patch releases to `libcnb-data` (such as `0.14.1`) would be automatically picked up. This could be potentially confusing, especially since we only have one unified version number and changelog for libcnb now. For example: 1. A buildpack maintainer has an issue with a libcnb upgrade, so pins `libcnb` to `=0.14.0` in their CNB's `Cargo.toml`. 2. However, Cargo when refreshing their CNB's `Cargo.lock` now records the `libcnb-data` version as `0.14.1`, since it's in-range. 3. Now their CNB is using a combination of 0.14.0 and 0.14.1, which confuses the buildpack maintainer, since as far as they are concerned they are using libcnb 0.14.0, and so they don't expect the changes documented under the `0.14.1` section of libcnb's unified changelog to be taking effect. --- Cargo.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 30049870..ce25c0a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,9 +23,9 @@ edition = "2021" license = "BSD-3-Clause" [workspace.dependencies] -libcnb = { version = "0.13.0", path = "libcnb" } -libcnb-data = { version = "0.13.0", path = "libcnb-data" } -libcnb-package = { version = "0.13.0", path = "libcnb-package" } -libcnb-proc-macros = { version = "0.13.0", path = "libcnb-proc-macros" } -libcnb-test = { version = "0.13.0", path = "libcnb-test" } +libcnb = { version = "=0.13.0", path = "libcnb" } +libcnb-data = { version = "=0.13.0", path = "libcnb-data" } +libcnb-package = { version = "=0.13.0", path = "libcnb-package" } +libcnb-proc-macros = { version = "=0.13.0", path = "libcnb-proc-macros" } +libcnb-test = { version = "=0.13.0", path = "libcnb-test" } toml = { version = "0.7.5" } From b700ea09f569e66ae002c3e5ae598b2dedaf0ba6 Mon Sep 17 00:00:00 2001 From: Ed Morley <501702+edmorley@users.noreply.github.com> Date: Fri, 18 Aug 2023 15:06:08 +0000 Subject: [PATCH 10/11] Prepare release v0.14.0 (#646) Changes: https://github.com/heroku/libcnb.rs/compare/v0.13.0...HEAD GUS-W-13973992. --- CHANGELOG.md | 25 ++++++++++++++----------- Cargo.toml | 14 +++++++------- RELEASING.md | 2 +- examples/ruby-sample/Cargo.toml | 8 ++++---- libcnb-cargo/Cargo.toml | 6 +++--- libcnb-data/Cargo.toml | 6 +++--- libcnb-proc-macros/Cargo.toml | 4 ++-- libcnb-test/Cargo.toml | 4 ++-- libcnb/Cargo.toml | 8 ++++---- libherokubuildpack/Cargo.toml | 8 ++++---- 10 files changed, 44 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 347e4d60..d2529c9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,29 +9,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] + +## [0.14.0] - 2023-08-18 + ### Added -- `libcnb-package`: Add cross-compilation assistance for Linux `aarch64-unknown-linux-musl`. ([#577](https://github.com/heroku/libcnb.rs/pull/577)) -- `libcnb-cargo`: Add `--package-dir` command line option to control where packaged buildpacks are written to. ([#583](https://github.com/heroku/libcnb.rs/pull/583)) +- `libcnb-package`: Added cross-compilation assistance for Linux `aarch64-unknown-linux-musl`. ([#577](https://github.com/heroku/libcnb.rs/pull/577)) +- `libcnb-cargo`: Added `--package-dir` command line option to control where packaged buildpacks are written. ([#583](https://github.com/heroku/libcnb.rs/pull/583)) - `libcnb-test`: - `LogOutput` now implements `std::fmt::Display`. ([#635](https://github.com/heroku/libcnb.rs/pull/635)) - `ContainerConfig` now implements `Clone`. ([#636](https://github.com/heroku/libcnb.rs/pull/636)) ### Changed +- `libcnb-cargo`: Moved the default location for packaged buildpacks from Cargo's `target/` directory to `packaged/` in the Cargo workspace root. This simplifies the path and stops modification of the `target/` directory which previously might have caching implications when other tools didn't expect non-Cargo output in that directory. Users that implicitly rely on the output directory need to adapt. The output of `cargo libcnb package` will refer to the new locations. ([#583](https://github.com/heroku/libcnb.rs/pull/583)) +- `libcnb-package`: + - buildpack target directory now contains the target triple. Users that implicitly rely on the output directory need to adapt. The output of `cargo libcnb package` will refer to the new locations. ([#580](https://github.com/heroku/libcnb.rs/pull/580)) + - `get_buildpack_target_dir` was renamed to `get_buildpack_package_dir` ([#583](https://github.com/heroku/libcnb.rs/pull/583)) - `libcnb-test`: - `ContainerContext::address_for_port` will now panic for all failure modes rather than just some, and so now returns `SocketAddr` directly instead of `Option`. This reduces test boilerplate due to the caller no longer needing to `.unwrap()` and improves debugging UX when containers crash after startup. ([#605](https://github.com/heroku/libcnb.rs/pull/605) and [#636](https://github.com/heroku/libcnb.rs/pull/636)) - Docker commands are now run using the Docker CLI instead of Bollard and the Docker daemon API. ([#620](https://github.com/heroku/libcnb.rs/pull/620)) - `ContainerConfig::entrypoint` now accepts a String rather than a vector of strings. Any arguments to the entrypoint should be moved to `ContainerConfig::command`. ([#620](https://github.com/heroku/libcnb.rs/pull/620)) - - `TestRunner::new` has been removed, since its only purpose was for advanced configuration that's no longer applicable. Use `TestRunner::default` instead. ([#620](https://github.com/heroku/libcnb.rs/pull/620)) - - `LogOutput` no longer exposes `stdout_raw` and `stderr_raw`. ([#607](https://github.com/heroku/libcnb.rs/pull/607)) + - Removed `TestRunner::new` since its only purpose was for advanced configuration that's no longer applicable. Use `TestRunner::default` instead. ([#620](https://github.com/heroku/libcnb.rs/pull/620)) + - Removed `stdout_raw` and `stderr_raw` from `LogOutput`. ([#607](https://github.com/heroku/libcnb.rs/pull/607)) - Improved wording of panic error messages. ([#619](https://github.com/heroku/libcnb.rs/pull/619) and [#620](https://github.com/heroku/libcnb.rs/pull/620)) -- `libcnb-package`: - - buildpack target directory now contains the target triple. Users that implicitly rely on the output directory need to adapt. The output of `cargo libcnb package` will refer to the new locations. ([#580](https://github.com/heroku/libcnb.rs/pull/580)) - - `get_buildpack_target_dir` was renamed to `get_buildpack_package_dir` ([#583](https://github.com/heroku/libcnb.rs/pull/583)) -- `libherokubuildpack`: Switch the `flate2` decompression backend from `miniz_oxide` to `zlib`. ([#593](https://github.com/heroku/libcnb.rs/pull/593)) -- Bump minimum external dependency versions. ([#587](https://github.com/heroku/libcnb.rs/pull/587)) -- `libcnb-cargo`: Default location for packaged buildpacks moved from Cargo's `target` directory to `packaged` in the Cargo workspace root. This simplifies the path and stops modification of the `target` directory which previously might have caching implications when other tools didn't expect non-Cargo output in that directory. Users that implicitly rely on the output directory need to adapt. The output of `cargo libcnb package` will refer to the new locations. ([#583](https://github.com/heroku/libcnb.rs/pull/583)) +- `libherokubuildpack`: Changed the `flate2` decompression backend from `miniz_oxide` to `zlib`. ([#593](https://github.com/heroku/libcnb.rs/pull/593)) ### Fixed @@ -183,7 +185,8 @@ version number. See the changelog below for other changes. - Remove support for legacy BOM. Remove `Launch::bom`, `Build::bom`, `bom::Bom`, `bom::Entry`. ([#489](https://github.com/heroku/libcnb.rs/pull/489)) -[unreleased]: https://github.com/heroku/libcnb.rs/compare/v0.13.0...HEAD +[unreleased]: https://github.com/heroku/libcnb.rs/compare/v0.14.0...HEAD +[0.14.0]: https://github.com/heroku/libcnb.rs/compare/v0.13.0...v0.14.0 [0.13.0]: https://github.com/heroku/libcnb.rs/compare/v0.12.0...v0.13.0 [0.12.0]: https://github.com/heroku/libcnb.rs/compare/v0.11.5...v0.12.0 [0.11.5]: https://github.com/heroku/libcnb.rs/compare/v0.11.4...v0.11.5 diff --git a/Cargo.toml b/Cargo.toml index ce25c0a0..d168c765 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,15 +17,15 @@ members = [ ] [workspace.package] -version = "0.13.0" +version = "0.14.0" rust-version = "1.64" edition = "2021" license = "BSD-3-Clause" [workspace.dependencies] -libcnb = { version = "=0.13.0", path = "libcnb" } -libcnb-data = { version = "=0.13.0", path = "libcnb-data" } -libcnb-package = { version = "=0.13.0", path = "libcnb-package" } -libcnb-proc-macros = { version = "=0.13.0", path = "libcnb-proc-macros" } -libcnb-test = { version = "=0.13.0", path = "libcnb-test" } -toml = { version = "0.7.5" } +libcnb = { version = "=0.14.0", path = "libcnb" } +libcnb-data = { version = "=0.14.0", path = "libcnb-data" } +libcnb-package = { version = "=0.14.0", path = "libcnb-package" } +libcnb-proc-macros = { version = "=0.14.0", path = "libcnb-proc-macros" } +libcnb-test = { version = "=0.14.0", path = "libcnb-test" } +toml = { version = "0.7.6" } diff --git a/RELEASING.md b/RELEASING.md index a8720475..3397e8b0 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -10,7 +10,7 @@ easier to gauge cross-crate compatibility. 1. In the `workspace.package` table, update `version` to the new version 2. In the `workspace.dependencies` table, update the `version` of each of the repository-local dependencies to the new version 3. Update [CHANGELOG.md](./CHANGELOG.md) - 1. Move all content under `## [Unreleased]` to a new section that follows this pattern: `## [VERSION] YYYY-MM-DD` + 1. Move all content under `## [Unreleased]` to a new section that follows this pattern: `## [VERSION] - YYYY-MM-DD` 2. If appropriate, add a high-level summary of changes at the beginning of the new section 3. Update the version compare links at the bottom of the file to both add the new version, and update the "unreleased" link's "from" version. 4. Install the latest version of [cargo-edit](https://github.com/killercup/cargo-edit): `cargo install cargo-edit` diff --git a/examples/ruby-sample/Cargo.toml b/examples/ruby-sample/Cargo.toml index d8cfbf72..3e90030b 100644 --- a/examples/ruby-sample/Cargo.toml +++ b/examples/ruby-sample/Cargo.toml @@ -6,12 +6,12 @@ rust-version.workspace = true publish = false [dependencies] -flate2 = { version = "1.0.26", default-features = false, features = ["zlib"] } +flate2 = { version = "1.0.27", default-features = false, features = ["zlib"] } libcnb.workspace = true -serde = "1.0.166" +serde = "1.0.183" sha2 = "0.10.7" -tar = { version = "0.4.38", default-features = false } -tempfile = "3.6.0" +tar = { version = "0.4.40", default-features = false } +tempfile = "3.7.1" ureq = { version = "2.7.1", default-features = false, features = ["tls"] } [dev-dependencies] diff --git a/libcnb-cargo/Cargo.toml b/libcnb-cargo/Cargo.toml index d5eefe23..8132b222 100644 --- a/libcnb-cargo/Cargo.toml +++ b/libcnb-cargo/Cargo.toml @@ -17,7 +17,7 @@ path = "src/main.rs" [dependencies] cargo_metadata = "0.17.0" -clap = { version = "4.3.10", default-features = false, features = [ +clap = { version = "4.3.22", default-features = false, features = [ "derive", "error-context", "help", @@ -27,8 +27,8 @@ clap = { version = "4.3.10", default-features = false, features = [ libcnb-data.workspace = true libcnb-package.workspace = true pathdiff = "0.2.1" -thiserror = "1.0.41" +thiserror = "1.0.47" toml.workspace = true [dev-dependencies] -tempfile = "3.6.0" +tempfile = "3.7.1" diff --git a/libcnb-data/Cargo.toml b/libcnb-data/Cargo.toml index f7c9d081..28659dac 100644 --- a/libcnb-data/Cargo.toml +++ b/libcnb-data/Cargo.toml @@ -14,10 +14,10 @@ include = ["src/**/*", "LICENSE", "README.md"] [dependencies] fancy-regex = { version = "0.11.0", default-features = false } libcnb-proc-macros.workspace = true -serde = { version = "1.0.166", features = ["derive"] } -thiserror = "1.0.41" +serde = { version = "1.0.183", features = ["derive"] } +thiserror = "1.0.47" toml.workspace = true uriparse = "0.6.4" [dev-dependencies] -serde_test = "1.0.166" +serde_test = "1.0.176" diff --git a/libcnb-proc-macros/Cargo.toml b/libcnb-proc-macros/Cargo.toml index 9713fcce..a9bdec3f 100644 --- a/libcnb-proc-macros/Cargo.toml +++ b/libcnb-proc-macros/Cargo.toml @@ -16,5 +16,5 @@ proc-macro = true [dependencies] cargo_metadata = "0.17.0" fancy-regex = { version = "0.11.0", default-features = false } -quote = "1.0.29" -syn = { version = "2.0.23", features = ["full"] } +quote = "1.0.33" +syn = { version = "2.0.29", features = ["full"] } diff --git a/libcnb-test/Cargo.toml b/libcnb-test/Cargo.toml index 58e6208c..9c67538c 100644 --- a/libcnb-test/Cargo.toml +++ b/libcnb-test/Cargo.toml @@ -17,8 +17,8 @@ fastrand = "2.0.0" fs_extra = "1.3.0" libcnb-data.workspace = true libcnb-package.workspace = true -tempfile = "3.6.0" +tempfile = "3.7.1" [dev-dependencies] -indoc = "2.0.2" +indoc = "2.0.3" ureq = { version = "2.7.1", default-features = false } diff --git a/libcnb/Cargo.toml b/libcnb/Cargo.toml index d4f48fa5..0ffdd3cb 100644 --- a/libcnb/Cargo.toml +++ b/libcnb/Cargo.toml @@ -12,14 +12,14 @@ readme = "README.md" include = ["src/**/*", "LICENSE", "README.md"] [dependencies] -anyhow = { version = "1.0.71", optional = true } +anyhow = { version = "1.0.75", optional = true } cyclonedx-bom = { version = "0.4.0", optional = true } libcnb-data.workspace = true libcnb-proc-macros.workspace = true -serde = { version = "1.0.166", features = ["derive"] } -thiserror = "1.0.41" +serde = { version = "1.0.183", features = ["derive"] } +thiserror = "1.0.47" toml.workspace = true [dev-dependencies] fastrand = "2.0.0" -tempfile = "3.6.0" +tempfile = "3.7.1" diff --git a/libherokubuildpack/Cargo.toml b/libherokubuildpack/Cargo.toml index c4af51b3..fd88c947 100644 --- a/libherokubuildpack/Cargo.toml +++ b/libherokubuildpack/Cargo.toml @@ -33,15 +33,15 @@ crossbeam-utils = { version = "0.8.16", optional = true } # Ideally we'd use the fastest `zlib-ng` backend, however it fails to cross-compile: # https://github.com/rust-lang/libz-sys/issues/93 # As such we have to use the next best alternate backend, which is `zlib`. -flate2 = { version = "1.0.26", default-features = false, features = ["zlib"], optional = true } +flate2 = { version = "1.0.27", default-features = false, features = ["zlib"], optional = true } libcnb = { workspace = true, optional = true } pathdiff = { version = "0.2.1", optional = true } sha2 = { version = "0.10.7", optional = true } -tar = { version = "0.4.38", default-features = false, optional = true } +tar = { version = "0.4.40", default-features = false, optional = true } termcolor = { version = "1.2.0", optional = true } -thiserror = { version = "1.0.41", optional = true } +thiserror = { version = "1.0.47", optional = true } toml = { workspace = true, optional = true } ureq = { version = "2.7.1", default-features = false, features = ["tls"], optional = true } [dev-dependencies] -tempfile = "3.6.0" +tempfile = "3.7.1" From 7fb80a8db5f4e1fca2928eaa0bbca92de013b468 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Aug 2023 17:11:03 +0000 Subject: [PATCH 11/11] Bump buildpacks/github-actions from 5.3.1 to 5.4.0 (#647) Bumps [buildpacks/github-actions](https://github.com/buildpacks/github-actions) from 5.3.1 to 5.4.0. - [Release notes](https://github.com/buildpacks/github-actions/releases) - [Commits](https://github.com/buildpacks/github-actions/compare/v5.3.1...v5.4.0) --- updated-dependencies: - dependency-name: buildpacks/github-actions dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0093d899..103dd0af 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -62,7 +62,7 @@ jobs: - name: Rust Cache uses: Swatinem/rust-cache@v2.6.0 - name: Install Pack CLI - uses: buildpacks/github-actions/setup-pack@v5.3.1 + uses: buildpacks/github-actions/setup-pack@v5.4.0 - name: Run integration tests # Runs only tests annotated with the `ignore` attribute (which in this repo, are the integration tests). run: cargo test -- --ignored