mirror of
https://github.com/actions/runner.git
synced 2026-03-04 20:13:20 +08:00
Compare commits
1 Commits
users/eric
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70f2734040 |
@@ -172,7 +172,6 @@ namespace GitHub.Runner.Common
|
||||
public static readonly string SnapshotPreflightHostedRunnerCheck = "actions_snapshot_preflight_hosted_runner_check";
|
||||
public static readonly string SnapshotPreflightImageGenPoolCheck = "actions_snapshot_preflight_image_gen_pool_check";
|
||||
public static readonly string CompareWorkflowParser = "actions_runner_compare_workflow_parser";
|
||||
public static readonly string ServiceContainerCommand = "actions_service_container_command";
|
||||
public static readonly string SetOrchestrationIdEnvForActions = "actions_set_orchestration_id_env_for_actions";
|
||||
public static readonly string SendJobLevelAnnotations = "actions_send_job_level_annotations";
|
||||
public static readonly string EmitCompositeMarkers = "actions_runner_emit_composite_markers";
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
|
||||
<PackageReference Include="System.Threading.Channels" Version="8.0.0" />
|
||||
<PackageReference Include="System.Threading.Channels" Version="10.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
|
||||
@@ -36,14 +36,6 @@ namespace GitHub.Runner.Worker.Container
|
||||
this.ContainerImage = containerImage;
|
||||
this.ContainerDisplayName = $"{container.Alias}_{Pipelines.Validation.NameValidation.Sanitize(containerImage)}_{Guid.NewGuid().ToString("N").Substring(0, 6)}";
|
||||
this.ContainerCreateOptions = container.Options;
|
||||
if (!string.IsNullOrEmpty(container.Entrypoint))
|
||||
{
|
||||
this.ContainerEntryPoint = container.Entrypoint;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(container.Command))
|
||||
{
|
||||
this.ContainerEntryPointArgs = container.Command;
|
||||
}
|
||||
_environmentVariables = container.Environment;
|
||||
this.IsJobContainer = isJobContainer;
|
||||
this.ContainerNetworkAlias = networkAlias;
|
||||
|
||||
@@ -1328,9 +1328,9 @@ namespace GitHub.Runner.Worker
|
||||
UpdateGlobalStepsContext();
|
||||
}
|
||||
|
||||
internal IPipelineTemplateEvaluator ToPipelineTemplateEvaluatorInternal(bool allowServiceContainerCommand, ObjectTemplating.ITraceWriter traceWriter = null)
|
||||
internal IPipelineTemplateEvaluator ToPipelineTemplateEvaluatorInternal(ObjectTemplating.ITraceWriter traceWriter = null)
|
||||
{
|
||||
return new PipelineTemplateEvaluatorWrapper(HostContext, this, allowServiceContainerCommand, traceWriter);
|
||||
return new PipelineTemplateEvaluatorWrapper(HostContext, this, traceWriter);
|
||||
}
|
||||
|
||||
private static void NoOp()
|
||||
@@ -1418,13 +1418,10 @@ namespace GitHub.Runner.Worker
|
||||
|
||||
public static IPipelineTemplateEvaluator ToPipelineTemplateEvaluator(this IExecutionContext context, ObjectTemplating.ITraceWriter traceWriter = null)
|
||||
{
|
||||
var allowServiceContainerCommand = (context.Global.Variables.GetBoolean(Constants.Runner.Features.ServiceContainerCommand) ?? false)
|
||||
|| StringUtil.ConvertToBoolean(Environment.GetEnvironmentVariable("ACTIONS_SERVICE_CONTAINER_COMMAND"));
|
||||
|
||||
// Create wrapper?
|
||||
if ((context.Global.Variables.GetBoolean(Constants.Runner.Features.CompareWorkflowParser) ?? false) || StringUtil.ConvertToBoolean(Environment.GetEnvironmentVariable("ACTIONS_RUNNER_COMPARE_WORKFLOW_PARSER")))
|
||||
{
|
||||
return (context as ExecutionContext).ToPipelineTemplateEvaluatorInternal(allowServiceContainerCommand, traceWriter);
|
||||
return (context as ExecutionContext).ToPipelineTemplateEvaluatorInternal(traceWriter);
|
||||
}
|
||||
|
||||
// Legacy
|
||||
@@ -1436,7 +1433,6 @@ namespace GitHub.Runner.Worker
|
||||
return new PipelineTemplateEvaluator(traceWriter, schema, context.Global.FileTable)
|
||||
{
|
||||
MaxErrorMessageLength = int.MaxValue, // Don't truncate error messages otherwise we might not scrub secrets correctly
|
||||
AllowServiceContainerCommand = allowServiceContainerCommand,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ namespace GitHub.Runner.Worker
|
||||
public PipelineTemplateEvaluatorWrapper(
|
||||
IHostContext hostContext,
|
||||
IExecutionContext context,
|
||||
bool allowServiceContainerCommand,
|
||||
ObjectTemplating.ITraceWriter traceWriter = null)
|
||||
{
|
||||
ArgUtil.NotNull(hostContext, nameof(hostContext));
|
||||
@@ -41,14 +40,11 @@ namespace GitHub.Runner.Worker
|
||||
_legacyEvaluator = new PipelineTemplateEvaluator(traceWriter, schema, context.Global.FileTable)
|
||||
{
|
||||
MaxErrorMessageLength = int.MaxValue, // Don't truncate error messages otherwise we might not scrub secrets correctly
|
||||
AllowServiceContainerCommand = allowServiceContainerCommand,
|
||||
};
|
||||
|
||||
// New evaluator
|
||||
var newTraceWriter = new GitHub.Actions.WorkflowParser.ObjectTemplating.EmptyTraceWriter();
|
||||
var features = WorkflowFeatures.GetDefaults();
|
||||
features.AllowServiceContainerCommand = allowServiceContainerCommand;
|
||||
_newEvaluator = new WorkflowTemplateEvaluator(newTraceWriter, context.Global.FileTable, features)
|
||||
_newEvaluator = new WorkflowTemplateEvaluator(newTraceWriter, context.Global.FileTable, features: null)
|
||||
{
|
||||
MaxErrorMessageLength = int.MaxValue, // Don't truncate error messages otherwise we might not scrub secrets correctly
|
||||
};
|
||||
@@ -405,18 +401,6 @@ namespace GitHub.Runner.Worker
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!string.Equals(legacyResult.Entrypoint, newResult.Entrypoint, StringComparison.Ordinal))
|
||||
{
|
||||
_trace.Info($"CompareJobContainer mismatch - Entrypoint differs (legacy='{legacyResult.Entrypoint}', new='{newResult.Entrypoint}')");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!string.Equals(legacyResult.Command, newResult.Command, StringComparison.Ordinal))
|
||||
{
|
||||
_trace.Info($"CompareJobContainer mismatch - Command differs (legacy='{legacyResult.Command}', new='{newResult.Command}')");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CompareDictionaries(legacyResult.Environment, newResult.Environment, "Environment"))
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -39,24 +39,6 @@ namespace GitHub.DistributedTask.Pipelines
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the container entrypoint override.
|
||||
/// </summary>
|
||||
public String Entrypoint
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the container command and args (after the image name).
|
||||
/// </summary>
|
||||
public String Command
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the volumes which are mounted into the container.
|
||||
/// </summary>
|
||||
|
||||
@@ -47,8 +47,6 @@ namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
|
||||
public const String NumberStrategyContext = "number-strategy-context";
|
||||
public const String On = "on";
|
||||
public const String Options = "options";
|
||||
public const String Entrypoint = "entrypoint";
|
||||
public const String Command = "command";
|
||||
public const String Outputs = "outputs";
|
||||
public const String OutputsPattern = "needs.*.outputs";
|
||||
public const String Password = "password";
|
||||
|
||||
@@ -237,8 +237,7 @@ namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
|
||||
internal static JobContainer ConvertToJobContainer(
|
||||
TemplateContext context,
|
||||
TemplateToken value,
|
||||
bool allowExpressions = false,
|
||||
bool allowServiceContainerCommand = false)
|
||||
bool allowExpressions = false)
|
||||
{
|
||||
var result = new JobContainer();
|
||||
if (allowExpressions && value.Traverse().Any(x => x is ExpressionToken))
|
||||
@@ -281,22 +280,6 @@ namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
|
||||
case PipelineTemplateConstants.Options:
|
||||
result.Options = containerPropertyPair.Value.AssertString($"{PipelineTemplateConstants.Container} {propertyName}").Value;
|
||||
break;
|
||||
case PipelineTemplateConstants.Entrypoint:
|
||||
if (allowServiceContainerCommand)
|
||||
{
|
||||
result.Entrypoint = containerPropertyPair.Value.AssertString($"{PipelineTemplateConstants.Container} {propertyName}").Value;
|
||||
break;
|
||||
}
|
||||
propertyName.AssertUnexpectedValue($"{PipelineTemplateConstants.Container} key");
|
||||
break;
|
||||
case PipelineTemplateConstants.Command:
|
||||
if (allowServiceContainerCommand)
|
||||
{
|
||||
result.Command = containerPropertyPair.Value.AssertString($"{PipelineTemplateConstants.Container} {propertyName}").Value;
|
||||
break;
|
||||
}
|
||||
propertyName.AssertUnexpectedValue($"{PipelineTemplateConstants.Container} key");
|
||||
break;
|
||||
case PipelineTemplateConstants.Ports:
|
||||
var ports = containerPropertyPair.Value.AssertSequence($"{PipelineTemplateConstants.Container} {propertyName}");
|
||||
var portList = new List<String>(ports.Count);
|
||||
@@ -343,8 +326,7 @@ namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
|
||||
internal static List<KeyValuePair<String, JobContainer>> ConvertToJobServiceContainers(
|
||||
TemplateContext context,
|
||||
TemplateToken services,
|
||||
bool allowExpressions = false,
|
||||
bool allowServiceContainerCommand = false)
|
||||
bool allowExpressions = false)
|
||||
{
|
||||
var result = new List<KeyValuePair<String, JobContainer>>();
|
||||
|
||||
@@ -358,7 +340,7 @@ namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
|
||||
foreach (var servicePair in servicesMapping)
|
||||
{
|
||||
var networkAlias = servicePair.Key.AssertString("services key").Value;
|
||||
var container = ConvertToJobContainer(context, servicePair.Value, allowExpressions, allowServiceContainerCommand);
|
||||
var container = ConvertToJobContainer(context, servicePair.Value);
|
||||
result.Add(new KeyValuePair<String, JobContainer>(networkAlias, container));
|
||||
}
|
||||
|
||||
|
||||
@@ -51,8 +51,6 @@ namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
|
||||
|
||||
public Int32 MaxResultSize { get; set; } = 10 * 1024 * 1024; // 10 mb
|
||||
|
||||
public bool AllowServiceContainerCommand { get; set; }
|
||||
|
||||
public Boolean EvaluateStepContinueOnError(
|
||||
TemplateToken token,
|
||||
DictionaryContextData contextData,
|
||||
@@ -359,7 +357,7 @@ namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
|
||||
{
|
||||
token = TemplateEvaluator.Evaluate(context, PipelineTemplateConstants.Services, token, 0, null, omitHeader: true);
|
||||
context.Errors.Check();
|
||||
result = PipelineTemplateConverter.ConvertToJobServiceContainers(context, token, allowServiceContainerCommand: AllowServiceContainerCommand);
|
||||
result = PipelineTemplateConverter.ConvertToJobServiceContainers(context, token);
|
||||
}
|
||||
catch (Exception ex) when (!(ex is TemplateValidationException))
|
||||
{
|
||||
|
||||
@@ -430,21 +430,6 @@
|
||||
}
|
||||
},
|
||||
|
||||
"service-container-mapping": {
|
||||
"mapping": {
|
||||
"properties": {
|
||||
"image": "string",
|
||||
"options": "string",
|
||||
"entrypoint": "string",
|
||||
"command": "string",
|
||||
"env": "container-env",
|
||||
"ports": "sequence-of-non-empty-string",
|
||||
"volumes": "sequence-of-non-empty-string",
|
||||
"credentials": "container-registry-credentials"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"services": {
|
||||
"context": [
|
||||
"github",
|
||||
@@ -469,7 +454,7 @@
|
||||
],
|
||||
"one-of": [
|
||||
"string",
|
||||
"service-container-mapping"
|
||||
"container-mapping"
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
@@ -62,8 +62,6 @@ namespace GitHub.Actions.WorkflowParser.Conversion
|
||||
public const String NumberStrategyContext = "number-strategy-context";
|
||||
public const String On = "on";
|
||||
public const String Options = "options";
|
||||
public const String Entrypoint = "entrypoint";
|
||||
public const String Command = "command";
|
||||
public const String Org = "org";
|
||||
public const String Organization = "organization";
|
||||
public const String Outputs = "outputs";
|
||||
|
||||
@@ -1146,22 +1146,6 @@ namespace GitHub.Actions.WorkflowParser.Conversion
|
||||
case WorkflowTemplateConstants.Options:
|
||||
result.Options = containerPropertyPair.Value.AssertString($"{WorkflowTemplateConstants.Container} {propertyName}").Value;
|
||||
break;
|
||||
case WorkflowTemplateConstants.Entrypoint:
|
||||
if (isServiceContainer && context.GetFeatures().AllowServiceContainerCommand)
|
||||
{
|
||||
result.Entrypoint = containerPropertyPair.Value.AssertString($"{WorkflowTemplateConstants.Container} {propertyName}").Value;
|
||||
break;
|
||||
}
|
||||
propertyName.AssertUnexpectedValue($"{WorkflowTemplateConstants.Container} key");
|
||||
break;
|
||||
case WorkflowTemplateConstants.Command:
|
||||
if (isServiceContainer && context.GetFeatures().AllowServiceContainerCommand)
|
||||
{
|
||||
result.Command = containerPropertyPair.Value.AssertString($"{WorkflowTemplateConstants.Container} {propertyName}").Value;
|
||||
break;
|
||||
}
|
||||
propertyName.AssertUnexpectedValue($"{WorkflowTemplateConstants.Container} key");
|
||||
break;
|
||||
case WorkflowTemplateConstants.Ports:
|
||||
var ports = containerPropertyPair.Value.AssertSequence($"{WorkflowTemplateConstants.Container} {propertyName}");
|
||||
var portList = new List<String>(ports.Count);
|
||||
|
||||
@@ -35,24 +35,6 @@ namespace GitHub.Actions.WorkflowParser
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the container entrypoint override.
|
||||
/// </summary>
|
||||
public String Entrypoint
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the container command and args (after the image name).
|
||||
/// </summary>
|
||||
public String Command
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the volumes which are mounted into the container.
|
||||
/// </summary>
|
||||
|
||||
@@ -48,13 +48,6 @@ namespace GitHub.Actions.WorkflowParser
|
||||
[DataMember(EmitDefaultValue = false)]
|
||||
public bool StrictJsonParsing { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether service containers may specify "entrypoint" and "command".
|
||||
/// Used during parsing and evaluation.
|
||||
/// </summary>
|
||||
[DataMember(EmitDefaultValue = false)]
|
||||
public bool AllowServiceContainerCommand { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default workflow features.
|
||||
/// </summary>
|
||||
@@ -67,7 +60,6 @@ namespace GitHub.Actions.WorkflowParser
|
||||
Snapshot = false, // Default to false since this feature is still in an experimental phase
|
||||
StrictJsonParsing = false, // Default to false since this is temporary for telemetry purposes only
|
||||
AllowModelsPermission = false, // Default to false since we want this to be disabled for all non-production environments
|
||||
AllowServiceContainerCommand = false, // Default to false since this feature is gated by actions_service_container_command
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -2609,38 +2609,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"service-container-mapping": {
|
||||
"mapping": {
|
||||
"properties": {
|
||||
"image": {
|
||||
"type": "string",
|
||||
"description": "Use `jobs.<job_id>.container.image` to define the Docker image to use as the container to run the action. The value can be the Docker Hub image or a registry name."
|
||||
},
|
||||
"options": {
|
||||
"type": "string",
|
||||
"description": "Use `jobs.<job_id>.container.options` to configure additional Docker container resource options."
|
||||
},
|
||||
"entrypoint": {
|
||||
"type": "string",
|
||||
"description": "Overrides the Docker ENTRYPOINT for the service container."
|
||||
},
|
||||
"command": {
|
||||
"type": "string",
|
||||
"description": "Specifies the Docker command and arguments for the service container."
|
||||
},
|
||||
"env": "container-env",
|
||||
"ports": {
|
||||
"type": "sequence-of-non-empty-string",
|
||||
"description": "Use `jobs.<job_id>.container.ports` to set an array of ports to expose on the container."
|
||||
},
|
||||
"volumes": {
|
||||
"type": "sequence-of-non-empty-string",
|
||||
"description": "Use `jobs.<job_id>.container.volumes` to set an array of volumes for the container to use. You can use volumes to share data between services or other steps in a job. You can specify named Docker volumes, anonymous Docker volumes, or bind mounts on the host."
|
||||
},
|
||||
"credentials": "container-registry-credentials"
|
||||
}
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"description": "Additional containers to host services for a job in a workflow. These are useful for creating databases or cache services like redis. The runner on the virtual machine will automatically create a network and manage the life cycle of the service containers. When you use a service container for a job or your step uses container actions, you don't need to set port information to access the service. Docker automatically exposes all ports between containers on the same network. When both the job and the action run in a container, you can directly reference the container by its hostname. The hostname is automatically mapped to the service name. When a step does not use a container action, you must access the service using localhost and bind the ports.",
|
||||
"context": [
|
||||
@@ -2667,7 +2635,7 @@
|
||||
],
|
||||
"one-of": [
|
||||
"string",
|
||||
"service-container-mapping"
|
||||
"container-mapping"
|
||||
]
|
||||
},
|
||||
"container-registry-credentials": {
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Setup();
|
||||
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
|
||||
var token = new StringToken(null, null, null, "test-value");
|
||||
var contextData = new DictionaryContextData();
|
||||
@@ -63,7 +63,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Setup();
|
||||
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
|
||||
// Call EvaluateAndCompare directly: the new evaluator cancels the token
|
||||
// and returns a different value, forcing hasMismatch = true.
|
||||
@@ -98,7 +98,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Setup();
|
||||
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
|
||||
// Different results without cancellation — mismatch SHOULD be recorded.
|
||||
var result = wrapper.EvaluateAndCompare<string, string>(
|
||||
@@ -130,7 +130,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Setup();
|
||||
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
var token = new BooleanToken(null, null, null, true);
|
||||
var contextData = new DictionaryContextData();
|
||||
var functions = new List<LegacyExpressions.IFunctionInfo>();
|
||||
@@ -156,7 +156,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Setup();
|
||||
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
var token = new MappingToken(null, null, null);
|
||||
token.Add(new StringToken(null, null, null, "FOO"), new StringToken(null, null, null, "bar"));
|
||||
var contextData = new DictionaryContextData();
|
||||
@@ -184,7 +184,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Setup();
|
||||
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
var token = new BasicExpressionToken(null, null, null, "true");
|
||||
var contextData = new DictionaryContextData();
|
||||
var functions = new List<LegacyExpressions.IFunctionInfo>();
|
||||
@@ -211,7 +211,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Setup();
|
||||
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
var token = new MappingToken(null, null, null);
|
||||
token.Add(new StringToken(null, null, null, "input1"), new StringToken(null, null, null, "val1"));
|
||||
var contextData = new DictionaryContextData();
|
||||
@@ -239,7 +239,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Setup();
|
||||
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
var token = new NumberToken(null, null, null, 10);
|
||||
var contextData = new DictionaryContextData();
|
||||
var functions = new List<LegacyExpressions.IFunctionInfo>();
|
||||
@@ -265,7 +265,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Setup();
|
||||
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
var token = new StringToken(null, null, null, "");
|
||||
var contextData = new DictionaryContextData();
|
||||
var functions = new List<LegacyExpressions.IFunctionInfo>();
|
||||
@@ -291,7 +291,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Setup();
|
||||
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
var token = new StringToken(null, null, null, "docker://");
|
||||
var contextData = new DictionaryContextData();
|
||||
var functions = new List<LegacyExpressions.IFunctionInfo>();
|
||||
@@ -317,7 +317,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Setup();
|
||||
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
var token = new MappingToken(null, null, null);
|
||||
token.Add(new StringToken(null, null, null, "image"), new StringToken(null, null, null, "docker://"));
|
||||
var contextData = new DictionaryContextData();
|
||||
@@ -344,7 +344,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Setup();
|
||||
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
var token = new MappingToken(null, null, null);
|
||||
token.Add(new StringToken(null, null, null, "image"), new StringToken(null, null, null, ""));
|
||||
var contextData = new DictionaryContextData();
|
||||
@@ -371,7 +371,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Setup();
|
||||
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
var token = new StringToken(null, null, null, "ubuntu:latest");
|
||||
var contextData = new DictionaryContextData();
|
||||
var functions = new List<LegacyExpressions.IFunctionInfo>();
|
||||
@@ -398,7 +398,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Setup();
|
||||
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
var token = new StringToken(null, null, null, "docker://ubuntu:latest");
|
||||
var contextData = new DictionaryContextData();
|
||||
var functions = new List<LegacyExpressions.IFunctionInfo>();
|
||||
@@ -425,7 +425,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Setup();
|
||||
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
var token = new MappingToken(null, null, null);
|
||||
token.Add(new StringToken(null, null, null, "out1"), new StringToken(null, null, null, "val1"));
|
||||
var contextData = new DictionaryContextData();
|
||||
@@ -453,7 +453,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Setup();
|
||||
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
var token = new StringToken(null, null, null, "https://example.com");
|
||||
var contextData = new DictionaryContextData();
|
||||
var functions = new List<LegacyExpressions.IFunctionInfo>();
|
||||
@@ -482,7 +482,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Setup();
|
||||
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
var token = new MappingToken(null, null, null);
|
||||
token.Add(new StringToken(null, null, null, "shell"), new StringToken(null, null, null, "bash"));
|
||||
var contextData = new DictionaryContextData();
|
||||
@@ -510,7 +510,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Setup();
|
||||
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
var contextData = new DictionaryContextData();
|
||||
var functions = new List<LegacyExpressions.IFunctionInfo>();
|
||||
|
||||
@@ -542,7 +542,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
serviceMapping.Add(new StringToken(null, null, null, "image"), new StringToken(null, null, null, ""));
|
||||
servicesMapping.Add(new StringToken(null, null, null, "db"), serviceMapping);
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
var contextData = new DictionaryContextData();
|
||||
var functions = new List<LegacyExpressions.IFunctionInfo>();
|
||||
|
||||
@@ -576,7 +576,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
serviceMapping.Add(new StringToken(null, null, null, "image"), new StringToken(null, null, null, "docker://"));
|
||||
servicesMapping.Add(new StringToken(null, null, null, "db"), serviceMapping);
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
var contextData = new DictionaryContextData();
|
||||
var functions = new List<LegacyExpressions.IFunctionInfo>();
|
||||
|
||||
@@ -611,7 +611,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
serviceMapping.Add(new StringToken(null, null, null, "image"), new BasicExpressionToken(null, null, null, "''"));
|
||||
servicesMapping.Add(new StringToken(null, null, null, "db"), serviceMapping);
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
var contextData = new DictionaryContextData();
|
||||
var functions = new List<LegacyExpressions.IFunctionInfo>();
|
||||
|
||||
@@ -644,7 +644,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
serviceMapping.Add(new StringToken(null, null, null, "image"), new StringToken(null, null, null, "postgres:latest"));
|
||||
servicesMapping.Add(new StringToken(null, null, null, "db"), serviceMapping);
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
var contextData = new DictionaryContextData();
|
||||
var functions = new List<LegacyExpressions.IFunctionInfo>();
|
||||
|
||||
@@ -673,7 +673,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Setup();
|
||||
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
var contextData = new DictionaryContextData();
|
||||
var functions = new List<LegacyExpressions.IFunctionInfo>();
|
||||
|
||||
@@ -702,7 +702,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Setup();
|
||||
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
|
||||
// Both throw JsonReaderException with different messages — should be treated as equivalent
|
||||
var legacyEx = new Newtonsoft.Json.JsonReaderException("Error reading JToken from JsonReader. Path '', line 0, position 0.");
|
||||
@@ -733,7 +733,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Setup();
|
||||
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
|
||||
// Legacy throws Newtonsoft JsonReaderException, new throws System.Text.Json.JsonException
|
||||
var legacyEx = new Newtonsoft.Json.JsonReaderException("Error reading JToken");
|
||||
@@ -764,7 +764,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Setup();
|
||||
_ec.Object.Global.Variables.Set(Constants.Runner.Features.CompareWorkflowParser, "true");
|
||||
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object, allowServiceContainerCommand: false);
|
||||
var wrapper = new PipelineTemplateEvaluatorWrapper(_hc, _ec.Object);
|
||||
|
||||
// Both throw non-JSON exceptions with different messages — should record mismatch
|
||||
var legacyEx = new InvalidOperationException("some error");
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using GitHub.DistributedTask.Expressions2;
|
||||
using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
||||
using GitHub.DistributedTask.Pipelines.ContextData;
|
||||
using GitHub.DistributedTask.Pipelines.ObjectTemplating;
|
||||
using GitHub.Runner.Worker.Container;
|
||||
using Xunit;
|
||||
|
||||
namespace GitHub.Runner.Common.Tests.Worker
|
||||
{
|
||||
public sealed class ServiceContainerCommandL0
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void ServiceContainer_ParsesEntrypointAndCommand_WhenFlagOn()
|
||||
{
|
||||
var schema = PipelineTemplateSchemaFactory.GetSchema();
|
||||
var trace = new GitHub.DistributedTask.ObjectTemplating.EmptyTraceWriter();
|
||||
var evaluator = new PipelineTemplateEvaluator(trace, schema, new List<string>())
|
||||
{
|
||||
AllowServiceContainerCommand = true,
|
||||
};
|
||||
|
||||
var services = new MappingToken(null, null, null);
|
||||
var service = new MappingToken(null, null, null);
|
||||
service.Add(new StringToken(null, null, null, "image"), new StringToken(null, null, null, "postgres:latest"));
|
||||
service.Add(new StringToken(null, null, null, "entrypoint"), new StringToken(null, null, null, "/bin/bash"));
|
||||
service.Add(new StringToken(null, null, null, "command"), new StringToken(null, null, null, "-lc echo hi"));
|
||||
services.Add(new StringToken(null, null, null, "db"), service);
|
||||
|
||||
var result = evaluator.EvaluateJobServiceContainers(services, new DictionaryContextData(), new List<IFunctionInfo>());
|
||||
|
||||
Assert.NotNull(result);
|
||||
Assert.Single(result);
|
||||
Assert.Equal("db", result[0].Key);
|
||||
Assert.Equal("postgres:latest", result[0].Value.Image);
|
||||
Assert.Equal("/bin/bash", result[0].Value.Entrypoint);
|
||||
Assert.Equal("-lc echo hi", result[0].Value.Command);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void ServiceContainer_RejectsEntrypointAndCommand_WhenFlagOff()
|
||||
{
|
||||
var schema = PipelineTemplateSchemaFactory.GetSchema();
|
||||
var trace = new GitHub.DistributedTask.ObjectTemplating.EmptyTraceWriter();
|
||||
var evaluator = new PipelineTemplateEvaluator(trace, schema, new List<string>());
|
||||
|
||||
var services = new MappingToken(null, null, null);
|
||||
var service = new MappingToken(null, null, null);
|
||||
service.Add(new StringToken(null, null, null, "image"), new StringToken(null, null, null, "postgres:latest"));
|
||||
service.Add(new StringToken(null, null, null, "entrypoint"), new StringToken(null, null, null, "/bin/bash"));
|
||||
services.Add(new StringToken(null, null, null, "db"), service);
|
||||
|
||||
Assert.Throws<GitHub.DistributedTask.ObjectTemplating.TemplateValidationException>(() =>
|
||||
evaluator.EvaluateJobServiceContainers(services, new DictionaryContextData(), new List<IFunctionInfo>()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void ContainerInfo_MapsEntrypointAndCommand_FromJobContainer()
|
||||
{
|
||||
using var hc = new TestHostContext(this);
|
||||
var jc = new GitHub.DistributedTask.Pipelines.JobContainer
|
||||
{
|
||||
Image = "postgres:latest",
|
||||
Entrypoint = "/bin/bash",
|
||||
Command = "-lc echo hi",
|
||||
};
|
||||
|
||||
var info = new ContainerInfo(hc, jc, isJobContainer: false, networkAlias: "db");
|
||||
|
||||
Assert.Equal("/bin/bash", info.ContainerEntryPoint);
|
||||
Assert.Equal("-lc echo hi", info.ContainerEntryPointArgs);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void ContainerInfo_IgnoresNullEntrypointAndCommand()
|
||||
{
|
||||
using var hc = new TestHostContext(this);
|
||||
var jc = new GitHub.DistributedTask.Pipelines.JobContainer
|
||||
{
|
||||
Image = "postgres:latest",
|
||||
};
|
||||
|
||||
var info = new ContainerInfo(hc, jc, isJobContainer: false, networkAlias: "db");
|
||||
|
||||
Assert.Null(info.ContainerEntryPoint);
|
||||
Assert.Null(info.ContainerEntryPointArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user