Compare commits

...

2 Commits

Author SHA1 Message Date
github-actions[bot]
b9275b59cf chore: update Node versions (#4319)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-30 12:58:17 +00:00
eric sciple
f0c228635e Remove AllowCaseFunction feature flag (#4316) 2026-03-27 11:45:42 -05:00
13 changed files with 71 additions and 84 deletions

View File

@@ -6,8 +6,8 @@ NODE_URL=https://nodejs.org/dist
NODE_ALPINE_URL=https://github.com/actions/alpine_nodejs/releases/download NODE_ALPINE_URL=https://github.com/actions/alpine_nodejs/releases/download
# When you update Node versions you must also create a new release of alpine_nodejs at that updated version. # When you update Node versions you must also create a new release of alpine_nodejs at that updated version.
# Follow the instructions here: https://github.com/actions/alpine_nodejs?tab=readme-ov-file#getting-started # Follow the instructions here: https://github.com/actions/alpine_nodejs?tab=readme-ov-file#getting-started
NODE20_VERSION="20.20.1" NODE20_VERSION="20.20.2"
NODE24_VERSION="24.14.0" NODE24_VERSION="24.14.1"
get_abs_path() { get_abs_path() {
# exploits the fact that pwd will print abs path when no args # exploits the fact that pwd will print abs path when no args

View File

@@ -316,7 +316,6 @@ namespace GitHub.Runner.Worker
Schema = _actionManifestSchema, Schema = _actionManifestSchema,
// TODO: Switch to real tracewriter for cutover // TODO: Switch to real tracewriter for cutover
TraceWriter = new GitHub.Actions.WorkflowParser.ObjectTemplating.EmptyTraceWriter(), TraceWriter = new GitHub.Actions.WorkflowParser.ObjectTemplating.EmptyTraceWriter(),
AllowCaseFunction = false,
}; };
// Expression values from execution context // Expression values from execution context

View File

@@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
@@ -315,7 +315,6 @@ namespace GitHub.Runner.Worker
maxBytes: 10 * 1024 * 1024), maxBytes: 10 * 1024 * 1024),
Schema = _actionManifestSchema, Schema = _actionManifestSchema,
TraceWriter = executionContext.ToTemplateTraceWriter(), TraceWriter = executionContext.ToTemplateTraceWriter(),
AllowCaseFunction = false,
}; };
// Expression values from execution context // Expression values from execution context

View File

@@ -17,10 +17,9 @@ namespace GitHub.DistributedTask.Expressions2
String expression, String expression,
ITraceWriter trace, ITraceWriter trace,
IEnumerable<INamedValueInfo> namedValues, IEnumerable<INamedValueInfo> namedValues,
IEnumerable<IFunctionInfo> functions, IEnumerable<IFunctionInfo> functions)
Boolean allowCaseFunction = true)
{ {
var context = new ParseContext(expression, trace, namedValues, functions, allowCaseFunction: allowCaseFunction); var context = new ParseContext(expression, trace, namedValues, functions);
context.Trace.Info($"Parsing expression: <{expression}>"); context.Trace.Info($"Parsing expression: <{expression}>");
return CreateTree(context); return CreateTree(context);
} }
@@ -416,12 +415,6 @@ namespace GitHub.DistributedTask.Expressions2
String name, String name,
out IFunctionInfo functionInfo) out IFunctionInfo functionInfo)
{ {
if (String.Equals(name, "case", StringComparison.OrdinalIgnoreCase) && !context.AllowCaseFunction)
{
functionInfo = null;
return false;
}
return ExpressionConstants.WellKnownFunctions.TryGetValue(name, out functionInfo) || return ExpressionConstants.WellKnownFunctions.TryGetValue(name, out functionInfo) ||
context.ExtensionFunctions.TryGetValue(name, out functionInfo); context.ExtensionFunctions.TryGetValue(name, out functionInfo);
} }
@@ -429,7 +422,6 @@ namespace GitHub.DistributedTask.Expressions2
private sealed class ParseContext private sealed class ParseContext
{ {
public Boolean AllowUnknownKeywords; public Boolean AllowUnknownKeywords;
public Boolean AllowCaseFunction;
public readonly String Expression; public readonly String Expression;
public readonly Dictionary<String, IFunctionInfo> ExtensionFunctions = new Dictionary<String, IFunctionInfo>(StringComparer.OrdinalIgnoreCase); public readonly Dictionary<String, IFunctionInfo> ExtensionFunctions = new Dictionary<String, IFunctionInfo>(StringComparer.OrdinalIgnoreCase);
public readonly Dictionary<String, INamedValueInfo> ExtensionNamedValues = new Dictionary<String, INamedValueInfo>(StringComparer.OrdinalIgnoreCase); public readonly Dictionary<String, INamedValueInfo> ExtensionNamedValues = new Dictionary<String, INamedValueInfo>(StringComparer.OrdinalIgnoreCase);
@@ -445,8 +437,7 @@ namespace GitHub.DistributedTask.Expressions2
ITraceWriter trace, ITraceWriter trace,
IEnumerable<INamedValueInfo> namedValues, IEnumerable<INamedValueInfo> namedValues,
IEnumerable<IFunctionInfo> functions, IEnumerable<IFunctionInfo> functions,
Boolean allowUnknownKeywords = false, Boolean allowUnknownKeywords = false)
Boolean allowCaseFunction = true)
{ {
Expression = expression ?? String.Empty; Expression = expression ?? String.Empty;
if (Expression.Length > ExpressionConstants.MaxLength) if (Expression.Length > ExpressionConstants.MaxLength)
@@ -467,7 +458,6 @@ namespace GitHub.DistributedTask.Expressions2
LexicalAnalyzer = new LexicalAnalyzer(Expression); LexicalAnalyzer = new LexicalAnalyzer(Expression);
AllowUnknownKeywords = allowUnknownKeywords; AllowUnknownKeywords = allowUnknownKeywords;
AllowCaseFunction = allowCaseFunction;
} }
private class NoOperationTraceWriter : ITraceWriter private class NoOperationTraceWriter : ITraceWriter

View File

@@ -86,12 +86,6 @@ namespace GitHub.DistributedTask.ObjectTemplating
internal ITraceWriter TraceWriter { get; set; } internal ITraceWriter TraceWriter { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the case expression function is allowed.
/// Defaults to true. Set to false to disable the case function.
/// </summary>
internal Boolean AllowCaseFunction { get; set; } = true;
private IDictionary<String, Int32> FileIds private IDictionary<String, Int32> FileIds
{ {
get get

View File

@@ -57,7 +57,7 @@ namespace GitHub.DistributedTask.ObjectTemplating.Tokens
var originalBytes = context.Memory.CurrentBytes; var originalBytes = context.Memory.CurrentBytes;
try try
{ {
var tree = new ExpressionParser().CreateTree(expression, null, context.GetExpressionNamedValues(), context.ExpressionFunctions, allowCaseFunction: context.AllowCaseFunction); var tree = new ExpressionParser().CreateTree(expression, null, context.GetExpressionNamedValues(), context.ExpressionFunctions);
var options = new EvaluationOptions var options = new EvaluationOptions
{ {
MaxMemory = context.Memory.MaxBytes, MaxMemory = context.Memory.MaxBytes,
@@ -94,7 +94,7 @@ namespace GitHub.DistributedTask.ObjectTemplating.Tokens
var originalBytes = context.Memory.CurrentBytes; var originalBytes = context.Memory.CurrentBytes;
try try
{ {
var tree = new ExpressionParser().CreateTree(expression, null, context.GetExpressionNamedValues(), context.ExpressionFunctions, allowCaseFunction: context.AllowCaseFunction); var tree = new ExpressionParser().CreateTree(expression, null, context.GetExpressionNamedValues(), context.ExpressionFunctions);
var options = new EvaluationOptions var options = new EvaluationOptions
{ {
MaxMemory = context.Memory.MaxBytes, MaxMemory = context.Memory.MaxBytes,
@@ -123,7 +123,7 @@ namespace GitHub.DistributedTask.ObjectTemplating.Tokens
var originalBytes = context.Memory.CurrentBytes; var originalBytes = context.Memory.CurrentBytes;
try try
{ {
var tree = new ExpressionParser().CreateTree(expression, null, context.GetExpressionNamedValues(), context.ExpressionFunctions, allowCaseFunction: context.AllowCaseFunction); var tree = new ExpressionParser().CreateTree(expression, null, context.GetExpressionNamedValues(), context.ExpressionFunctions);
var options = new EvaluationOptions var options = new EvaluationOptions
{ {
MaxMemory = context.Memory.MaxBytes, MaxMemory = context.Memory.MaxBytes,
@@ -152,7 +152,7 @@ namespace GitHub.DistributedTask.ObjectTemplating.Tokens
var originalBytes = context.Memory.CurrentBytes; var originalBytes = context.Memory.CurrentBytes;
try try
{ {
var tree = new ExpressionParser().CreateTree(expression, null, context.GetExpressionNamedValues(), context.ExpressionFunctions, allowCaseFunction: context.AllowCaseFunction); var tree = new ExpressionParser().CreateTree(expression, null, context.GetExpressionNamedValues(), context.ExpressionFunctions);
var options = new EvaluationOptions var options = new EvaluationOptions
{ {
MaxMemory = context.Memory.MaxBytes, MaxMemory = context.Memory.MaxBytes,

View File

@@ -681,7 +681,7 @@ namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
var node = default(ExpressionNode); var node = default(ExpressionNode);
try try
{ {
node = expressionParser.CreateTree(condition, null, namedValues, functions, allowCaseFunction: context.AllowCaseFunction) as ExpressionNode; node = expressionParser.CreateTree(condition, null, namedValues, functions) as ExpressionNode;
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@@ -1,4 +1,4 @@
#nullable disable // Consider removing in the future to minimize likelihood of NullReferenceException; refer https://learn.microsoft.com/en-us/dotnet/csharp/nullable-references #nullable disable // Consider removing in the future to minimize likelihood of NullReferenceException; refer https://learn.microsoft.com/en-us/dotnet/csharp/nullable-references
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -17,10 +17,9 @@ namespace GitHub.Actions.Expressions
String expression, String expression,
ITraceWriter trace, ITraceWriter trace,
IEnumerable<INamedValueInfo> namedValues, IEnumerable<INamedValueInfo> namedValues,
IEnumerable<IFunctionInfo> functions, IEnumerable<IFunctionInfo> functions)
Boolean allowCaseFunction = true)
{ {
var context = new ParseContext(expression, trace, namedValues, functions, allowCaseFunction: allowCaseFunction); var context = new ParseContext(expression, trace, namedValues, functions);
context.Trace.Info($"Parsing expression: <{expression}>"); context.Trace.Info($"Parsing expression: <{expression}>");
return CreateTree(context); return CreateTree(context);
} }
@@ -322,7 +321,7 @@ namespace GitHub.Actions.Expressions
context.Operators.Pop(); context.Operators.Pop();
} }
var functionOperands = PopOperands(context, parameterCount); var functionOperands = PopOperands(context, parameterCount);
// Node already exists on the operand stack // Node already exists on the operand stack
function = (Function)context.Operands.Peek(); function = (Function)context.Operands.Peek();
@@ -416,12 +415,6 @@ namespace GitHub.Actions.Expressions
String name, String name,
out IFunctionInfo functionInfo) out IFunctionInfo functionInfo)
{ {
if (String.Equals(name, "case", StringComparison.OrdinalIgnoreCase) && !context.AllowCaseFunction)
{
functionInfo = null;
return false;
}
return ExpressionConstants.WellKnownFunctions.TryGetValue(name, out functionInfo) || return ExpressionConstants.WellKnownFunctions.TryGetValue(name, out functionInfo) ||
context.ExtensionFunctions.TryGetValue(name, out functionInfo); context.ExtensionFunctions.TryGetValue(name, out functionInfo);
} }
@@ -429,7 +422,6 @@ namespace GitHub.Actions.Expressions
private sealed class ParseContext private sealed class ParseContext
{ {
public Boolean AllowUnknownKeywords; public Boolean AllowUnknownKeywords;
public Boolean AllowCaseFunction;
public readonly String Expression; public readonly String Expression;
public readonly Dictionary<String, IFunctionInfo> ExtensionFunctions = new Dictionary<String, IFunctionInfo>(StringComparer.OrdinalIgnoreCase); public readonly Dictionary<String, IFunctionInfo> ExtensionFunctions = new Dictionary<String, IFunctionInfo>(StringComparer.OrdinalIgnoreCase);
public readonly Dictionary<String, INamedValueInfo> ExtensionNamedValues = new Dictionary<String, INamedValueInfo>(StringComparer.OrdinalIgnoreCase); public readonly Dictionary<String, INamedValueInfo> ExtensionNamedValues = new Dictionary<String, INamedValueInfo>(StringComparer.OrdinalIgnoreCase);
@@ -445,8 +437,7 @@ namespace GitHub.Actions.Expressions
ITraceWriter trace, ITraceWriter trace,
IEnumerable<INamedValueInfo> namedValues, IEnumerable<INamedValueInfo> namedValues,
IEnumerable<IFunctionInfo> functions, IEnumerable<IFunctionInfo> functions,
Boolean allowUnknownKeywords = false, Boolean allowUnknownKeywords = false)
Boolean allowCaseFunction = true)
{ {
Expression = expression ?? String.Empty; Expression = expression ?? String.Empty;
if (Expression.Length > ExpressionConstants.MaxLength) if (Expression.Length > ExpressionConstants.MaxLength)
@@ -467,7 +458,6 @@ namespace GitHub.Actions.Expressions
LexicalAnalyzer = new LexicalAnalyzer(Expression); LexicalAnalyzer = new LexicalAnalyzer(Expression);
AllowUnknownKeywords = allowUnknownKeywords; AllowUnknownKeywords = allowUnknownKeywords;
AllowCaseFunction = allowCaseFunction;
} }
private class NoOperationTraceWriter : ITraceWriter private class NoOperationTraceWriter : ITraceWriter

View File

@@ -1828,7 +1828,7 @@ namespace GitHub.Actions.WorkflowParser.Conversion
var node = default(ExpressionNode); var node = default(ExpressionNode);
try try
{ {
node = expressionParser.CreateTree(condition, null, namedValues, functions, allowCaseFunction: context.AllowCaseFunction) as ExpressionNode; node = expressionParser.CreateTree(condition, null, namedValues, functions) as ExpressionNode;
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@@ -1,4 +1,4 @@
#nullable disable // Consider removing in the future to minimize likelihood of NullReferenceException; refer https://learn.microsoft.com/en-us/dotnet/csharp/nullable-references #nullable disable // Consider removing in the future to minimize likelihood of NullReferenceException; refer https://learn.microsoft.com/en-us/dotnet/csharp/nullable-references
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -113,12 +113,6 @@ namespace GitHub.Actions.WorkflowParser.ObjectTemplating
/// </summary> /// </summary>
internal Boolean StrictJsonParsing { get; set; } internal Boolean StrictJsonParsing { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the case expression function is allowed.
/// Defaults to true. Set to false to disable the case function.
/// </summary>
internal Boolean AllowCaseFunction { get; set; } = true;
internal ITraceWriter TraceWriter { get; set; } internal ITraceWriter TraceWriter { get; set; }
private IDictionary<String, Int32> FileIds private IDictionary<String, Int32> FileIds

View File

@@ -1,4 +1,4 @@
#nullable disable // Consider removing in the future to minimize likelihood of NullReferenceException; refer https://learn.microsoft.com/en-us/dotnet/csharp/nullable-references #nullable disable // Consider removing in the future to minimize likelihood of NullReferenceException; refer https://learn.microsoft.com/en-us/dotnet/csharp/nullable-references
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -55,7 +55,7 @@ namespace GitHub.Actions.WorkflowParser.ObjectTemplating.Tokens
var originalBytes = context.Memory.CurrentBytes; var originalBytes = context.Memory.CurrentBytes;
try try
{ {
var tree = new ExpressionParser().CreateTree(expression, null, context.GetExpressionNamedValues(), context.ExpressionFunctions, allowCaseFunction: context.AllowCaseFunction); var tree = new ExpressionParser().CreateTree(expression, null, context.GetExpressionNamedValues(), context.ExpressionFunctions);
var options = new EvaluationOptions var options = new EvaluationOptions
{ {
MaxMemory = context.Memory.MaxBytes, MaxMemory = context.Memory.MaxBytes,
@@ -93,7 +93,7 @@ namespace GitHub.Actions.WorkflowParser.ObjectTemplating.Tokens
var originalBytes = context.Memory.CurrentBytes; var originalBytes = context.Memory.CurrentBytes;
try try
{ {
var tree = new ExpressionParser().CreateTree(expression, null, context.GetExpressionNamedValues(), context.ExpressionFunctions, allowCaseFunction: context.AllowCaseFunction); var tree = new ExpressionParser().CreateTree(expression, null, context.GetExpressionNamedValues(), context.ExpressionFunctions);
var options = new EvaluationOptions var options = new EvaluationOptions
{ {
MaxMemory = context.Memory.MaxBytes, MaxMemory = context.Memory.MaxBytes,
@@ -123,7 +123,7 @@ namespace GitHub.Actions.WorkflowParser.ObjectTemplating.Tokens
var originalBytes = context.Memory.CurrentBytes; var originalBytes = context.Memory.CurrentBytes;
try try
{ {
var tree = new ExpressionParser().CreateTree(expression, null, context.GetExpressionNamedValues(), context.ExpressionFunctions, allowCaseFunction: context.AllowCaseFunction); var tree = new ExpressionParser().CreateTree(expression, null, context.GetExpressionNamedValues(), context.ExpressionFunctions);
var options = new EvaluationOptions var options = new EvaluationOptions
{ {
MaxMemory = context.Memory.MaxBytes, MaxMemory = context.Memory.MaxBytes,
@@ -153,7 +153,7 @@ namespace GitHub.Actions.WorkflowParser.ObjectTemplating.Tokens
var originalBytes = context.Memory.CurrentBytes; var originalBytes = context.Memory.CurrentBytes;
try try
{ {
var tree = new ExpressionParser().CreateTree(expression, null, context.GetExpressionNamedValues(), context.ExpressionFunctions, allowCaseFunction: context.AllowCaseFunction); var tree = new ExpressionParser().CreateTree(expression, null, context.GetExpressionNamedValues(), context.ExpressionFunctions);
var options = new EvaluationOptions var options = new EvaluationOptions
{ {
MaxMemory = context.Memory.MaxBytes, MaxMemory = context.Memory.MaxBytes,
@@ -289,4 +289,4 @@ namespace GitHub.Actions.WorkflowParser.ObjectTemplating.Tokens
return result; return result;
} }
} }
} }

View File

@@ -1,4 +1,4 @@
using GitHub.DistributedTask.Expressions2; using GitHub.DistributedTask.Expressions2;
using GitHub.DistributedTask.Expressions2.Sdk; using GitHub.DistributedTask.Expressions2.Sdk;
using GitHub.DistributedTask.ObjectTemplating; using GitHub.DistributedTask.ObjectTemplating;
using System; using System;
@@ -9,7 +9,7 @@ namespace GitHub.Runner.Common.Tests.Sdk
{ {
/// <summary> /// <summary>
/// Regression tests for ExpressionParser.CreateTree to verify that /// Regression tests for ExpressionParser.CreateTree to verify that
/// allowCaseFunction does not accidentally set allowUnknownKeywords. /// the case function does not accidentally set allowUnknownKeywords.
/// </summary> /// </summary>
public sealed class ExpressionParserL0 public sealed class ExpressionParserL0
{ {
@@ -18,7 +18,7 @@ namespace GitHub.Runner.Common.Tests.Sdk
[Trait("Category", "Sdk")] [Trait("Category", "Sdk")]
public void CreateTree_RejectsUnrecognizedNamedValue() public void CreateTree_RejectsUnrecognizedNamedValue()
{ {
// Regression: allowCaseFunction was passed positionally into // Regression: the case function parameter was passed positionally into
// the allowUnknownKeywords parameter, causing all named values // the allowUnknownKeywords parameter, causing all named values
// to be silently accepted. // to be silently accepted.
var parser = new ExpressionParser(); var parser = new ExpressionParser();
@@ -52,7 +52,7 @@ namespace GitHub.Runner.Common.Tests.Sdk
[Fact] [Fact]
[Trait("Level", "L0")] [Trait("Level", "L0")]
[Trait("Category", "Sdk")] [Trait("Category", "Sdk")]
public void CreateTree_CaseFunctionWorks_WhenAllowed() public void CreateTree_CaseFunctionWorks()
{ {
var parser = new ExpressionParser(); var parser = new ExpressionParser();
var namedValues = new List<INamedValueInfo> var namedValues = new List<INamedValueInfo>
@@ -60,35 +60,17 @@ namespace GitHub.Runner.Common.Tests.Sdk
new NamedValueInfo<ContextValueNode>("github"), new NamedValueInfo<ContextValueNode>("github"),
}; };
var node = parser.CreateTree("case(github.event_name, 'push', 'Push Event')", null, namedValues, null, allowCaseFunction: true); var node = parser.CreateTree("case(github.event_name, 'push', 'Push Event')", null, namedValues, null);
Assert.NotNull(node); Assert.NotNull(node);
} }
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Sdk")]
public void CreateTree_CaseFunctionRejected_WhenDisallowed()
{
var parser = new ExpressionParser();
var namedValues = new List<INamedValueInfo>
{
new NamedValueInfo<ContextValueNode>("github"),
};
var ex = Assert.Throws<ParseException>(() =>
parser.CreateTree("case(github.event_name, 'push', 'Push Event')", null, namedValues, null, allowCaseFunction: false));
Assert.Contains("Unrecognized function", ex.Message);
}
[Fact] [Fact]
[Trait("Level", "L0")] [Trait("Level", "L0")]
[Trait("Category", "Sdk")] [Trait("Category", "Sdk")]
public void CreateTree_CaseFunctionDoesNotAffectUnknownKeywords() public void CreateTree_CaseFunctionDoesNotAffectUnknownKeywords()
{ {
// The key regression test: with allowCaseFunction=true (default), // The key regression test: unrecognized named values must still be rejected.
// unrecognized named values must still be rejected.
var parser = new ExpressionParser(); var parser = new ExpressionParser();
var namedValues = new List<INamedValueInfo> var namedValues = new List<INamedValueInfo>
{ {
@@ -96,7 +78,7 @@ namespace GitHub.Runner.Common.Tests.Sdk
}; };
var ex = Assert.Throws<ParseException>(() => var ex = Assert.Throws<ParseException>(() =>
parser.CreateTree("github.ref", null, namedValues, null, allowCaseFunction: true)); parser.CreateTree("github.ref", null, namedValues, null));
Assert.Contains("Unrecognized named-value", ex.Message); Assert.Contains("Unrecognized named-value", ex.Message);
} }

View File

@@ -504,7 +504,7 @@ namespace GitHub.Runner.Common.Tests.Worker
} }
} }
[Fact] [Fact]
[Trait("Level", "L0")] [Trait("Level", "L0")]
[Trait("Category", "Worker")] [Trait("Category", "Worker")]
public void Load_Node24Action() public void Load_Node24Action()
@@ -1006,6 +1006,45 @@ namespace GitHub.Runner.Common.Tests.Worker
_ec.Setup(x => x.AddIssue(It.IsAny<Issue>(), It.IsAny<ExecutionContextLogOptions>())).Callback((Issue issue, ExecutionContextLogOptions logOptions) => { _hc.GetTrace().Info($"[{issue.Type}]{logOptions.LogMessageOverride ?? issue.Message}"); }); _ec.Setup(x => x.AddIssue(It.IsAny<Issue>(), It.IsAny<ExecutionContextLogOptions>())).Callback((Issue issue, ExecutionContextLogOptions logOptions) => { _hc.GetTrace().Info($"[{issue.Type}]{logOptions.LogMessageOverride ?? issue.Message}"); });
} }
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public void Evaluate_Default_Input_Case_Function()
{
try
{
//Arrange
Setup();
var actionManifest = new ActionManifestManager();
actionManifest.Initialize(_hc);
_ec.Object.ExpressionValues["github"] = new LegacyContextData.DictionaryContextData
{
{ "ref", new LegacyContextData.StringContextData("refs/heads/main") },
};
_ec.Object.ExpressionValues["strategy"] = new LegacyContextData.DictionaryContextData();
_ec.Object.ExpressionValues["matrix"] = new LegacyContextData.DictionaryContextData();
_ec.Object.ExpressionValues["steps"] = new LegacyContextData.DictionaryContextData();
_ec.Object.ExpressionValues["job"] = new LegacyContextData.DictionaryContextData();
_ec.Object.ExpressionValues["runner"] = new LegacyContextData.DictionaryContextData();
_ec.Object.ExpressionValues["env"] = new LegacyContextData.DictionaryContextData();
_ec.Object.ExpressionFunctions.Add(new LegacyExpressions.FunctionInfo<GitHub.Runner.Worker.Expressions.HashFilesFunction>("hashFiles", 1, 255));
// Act — evaluate a case() expression as a default input value.
// The feature flag is set, so this should succeed.
var token = new BasicExpressionToken(null, null, null, "case(true, 'matched', 'default')");
var result = actionManifest.EvaluateDefaultInput(_ec.Object, "testInput", token);
// Assert — case() should evaluate successfully
Assert.Equal("matched", result);
}
finally
{
Teardown();
}
}
private void Teardown() private void Teardown()
{ {
_hc?.Dispose(); _hc?.Dispose();