Skip to content

Commit

Permalink
Fix issues for composite actions (Run Service flow)
Browse files Browse the repository at this point in the history
  • Loading branch information
ericsciple committed Aug 30, 2024
1 parent 99b464e commit deade9c
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 7 deletions.
15 changes: 9 additions & 6 deletions src/Runner.Worker/ExecutionContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public interface IExecutionContext : IRunnerService
// Initialize
void InitializeJob(Pipelines.AgentJobRequestMessage message, CancellationToken token);
void CancelToken();
IExecutionContext CreateChild(Guid recordId, string displayName, string refName, string scopeName, string contextName, ActionRunStage stage, Dictionary<string, string> intraActionState = null, int? recordOrder = null, IPagingLogger logger = null, bool isEmbedded = false, CancellationTokenSource cancellationTokenSource = null, Guid embeddedId = default(Guid), string siblingScopeName = null, TimeSpan? timeout = null);
IExecutionContext CreateChild(Guid recordId, string displayName, string refName, string scopeName, string contextName, ActionRunStage stage, Dictionary<string, string> intraActionState = null, int? recordOrder = null, IPagingLogger logger = null, bool isEmbedded = false, List<Issue> embeddedIssueCollector = null, CancellationTokenSource cancellationTokenSource = null, Guid embeddedId = default(Guid), string siblingScopeName = null, TimeSpan? timeout = null);
IExecutionContext CreateEmbeddedChild(string scopeName, string contextName, Guid embeddedId, ActionRunStage stage, Dictionary<string, string> intraActionState = null, string siblingScopeName = null);

// logging
Expand Down Expand Up @@ -135,7 +135,6 @@ public sealed class ExecutionContext : RunnerService, IExecutionContext

private readonly TimelineRecord _record = new();
private readonly Dictionary<Guid, TimelineRecord> _detailRecords = new();
private readonly List<Issue> _embeddedIssueCollector;
private readonly object _loggerLock = new();
private readonly object _matchersLock = new();
private readonly ExecutionContext _parentExecutionContext;
Expand All @@ -154,6 +153,7 @@ public sealed class ExecutionContext : RunnerService, IExecutionContext
private CancellationTokenSource _cancellationTokenSource;
private TaskCompletionSource<int> _forceCompleted = new();
private bool _throttlingReported = false;
private List<Issue> _embeddedIssueCollector;

// only job level ExecutionContext will track throttling delay.
private long _totalThrottlingDelayInMilliseconds = 0;
Expand Down Expand Up @@ -356,6 +356,7 @@ public IExecutionContext CreateChild(
int? recordOrder = null,
IPagingLogger logger = null,
bool isEmbedded = false,
List<Issue> embeddedIssueCollector = null,
CancellationTokenSource cancellationTokenSource = null,
Guid embeddedId = default(Guid),
string siblingScopeName = null,
Expand All @@ -365,6 +366,10 @@ public IExecutionContext CreateChild(

var child = new ExecutionContext(this, isEmbedded);
child.Initialize(HostContext);
if ((Global.Variables.GetBoolean("RunService.FixEmbeddedIssues") ?? false) && embeddedIssueCollector != null)
{
child._embeddedIssueCollector = embeddedIssueCollector;
}
child.Global = Global;
child.ScopeName = scopeName;
child.ContextName = contextName;
Expand Down Expand Up @@ -433,7 +438,7 @@ public IExecutionContext CreateEmbeddedChild(
Dictionary<string, string> intraActionState = null,
string siblingScopeName = null)
{
return Root.CreateChild(_record.Id, _record.Name, _record.Id.ToString("N"), scopeName, contextName, stage, logger: _logger, isEmbedded: true, cancellationTokenSource: null, intraActionState: intraActionState, embeddedId: embeddedId, siblingScopeName: siblingScopeName, timeout: GetRemainingTimeout(), recordOrder: _record.Order);
return Root.CreateChild(_record.Id, _record.Name, _record.Id.ToString("N"), scopeName, contextName, stage, logger: _logger, isEmbedded: true, embeddedIssueCollector: _embeddedIssueCollector, cancellationTokenSource: null, intraActionState: intraActionState, embeddedId: embeddedId, siblingScopeName: siblingScopeName, timeout: GetRemainingTimeout(), recordOrder: _record.Order);
}

public void Start(string currentOperation = null)
Expand Down Expand Up @@ -520,7 +525,6 @@ public TaskResult Complete(TaskResult? result = null, string currentOperation =
Global.StepsResult.Add(stepResult);
}


if (Root != this)
{
// only dispose TokenSource for step level ExecutionContext
Expand Down Expand Up @@ -837,7 +841,6 @@ public void InitializeJob(Pipelines.AgentJobRequestMessage message, Cancellation
// Actions environment
ActionsEnvironment = message.ActionsEnvironment;


// Service container info
Global.ServiceContainers = new List<ContainerInfo>();

Expand Down Expand Up @@ -1418,7 +1421,7 @@ private static void ResolvePathsInExpressionValuesDictionary(this IExecutionCont
{
if (key == PipelineTemplateConstants.HostWorkspace)
{
// The HostWorkspace context var is excluded so that there is a var that always points to the host path.
// The HostWorkspace context var is excluded so that there is a var that always points to the host path.
// This var can be used to translate back from container paths, e.g. in HashFilesFunction, which always runs on the host machine
continue;
}
Expand Down
78 changes: 77 additions & 1 deletion src/Test/L0/Worker/ExecutionContextL0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,82 @@ public void PublishStepTelemetry_EmbeddedStep()
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public void PublishStepResult_EmbeddedStep()
{
using (TestHostContext hc = CreateTestContext())
{
// Job request
TaskOrchestrationPlanReference plan = new();
TimelineReference timeline = new();
Guid jobId = Guid.NewGuid();
string jobName = "some job name";
var variables = new Dictionary<string, VariableValue>()
{
["RunService.FixEmbeddedIssues"] = new VariableValue("true"),
};
var jobRequest = new Pipelines.AgentJobRequestMessage(plan, timeline, jobId, jobName, jobName, null, null, null, variables, new List<MaskHint>(), new Pipelines.JobResources(), new Pipelines.ContextData.DictionaryContextData(), new Pipelines.WorkspaceOptions(), new List<Pipelines.ActionStep>(), null, null, null, null, null);
jobRequest.Resources.Repositories.Add(new Pipelines.RepositoryResource()
{
Alias = Pipelines.PipelineConstants.SelfAlias,
Id = "github",
Version = "sha1"
});
jobRequest.ContextData["github"] = new Pipelines.ContextData.DictionaryContextData();

// Mocks
var pagingLogger = new Mock<IPagingLogger>();
var pagingLogger2 = new Mock<IPagingLogger>();
var jobServerQueue = new Mock<IJobServerQueue>();
jobServerQueue.Setup(x => x.QueueTimelineRecordUpdate(It.IsAny<Guid>(), It.IsAny<TimelineRecord>()));
hc.EnqueueInstance(pagingLogger.Object);
hc.EnqueueInstance(pagingLogger2.Object);
hc.SetSingleton(jobServerQueue.Object);

// Job context
var jobContext = new Runner.Worker.ExecutionContext();
jobContext.Initialize(hc);
jobContext.InitializeJob(jobRequest, CancellationToken.None);
jobContext.Start();

// Step 1 context
var step1 = jobContext.CreateChild(Guid.NewGuid(), "my_step", "my_step", null, null, ActionRunStage.Main);
step1.Start();

// Embedded step 1a context
var embeddedStep1a = step1.CreateEmbeddedChild(null, null, Guid.NewGuid(), ActionRunStage.Main);
embeddedStep1a.Start();
embeddedStep1a.StepTelemetry.Type = "node16";
embeddedStep1a.StepTelemetry.Action = "actions/checkout";
embeddedStep1a.StepTelemetry.Ref = "v2";
embeddedStep1a.AddIssue(new Issue() { Type = IssueType.Error, Message = "error" }, ExecutionContextLogOptions.Default);
embeddedStep1a.AddIssue(new Issue() { Type = IssueType.Warning, Message = "warning" }, ExecutionContextLogOptions.Default);
embeddedStep1a.AddIssue(new Issue() { Type = IssueType.Notice, Message = "notice" }, ExecutionContextLogOptions.Default);
embeddedStep1a.Complete();

// Embedded step 1b context
var embeddedStep1b = step1.CreateEmbeddedChild(null, null, Guid.NewGuid(), ActionRunStage.Main);
embeddedStep1b.Start();
embeddedStep1b.StepTelemetry.Type = "node16";
embeddedStep1b.StepTelemetry.Action = "actions/checkout";
embeddedStep1b.StepTelemetry.Ref = "v2";
embeddedStep1b.AddIssue(new Issue() { Type = IssueType.Error, Message = "error 2" }, ExecutionContextLogOptions.Default);
embeddedStep1b.AddIssue(new Issue() { Type = IssueType.Warning, Message = "warning 2" }, ExecutionContextLogOptions.Default);
embeddedStep1b.AddIssue(new Issue() { Type = IssueType.Notice, Message = "notice 2" }, ExecutionContextLogOptions.Default);
embeddedStep1b.Complete();

step1.Complete();

// Assert
Assert.Equal(3, jobContext.Global.StepsResult.Count);
Assert.Equal(0, jobContext.Global.StepsResult[0].Annotations.Count);
Assert.Equal(0, jobContext.Global.StepsResult[1].Annotations.Count);
Assert.Equal(6, jobContext.Global.StepsResult[2].Annotations.Count);
}
}

[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public void PublishStepResult_EmbeddedStep_Legacy()
{
using (TestHostContext hc = CreateTestContext())
{
Expand Down Expand Up @@ -807,7 +883,7 @@ public void PublishStepResult_EmbeddedStep()
ec.InitializeJob(jobRequest, CancellationToken.None);
ec.Start();

var embeddedStep = ec.CreateChild(Guid.NewGuid(), "action_1_pre", "action_1_pre", null, null, ActionRunStage.Main, isEmbedded: true);
var embeddedStep = ec.CreateEmbeddedChild(null, null, Guid.NewGuid(), ActionRunStage.Main);
embeddedStep.Start();

embeddedStep.StepTelemetry.Type = "node16";
Expand Down

0 comments on commit deade9c

Please sign in to comment.