diff --git a/src/Runner.Worker/Dap/DapVariableProvider.cs b/src/Runner.Worker/Dap/DapVariableProvider.cs
index 87f068c74..ea1fa591a 100644
--- a/src/Runner.Worker/Dap/DapVariableProvider.cs
+++ b/src/Runner.Worker/Dap/DapVariableProvider.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using GitHub.DistributedTask.ObjectTemplating.Tokens;
using GitHub.DistributedTask.Pipelines.ContextData;
using GitHub.Runner.Common;
@@ -170,6 +171,92 @@ namespace GitHub.Runner.Worker.Dap
return _hostContext.SecretMasker.MaskSecrets(value);
}
+ ///
+ /// Evaluates a GitHub Actions expression (e.g. "github.repository",
+ /// "${{ github.event_name }}") in the context of the current step and
+ /// returns a masked result suitable for the DAP evaluate response.
+ ///
+ /// Uses the runner's standard
+ /// so the full expression language is available (functions, operators,
+ /// context access).
+ ///
+ public EvaluateResponseBody EvaluateExpression(string expression, IExecutionContext context)
+ {
+ if (context?.ExpressionValues == null)
+ {
+ return new EvaluateResponseBody
+ {
+ Result = "(no execution context available)",
+ Type = "string",
+ VariablesReference = 0
+ };
+ }
+
+ // Strip ${{ }} wrapper if present
+ var expr = expression?.Trim() ?? string.Empty;
+ if (expr.StartsWith("${{") && expr.EndsWith("}}"))
+ {
+ expr = expr.Substring(3, expr.Length - 5).Trim();
+ }
+
+ if (string.IsNullOrEmpty(expr))
+ {
+ return new EvaluateResponseBody
+ {
+ Result = string.Empty,
+ Type = "string",
+ VariablesReference = 0
+ };
+ }
+
+ try
+ {
+ var templateEvaluator = context.ToPipelineTemplateEvaluator();
+ var token = new BasicExpressionToken(null, null, null, expr);
+
+ var result = templateEvaluator.EvaluateStepDisplayName(
+ token,
+ context.ExpressionValues,
+ context.ExpressionFunctions);
+
+ result = MaskSecrets(result ?? "null");
+
+ return new EvaluateResponseBody
+ {
+ Result = result,
+ Type = InferResultType(result),
+ VariablesReference = 0
+ };
+ }
+ catch (Exception ex)
+ {
+ var errorMessage = MaskSecrets($"Evaluation error: {ex.Message}");
+ return new EvaluateResponseBody
+ {
+ Result = errorMessage,
+ Type = "string",
+ VariablesReference = 0
+ };
+ }
+ }
+
+ ///
+ /// Infers a simple DAP type hint from the string representation of a result.
+ ///
+ internal static string InferResultType(string value)
+ {
+ if (value == null || value == "null")
+ return "null";
+ if (value == "true" || value == "false")
+ return "boolean";
+ if (double.TryParse(value, System.Globalization.NumberStyles.Any,
+ System.Globalization.CultureInfo.InvariantCulture, out _))
+ return "number";
+ if (value.StartsWith("{") || value.StartsWith("["))
+ return "object";
+ return "string";
+ }
+
#region Private helpers
private void ConvertToVariables(