Skip to content

Commit 1911557

Browse files
committed
fix(k8s): always copy GitHub workspace directories regardless of userMountVolumes
**Problem:** The prepare script that copies GitHub workspace directories (/_github_workflow, /_github_home) from /__w/_temp/ to /github/ was only created and executed when userMountVolumes were defined. This caused failures when actions tried to access $GITHUB_EVENT_PATH=/github/workflow/event.json in environments without user mounts. **Root Cause:** The conditional logic at line 102 tied the creation of the prepare script to the presence of userMountVolumes: ```typescript if (args.container?.userMountVolumes?.length) { prepareScript = prepareJobScript(args.container.userMountVolumes || []) } ``` However, the prepare script ALWAYS needs to run to copy GitHub directories - these are required for GitHub Actions to function correctly. The user mounts are optional. **Impact:** This bug affected: - Kubernetes mode runners without user-defined mount volumes - Kubernetes-novolume mode in all configurations - Actions that access workflow metadata (e.g., Docker Buildx reading event.json) **Solution:** - Remove the conditional logic - always create and execute the prepare script - The prepareJobScript function already handles empty userMountVolumes gracefully - Separate the concerns: GitHub directory copying (required) vs user mount setup (optional) **Testing:** This fix has been validated in production with deskrun's cached-privileged-kubernetes runners, where actions like Docker Buildx can now successfully access event.json. Fixes #299 Related: rkoster/deskrun#28, rkoster/rubionic-workspace#226
1 parent 5f5708a commit 1911557

File tree

1 file changed

+19
-20
lines changed

1 file changed

+19
-20
lines changed

packages/k8s/src/hooks/prepare-job.ts

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,9 @@ export async function prepareJob(
9898

9999
const runnerWorkspace = dirname(process.env.RUNNER_WORKSPACE as string)
100100

101-
let prepareScript: { containerPath: string; runnerPath: string } | undefined
102-
if (args.container?.userMountVolumes?.length) {
103-
prepareScript = prepareJobScript(args.container.userMountVolumes || [])
104-
}
101+
// Always create prepare script to copy GitHub workspace directories
102+
// The script handles both required GitHub directories and optional user mounts
103+
const prepareScript = prepareJobScript(args.container?.userMountVolumes || [])
105104

106105
try {
107106
await waitForPodPhases(
@@ -117,25 +116,25 @@ export async function prepareJob(
117116

118117
await execCpToPod(createdPod.metadata.name, runnerWorkspace, '/__w')
119118

120-
if (prepareScript) {
121-
await execPodStep(
122-
['sh', '-e', prepareScript.containerPath],
123-
createdPod.metadata.name,
124-
JOB_CONTAINER_NAME
125-
)
119+
// Always execute prepare script to ensure GitHub workspace directories are copied
120+
await execPodStep(
121+
['sh', '-e', prepareScript.containerPath],
122+
createdPod.metadata.name,
123+
JOB_CONTAINER_NAME
124+
)
126125

127-
const promises: Promise<void>[] = []
128-
for (const vol of args?.container?.userMountVolumes || []) {
129-
promises.push(
130-
execCpToPod(
131-
createdPod.metadata.name,
132-
vol.sourceVolumePath,
133-
vol.targetVolumePath
134-
)
126+
// Copy user mount volumes if any are defined
127+
const promises: Promise<void>[] = []
128+
for (const vol of args?.container?.userMountVolumes || []) {
129+
promises.push(
130+
execCpToPod(
131+
createdPod.metadata.name,
132+
vol.sourceVolumePath,
133+
vol.targetVolumePath
135134
)
136-
}
137-
await Promise.all(promises)
135+
)
138136
}
137+
await Promise.all(promises)
139138

140139
core.debug('Job pod is ready for traffic')
141140

0 commit comments

Comments
 (0)