ix(executor): correct image selection and workspace mapping for run steps

Previously, `run` steps in Docker jobs were failing due to several issues:
- They were hardcoded to use `ubuntu:latest`, which often lacked necessary tools like `cargo`.
- Even when the image was correct, the host workspace directory was not properly mapped into the container, preventing access to source files.

This commit addresses these issues by:
- Using the correct runner image specified by the job's `runs_on` field for `run` steps, instead of always defaulting to `ubuntu:latest`.
- Updating the `get_runner_image` function to map `macos-latest` runners to `rust:latest` to ensure the Rust toolchain is available for relevant workflows.
- Correctly mapping the host working directory to `/github/workspace` within the container for `run` steps.
- Setting the container's working directory to `/github/workspace` when executing `run` steps.

This allows commands like `cargo build` and `cargo test` within `run` steps to find both the necessary tools and the project source code inside the container.
This commit is contained in:
bahdotsh
2025-04-30 16:51:38 +05:30
parent e978d09a7d
commit 34e1fc513e
2 changed files with 32 additions and 24 deletions

View File

@@ -586,7 +586,7 @@ impl ContainerRuntime for DockerRuntime {
logging::info(&format!("Docker: Running container with image: {}", image));
// Add a global timeout for all Docker operations to prevent freezing
let timeout_duration = std::time::Duration::from_secs(60); // 1 minute timeout
let timeout_duration = std::time::Duration::from_secs(360); // Increased outer timeout to 6 minutes
// Run the entire container operation with a timeout
match tokio::time::timeout(
@@ -597,7 +597,7 @@ impl ContainerRuntime for DockerRuntime {
{
Ok(result) => result,
Err(_) => {
logging::error("Docker operation timed out after 60 seconds");
logging::error("Docker operation timed out after 360 seconds");
Err(ContainerError::ContainerExecution(
"Operation timed out".to_string(),
))
@@ -926,9 +926,9 @@ impl DockerRuntime {
}
}
// Wait for container to finish with a timeout (30 seconds)
// Wait for container to finish with a timeout (300 seconds)
let wait_result = tokio::time::timeout(
std::time::Duration::from_secs(30),
std::time::Duration::from_secs(300),
self.docker
.wait_container::<String>(&container.id, None)
.collect::<Vec<_>>(),

View File

@@ -607,7 +607,7 @@ async fn execute_job(ctx: JobExecutionContext<'_>) -> Result<JobResult, Executio
working_dir: job_dir.path(),
runtime: ctx.runtime,
workflow: ctx.workflow,
job_runs_on: &job.runs_on,
runner_image: &runner_image,
verbose: ctx.verbose,
matrix_combination: &None,
})
@@ -845,7 +845,7 @@ async fn execute_matrix_job(
working_dir: job_dir.path(),
runtime,
workflow,
job_runs_on: &job_template.runs_on,
runner_image: &runner_image,
verbose,
matrix_combination: &Some(combination.values.clone()),
})
@@ -913,7 +913,7 @@ struct StepExecutionContext<'a> {
working_dir: &'a Path,
runtime: &'a dyn ContainerRuntime,
workflow: &'a WorkflowDefinition,
job_runs_on: &'a str,
runner_image: &'a str,
verbose: bool,
#[allow(dead_code)]
matrix_combination: &'a Option<HashMap<String, Value>>,
@@ -1016,7 +1016,7 @@ async fn execute_step(ctx: StepExecutionContext<'_>) -> Result<StepResult, Execu
&step_env,
ctx.working_dir,
ctx.runtime,
ctx.job_runs_on,
ctx.runner_image,
ctx.verbose,
)
.await?
@@ -1331,17 +1331,19 @@ async fn execute_step(ctx: StepExecutionContext<'_>) -> Result<StepResult, Execu
.map(|(k, v)| (k.as_str(), v.as_str()))
.collect();
// Map volumes
let volumes: Vec<(&Path, &Path)> =
vec![(ctx.working_dir, Path::new("/github/workspace"))];
// Define the standard workspace path inside the container
let container_workspace = Path::new("/github/workspace");
// Set up volume mapping from host working dir to container workspace
let volumes: Vec<(&Path, &Path)> = vec![(ctx.working_dir, container_workspace)];
let output = ctx
.runtime
.run_container(
&image,
ctx.runner_image,
&cmd.to_vec(),
&env_vars,
Path::new("/github/workspace"),
container_workspace,
&volumes,
)
.await
@@ -1455,15 +1457,21 @@ async fn execute_step(ctx: StepExecutionContext<'_>) -> Result<StepResult, Execu
.map(|(k, v)| (k.as_str(), v.as_str()))
.collect();
// Define the standard workspace path inside the container
let container_workspace = Path::new("/github/workspace");
// Set up volume mapping from host working dir to container workspace
let volumes: Vec<(&Path, &Path)> = vec![(ctx.working_dir, container_workspace)];
// Execute the command
match ctx
.runtime
.run_container(
"ubuntu:latest", // or appropriate runner image
ctx.runner_image,
&cmd_parts,
&env_vars,
ctx.working_dir,
&[], // Empty volumes for now, add if needed
container_workspace,
&volumes,
)
.await
{
@@ -1606,11 +1614,11 @@ fn get_runner_image(runs_on: &str) -> String {
"ubuntu-20.04-large" => "catthehacker/ubuntu:full-20.04",
"ubuntu-18.04-large" => "catthehacker/ubuntu:full-18.04",
// macOS runners - use existing images for macOS compatibility layer
"macos-latest" => "catthehacker/ubuntu:act-latest", // Use Ubuntu with macOS compatibility
"macos-12" => "catthehacker/ubuntu:act-latest", // Monterey equivalent
"macos-11" => "catthehacker/ubuntu:act-latest", // Big Sur equivalent
"macos-10.15" => "catthehacker/ubuntu:act-latest", // Catalina equivalent
// macOS runners - use a standard Rust image for compatibility
"macos-latest" => "rust:latest",
"macos-12" => "rust:latest", // Monterey equivalent
"macos-11" => "rust:latest", // Big Sur equivalent
"macos-10.15" => "rust:latest", // Catalina equivalent
// Windows runners - using servercore-based images
"windows-latest" => "mcr.microsoft.com/windows/servercore:ltsc2022",
@@ -1649,7 +1657,7 @@ fn get_runner_image(runs_on: &str) -> String {
// Check for platform prefixes and provide appropriate images
let runs_on_lower = runs_on.trim().to_lowercase();
if runs_on_lower.starts_with("macos") {
"catthehacker/ubuntu:act-latest" // Use Ubuntu with macOS compatibility
"rust:latest" // Use Rust image for macOS runners
} else if runs_on_lower.starts_with("windows") {
"mcr.microsoft.com/windows/servercore:ltsc2022" // Default Windows image
} else if runs_on_lower.starts_with("python") {
@@ -1727,7 +1735,7 @@ async fn execute_composite_action(
job_env: &HashMap<String, String>,
working_dir: &Path,
runtime: &dyn ContainerRuntime,
job_runs_on: &str,
runner_image: &str,
verbose: bool,
) -> Result<StepResult, ExecutionError> {
// Find the action definition file
@@ -1823,7 +1831,7 @@ async fn execute_composite_action(
on_raw: serde_yaml::Value::Null,
jobs: HashMap::new(),
},
job_runs_on,
runner_image,
verbose,
matrix_combination: &None,
}))