Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds Dev Tunnels–based remote connectivity for debugger (DAP) jobs by extending the job message contract with tunnel details and updating the worker-side debugger startup to bind to the tunnel-provided port and start a tunnel relay.
Changes:
- Extend
AgentJobRequestMessagewithDebuggerTunnelpayload deserialization (tunnel ID/cluster/token/port) and add theDebuggerTunnelInfocontract type. - Replace
GlobalContext.EnableDebuggerwith a consolidatedDebuggerConfig(enabled + tunnel info) and update debugger enablement checks accordingly. - Update
DapDebuggerto require a valid tunnel config, bind to the tunnel port, and start/stop a Dev Tunnel relay; adjust L0 tests to use the new config model.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Test/L0/Worker/DapDebuggerL0.cs | Updates L0 tests to use tunnel-based debugger config and skips relay during unit tests. |
| src/Test/L0/Sdk/RSWebApi/AgentJobRequestMessageL0.cs | Adds deserialization tests for the new DebuggerTunnel payload. |
| src/Sdk/DTPipelines/Pipelines/DebuggerTunnelInfo.cs | Introduces the tunnel info DataContract used in job messages. |
| src/Sdk/DTPipelines/Pipelines/AgentJobRequestMessage.cs | Adds DebuggerTunnel DataMember to the job request message. |
| src/Runner.Worker/Runner.Worker.csproj | Adds Microsoft.DevTunnels.Connections dependency for relay hosting. |
| src/Runner.Worker/JobRunner.cs | Switches debugger enablement check to Global.Debugger?.Enabled. |
| src/Runner.Worker/GlobalContext.cs | Replaces EnableDebugger with DebuggerConfig Debugger. |
| src/Runner.Worker/ExecutionContext.cs | Populates Global.Debugger from EnableDebugger + DebuggerTunnel in the acquire response. |
| src/Runner.Worker/Dap/DebuggerConfig.cs | Adds consolidated debugger configuration and tunnel validity check. |
| src/Runner.Worker/Dap/DapDebugger.cs | Requires valid tunnel config, binds to tunnel port, and starts/stops Dev Tunnel relay. |
| /// Useful when third-party libraries require a <see cref="System.Diagnostics.TraceSource"/> | ||
| /// to route their diagnostics into the runner's log infrastructure. | ||
| /// </summary> | ||
| public TraceSource Source => _traceSource; |
There was a problem hiding this comment.
does this work? are we able to get log from the AzureSDK into the runner diag log?
There was a problem hiding this comment.
Yup:
[2026-04-02 12:46:34Z INFO DapDebugger] Starting Dev Tunnel relay (tunnel=neat-ocean-5b7j1lw, cluster=use2)
[2026-04-02 12:46:34Z VERB HttpClientHandlerFactory] Entering Initialize
[2026-04-02 12:46:34Z INFO Worker] Listening for cancel message from the channel.
[2026-04-02 12:46:34Z INFO Worker] Waiting for the job to complete or for a cancel message from the channel.
DevTunnelRelay Verbose: 0 : Connecting to host tunnel relay wss://use2-data.rel.tunnels.api.visualstudio.com/api/v1/Host/Connect/***
[2026-04-02 12:46:35Z VERB JobServerQueue] Merged Timeline records
[2026-04-02 12:46:35Z VERB JobServerQueue] Record: t=Job, n=build, s=InProgress, st=04/02/2026 12:46:34, 0%, ft=, r=:
[2026-04-02 12:46:35Z INFO JobServerQueue] Job timeline record has been updated for the first time.
DevTunnelRelay Verbose: 0 : Connected with subprotocol 'tunnel-relay-host'
src/Runner.Worker/Dap/DapDebugger.cs
Outdated
| HandleClientDisconnected(); | ||
| CleanupConnection(); | ||
| } | ||
| catch (ObjectDisposedException) |
There was a problem hiding this comment.
if we are catching ObjectDisposedException, we might have something doing wrong since we shouldn't dispose an object if we are stilling using it somewhere else, dispose should be the last thing to call when everything has stopped.
There was a problem hiding this comment.
Yeah I made a bit of a mess trying to get cancellation/shutdown to cleanup everything, should be better now.
This PR adds remote debugger connectivity to the runner via Dev Tunnels. The runner now deserializes the DebuggerTunnel payload (tunnel ID, cluster, host token, port) from the job message, binds the DAP server to the tunnel-provided port, and starts a Dev Tunnel relay so remote DAP clients can connect. The DAP port is now mandated by the backend for two reasons:
Since we're adding more debugger configuration this also changes the previous
EnableDebuggerbool in context with an object carrying that configuration.https://github.com/github/c2c-actions/issues/9831