Execute debugger REPL commands inside job container#4420
Open
rentziass wants to merge 3 commits into
Open
Conversation
When a job uses a container: definition, the debugger REPL was always executing run commands on the host via IProcessInvoker directly. This meant that commands like 'cat /etc/os-release' would show the host OS instead of the container's OS. Fix this by reusing IStepHost — the same abstraction that normal run: steps use — to decide whether to execute on the host or inside the container via docker exec. The decision is based on the current step type: - Action steps (user-defined run:/uses:) execute inside the container, matching the behavior of normal workflow run: steps. - Infrastructure steps (Set up job, Initialize containers, Stop containers, Complete job) always execute on the host. This also correctly handles container hooks (where ContainerId may be empty but execution should still go through the container hook manager) and PrependPath propagation for both host and container execution. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When the debugger pauses at a step, emit a console output banner so the user knows where REPL commands will execute: ⬡ alpine:3.20 (abc123def456) — commands run inside the container ⊙ host — commands run on the host This compensates for DAP not supporting custom prompts. The banner appears automatically each time the debugger stops, using the container image name and a short container ID for container steps, or 'host' for infrastructure steps. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the DAP debugger REPL so run("...") commands execute in the same place a normal workflow run: step would: inside the job container for user/action steps, and on the runner host for infrastructure steps. It does so by reusing the existing IStepHost abstraction (including container path translation and PATH propagation), and adds a console banner on each pause to indicate where REPL commands will run.
Changes:
- Route REPL execution through
IStepHost(container vs host) instead of always usingIProcessInvokerdirectly. - Add step-type awareness (
isActionStep) and emit an execution-context banner on pause. - Add unit tests for
CreateStepHostdecision logic.
Show a summary per file
| File | Description |
|---|---|
src/Runner.Worker/Dap/DapReplExecutor.cs |
Switch REPL command execution to IStepHost, handling container path translation and PATH propagation, and add CreateStepHost selection logic. |
src/Runner.Worker/Dap/DapDebugger.cs |
Pass action/infrastructure step context into the REPL executor and emit a banner indicating host vs container execution. |
src/Test/L0/Worker/DapReplExecutorL0.cs |
Extend L0 coverage for CreateStepHost across container/no-container and action/infrastructure scenarios. |
Copilot's findings
Comments suppressed due to low confidence (1)
src/Runner.Worker/Dap/DapReplExecutor.cs:151
PrependPathpropagation is currently gated onstepHost is ContainerStepHost. Since the step host is created asIContainerStepHost, this will fail to setPrependPathfor any non-ContainerStepHostimplementation, causing PATH behavior to diverge from normal container step execution. Consider switching this cast/check toIContainerStepHostso all container step hosts receivePrependPath.
// 7. Handle PrependPath — mirrors Handler.AddPrependPathToEnvironment
if (context.Global.PrependPath.Count > 0)
{
if (stepHost is ContainerStepHost containerHost)
{
containerHost.PrependPath = prependPath;
}
- Files reviewed: 3/3 changed files
- Comments generated: 3
…ing and test - Check against IContainerStepHost interface instead of the concrete ContainerStepHost type, so alternative implementations registered in the service locator are handled correctly. - Add a trace warning when container hooks are enabled, since the hook manager does not raise OutputDataReceived/ErrorDataReceived events and REPL output will not be streamed in that mode. - Add a test for the container hooks path where ContainerId is empty but hooks are enabled, verifying CreateStepHost still returns an IContainerStepHost. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When a job uses a
container:definition, the debugger REPL was always executingruncommands on the runner host viaIProcessInvokerdirectly. This meant commands likecat /etc/os-releasewould show the host OS (Ubuntu) instead of the container's OS (e.g. Alpine), making the debugger unreliable for inspecting container job state.Approach
Instead of duplicating
docker execlogic, the REPL executor now reusesIStepHost-- the same abstraction that normal workflowrun:steps use. The debugger determines the current step type and creates the appropriate host:run:/uses:) get aContainerStepHost, which routes execution throughdocker exec(or container hooks when enabled). Script paths and working directories are translated to container paths, andPrependPathis propagated to the container'sPATH.DefaultStepHostand always execute on the runner host, since these steps operate outside the container lifecycle.The guiding principle: running a command in the debug console should behave identically to having a
run:step in your workflow file.Execution context banner
Since DAP doesn't support customizing the console prompt, the debugger now emits a banner each time it pauses at a step so the user knows where commands will run:
Testing
Added unit tests for
CreateStepHostcovering:DefaultStepHostContainerStepHostDefaultStepHostDefaultStepHost