Skip to content

Commit eb1bcef

Browse files
authored
Merge pull request #294 from buildkite-plugins/SUP-1304/Fixing-Windows-paths
Fix Windows path handling for Docker volume mounts
2 parents a24e630 + b27e354 commit eb1bcef

3 files changed

Lines changed: 79 additions & 13 deletions

File tree

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,9 @@ Default: `busybox`
367367

368368
Whether to automatically mount the `buildkite-agent` binary from the host agent machine into the container.
369369

370-
Set to `true` if you want to enable and are sure that the binary running in the agent is compatible with the container's architecture and environment (for example, don't try to mount the OS X or Windows agent binary in a container running linux). If enabled in Windows agents your pipeline, step or agent **must have the `BUILDKITE_AGENT_BINARY_PATH` environment variable defined** with the executable to mount in the (Windows) agent.
370+
Set to `true` if you want to enable and are sure that the binary running in the agent is compatible with the container's architecture and environment (for example, don't try to mount the OS X or Windows agent binary in a container running linux).
371+
372+
**Important:** When using Windows agents, you must define the `BUILDKITE_AGENT_BINARY_PATH` environment variable with the full path to the agent executable (for example, `C:\buildkite-agent.exe`).
371373

372374
Default: `false`
373375

commands/run.sh

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,11 @@ agent_mount_folder="/usr/bin/buildkite-agent"
1919
if is_windows ; then
2020
tty_default=''
2121
init_default=''
22-
workdir_default="C:\\workdir"
23-
# escaping /C is a necessary workaround for an issue with Git for Windows 2.24.1.2
24-
# https://github.com/git-for-windows/git/issues/2442
22+
workdir_default="C:/workdir"
2523
pwd_default="$(cmd.exe //C "echo %CD%")"
2624

27-
# single quotes are important to avoid double-escaping the already escaped backslash
28-
agent_mount_folder='C:\\buildkite-agent'
25+
# Use Windows-style path for Windows containers (backslashes work in Windows containers)
26+
agent_mount_folder='C:\buildkite-agent'
2927
fi
3028

3129

@@ -71,7 +69,13 @@ fi
7169

7270
# By default, mount $PWD onto $WORKDIR
7371
if [[ "${BUILDKITE_PLUGIN_DOCKER_MOUNT_CHECKOUT:-on}" =~ ^(true|on|1)$ ]] ; then
74-
args+=( "--volume" "${pwd_default}:${workdir}" )
72+
if is_windows; then
73+
# Normalize Windows source path for Docker volume syntax, keep destination as Windows path
74+
normalized_pwd="${pwd_default//\\//}"
75+
args+=( "--volume" "${normalized_pwd}:${workdir}" )
76+
else
77+
args+=( "--volume" "${pwd_default}:${workdir}" )
78+
fi
7579
fi
7680

7781
# Parse volumes (and deprecated mounts) and add them to the docker args
@@ -215,12 +219,30 @@ fi
215219

216220
# Mount buildkite-agent if we have a path for it
217221
if [[ -n "${BUILDKITE_AGENT_BINARY_PATH:-}" ]] ; then
218-
args+=(
219-
"--env" "BUILDKITE_JOB_ID"
220-
"--env" "BUILDKITE_BUILD_ID"
221-
"--env" "BUILDKITE_AGENT_ACCESS_TOKEN"
222-
"--volume" "$BUILDKITE_AGENT_BINARY_PATH:${agent_mount_folder}"
223-
)
222+
# Normalize paths for Windows to avoid Docker volume specification errors
223+
if is_windows; then
224+
# Convert backslashes to forward slashes for Docker volume syntax (source side only as Docker will accept C:/)
225+
# Handle both single and double backslashes properly
226+
# Replace double backslashes first
227+
normalized_source_path="${BUILDKITE_AGENT_BINARY_PATH//\\\\//}"
228+
# Then replace remaining single backslashes
229+
normalized_source_path="${normalized_source_path//\\//}"
230+
# Keep destination path as-is for Windows containers to preserve compatibility with Windows
231+
232+
args+=(
233+
"--env" "BUILDKITE_JOB_ID"
234+
"--env" "BUILDKITE_BUILD_ID"
235+
"--env" "BUILDKITE_AGENT_ACCESS_TOKEN"
236+
"--volume" "${normalized_source_path}:${agent_mount_folder}"
237+
)
238+
else
239+
args+=(
240+
"--env" "BUILDKITE_JOB_ID"
241+
"--env" "BUILDKITE_BUILD_ID"
242+
"--env" "BUILDKITE_AGENT_ACCESS_TOKEN"
243+
"--volume" "$BUILDKITE_AGENT_BINARY_PATH:${agent_mount_folder}"
244+
)
245+
fi
224246
fi
225247

226248
if [[ -n "${BUILDKITE_AGENT_JOB_API_SOCKET:-}" ]] ; then

tests/windows.bats

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,45 @@ setup() {
3131
unstub docker
3232
unstub cmd.exe
3333
}
34+
35+
@test "Run with backslash Windows agent path" {
36+
export OSTYPE="win"
37+
export BUILDKITE_PLUGIN_DOCKER_MOUNT_BUILDKITE_AGENT=true
38+
export BUILDKITE_COMMAND="pwd"
39+
export BUILDKITE_AGENT_BINARY_PATH="C:\\buildkite-agent.exe"
40+
41+
stub cmd.exe \
42+
"//C $'echo %CD%' : echo WIN_PATH"
43+
44+
stub docker \
45+
"run -i --rm --volume WIN_PATH:C:/workdir --workdir C:/workdir --env BUILDKITE_JOB_ID --env BUILDKITE_BUILD_ID --env BUILDKITE_AGENT_ACCESS_TOKEN --volume C:/buildkite-agent.exe:C:\\\\buildkite-agent --label com.buildkite.job-id=1-2-3-4 image:tag CMD.EXE /c 'pwd' : echo ran command in docker"
46+
47+
run "$PWD"/hooks/command
48+
49+
assert_success
50+
assert_output --partial "ran command in docker"
51+
52+
unstub docker
53+
unstub cmd.exe
54+
}
55+
56+
@test "Run with double backslash Windows agent path" {
57+
export OSTYPE="win"
58+
export BUILDKITE_PLUGIN_DOCKER_MOUNT_BUILDKITE_AGENT=true
59+
export BUILDKITE_COMMAND="pwd"
60+
export BUILDKITE_AGENT_BINARY_PATH="C:\\\\buildkite-agent.exe"
61+
62+
stub cmd.exe \
63+
"//C $'echo %CD%' : echo WIN_PATH"
64+
65+
stub docker \
66+
"run -i --rm --volume WIN_PATH:C:/workdir --workdir C:/workdir --env BUILDKITE_JOB_ID --env BUILDKITE_BUILD_ID --env BUILDKITE_AGENT_ACCESS_TOKEN --volume C:/buildkite-agent.exe:C:\\\\buildkite-agent --label com.buildkite.job-id=1-2-3-4 image:tag CMD.EXE /c 'pwd' : echo ran command in docker"
67+
68+
run "$PWD"/hooks/command
69+
70+
assert_success
71+
assert_output --partial "ran command in docker"
72+
73+
unstub docker
74+
unstub cmd.exe
75+
}

0 commit comments

Comments
 (0)