Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ jobs:
pattern: "commit-boost-*"

- name: Sign all binaries with Sigstore
uses: sigstore/gh-action-sigstore-python@v3.0.0
uses: sigstore/gh-action-sigstore-python@v3.5.0
with:
inputs: ./artifacts/**/*.tar.gz

Expand Down
11 changes: 8 additions & 3 deletions bin/tests/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,16 @@ fn test_init_compose_file_pbs_service_structure() {
assert_eq!(pbs["image"].as_str(), Some("ghcr.io/commit-boost/commit-boost:latest"), "image");
assert_eq!(pbs["container_name"].as_str(), Some("cb_pbs"), "container_name");

// Config file must be mounted inside the container.
// Config file must be mounted inside the container, from the path it was
// read from. `--config` here is ABSOLUTE, so the source must be that path
// verbatim: a `./` prefix would make compose resolve it against the project
// directory and docker would create a directory there instead.
let volumes = pbs["volumes"].as_sequence().expect("volumes is a list");
let expected_mount = format!("{}:/cb-config.toml:ro", config.display());
assert!(
volumes.iter().any(|v| v.as_str().map_or(false, |s| s.ends_with(":/cb-config.toml:ro"))),
"config must be mounted at /cb-config.toml"
volumes.iter().any(|v| v.as_str() == Some(expected_mount.as_str())),
"config must be mounted at /cb-config.toml from {}, got {volumes:?}",
config.display()
);

// Required environment variables must be present.
Expand Down
29 changes: 27 additions & 2 deletions crates/cli/src/docker_init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,19 @@ use docker_compose_types::{
use eyre::Result;
use indexmap::IndexMap;

/// A host path as a compose bind-mount source. Compose reads a source with no
/// `/` or `./` prefix as a NAMED VOLUME, so a relative path needs the prefix;
/// an absolute one must be passed through, or it is resolved against the
/// project directory and docker creates a root-owned directory there.
fn compose_bind_source(path: &Path) -> String {
let source = path.display().to_string();
if path.is_absolute() || source.starts_with("./") || source.starts_with("../") {
source
} else {
format!("./{source}")
}
}

/// Name of the docker compose file
pub const CB_COMPOSE_FILE: &str = "cb.docker-compose.yml";
/// Name of the envs file
Expand Down Expand Up @@ -91,8 +104,8 @@ pub async fn handle_docker_init(config_path: PathBuf, output_dir: PathBuf) -> Re
let mut service_config = ServiceCreationInfo {
config_info: CommitBoostConfigInfo {
config_volume: Volumes::Simple(format!(
"./{}:{}:ro",
config_path.display(),
"{}:{}:ro",
compose_bind_source(&config_path),
CONFIG_DEFAULT
)),
cb_config: CommitBoostConfig::from_file(&config_path)?,
Expand Down Expand Up @@ -954,6 +967,18 @@ mod tests {

// --- get_env_val ---

/// Compose reads a bare source as a named volume, so a relative path keeps
/// the `./` prefix; an absolute one must NOT get it, or compose resolves
/// `.//abs/path` against the project directory and docker creates a
/// root-owned directory there instead of mounting the file.
#[test]
fn test_compose_bind_source_prefixes_only_relative_paths() {
assert_eq!(compose_bind_source(Path::new("cb-config.toml")), "./cb-config.toml");
assert_eq!(compose_bind_source(Path::new("./cb-config.toml")), "./cb-config.toml");
assert_eq!(compose_bind_source(Path::new("../cb-config.toml")), "../cb-config.toml");
assert_eq!(compose_bind_source(Path::new("/etc/cb/config.toml")), "/etc/cb/config.toml");
}

#[test]
fn test_get_env_val_returns_string_pair() {
let (key, val) = get_env_val("MY_KEY", "my_value");
Expand Down