Skip to content

Commit 67033e1

Browse files
committed
fix(cli): mount the config from an absolute --config path correctly
1 parent dd7302b commit 67033e1

3 files changed

Lines changed: 36 additions & 6 deletions

File tree

‎.github/workflows/release.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ jobs:
301301
pattern: "commit-boost-*"
302302

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

‎bin/tests/binary.rs‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,16 @@ fn test_init_compose_file_pbs_service_structure() {
130130
assert_eq!(pbs["image"].as_str(), Some("ghcr.io/commit-boost/commit-boost:latest"), "image");
131131
assert_eq!(pbs["container_name"].as_str(), Some("cb_pbs"), "container_name");
132132

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

140145
// Required environment variables must be present.

‎crates/cli/src/docker_init.rs‎

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,19 @@ use docker_compose_types::{
3131
use eyre::Result;
3232
use indexmap::IndexMap;
3333

34+
/// A host path as a compose bind-mount source. Compose reads a source with no
35+
/// `/` or `./` prefix as a NAMED VOLUME, so a relative path needs the prefix;
36+
/// an absolute one must be passed through, or it is resolved against the
37+
/// project directory and docker creates a root-owned directory there.
38+
fn compose_bind_source(path: &Path) -> String {
39+
let source = path.display().to_string();
40+
if path.is_absolute() || source.starts_with("./") || source.starts_with("../") {
41+
source
42+
} else {
43+
format!("./{source}")
44+
}
45+
}
46+
3447
/// Name of the docker compose file
3548
pub const CB_COMPOSE_FILE: &str = "cb.docker-compose.yml";
3649
/// Name of the envs file
@@ -91,8 +104,8 @@ pub async fn handle_docker_init(config_path: PathBuf, output_dir: PathBuf) -> Re
91104
let mut service_config = ServiceCreationInfo {
92105
config_info: CommitBoostConfigInfo {
93106
config_volume: Volumes::Simple(format!(
94-
"./{}:{}:ro",
95-
config_path.display(),
107+
"{}:{}:ro",
108+
compose_bind_source(&config_path),
96109
CONFIG_DEFAULT
97110
)),
98111
cb_config: CommitBoostConfig::from_file(&config_path)?,
@@ -954,6 +967,18 @@ mod tests {
954967

955968
// --- get_env_val ---
956969

970+
/// Compose reads a bare source as a named volume, so a relative path keeps
971+
/// the `./` prefix; an absolute one must NOT get it, or compose resolves
972+
/// `.//abs/path` against the project directory and docker creates a
973+
/// root-owned directory there instead of mounting the file.
974+
#[test]
975+
fn test_compose_bind_source_prefixes_only_relative_paths() {
976+
assert_eq!(compose_bind_source(Path::new("cb-config.toml")), "./cb-config.toml");
977+
assert_eq!(compose_bind_source(Path::new("./cb-config.toml")), "./cb-config.toml");
978+
assert_eq!(compose_bind_source(Path::new("../cb-config.toml")), "../cb-config.toml");
979+
assert_eq!(compose_bind_source(Path::new("/etc/cb/config.toml")), "/etc/cb/config.toml");
980+
}
981+
957982
#[test]
958983
fn test_get_env_val_returns_string_pair() {
959984
let (key, val) = get_env_val("MY_KEY", "my_value");

0 commit comments

Comments
 (0)