Skip to content

Commit e930403

Browse files
committed
Set composite step's action_status when job is cancelled
Also make composite step inherit timeout from parent
1 parent 7d432fb commit e930403

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

src/Runner.Worker/ExecutionContext.cs

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ public interface IExecutionContext : IRunnerService
7878
List<string> StepEnvironmentOverrides { get; }
7979

8080
ExecutionContext Root { get; }
81+
ExecutionContext Parent { get; }
8182

8283
// Initialize
8384
void InitializeJob(Pipelines.AgentJobRequestMessage message, CancellationToken token);
@@ -264,6 +265,14 @@ public ExecutionContext Root
264265
}
265266
}
266267

268+
public ExecutionContext Parent
269+
{
270+
get
271+
{
272+
return _parentExecutionContext;
273+
}
274+
}
275+
267276
public JobContext JobContext
268277
{
269278
get
@@ -406,7 +415,7 @@ public IExecutionContext CreateChild(
406415

407416
/// <summary>
408417
/// An embedded execution context shares the same record ID, record name, logger,
409-
/// and a linked cancellation token.
418+
/// but NOT the cancellation token (just like workflow steps contexts - they don't share a token)
410419
/// </summary>
411420
public IExecutionContext CreateEmbeddedChild(
412421
string scopeName,
@@ -416,7 +425,7 @@ public IExecutionContext CreateEmbeddedChild(
416425
Dictionary<string, string> intraActionState = null,
417426
string siblingScopeName = null)
418427
{
419-
return Root.CreateChild(_record.Id, _record.Name, _record.Id.ToString("N"), scopeName, contextName, stage, logger: _logger, isEmbedded: true, cancellationTokenSource: CancellationTokenSource.CreateLinkedTokenSource(_cancellationTokenSource.Token), intraActionState: intraActionState, embeddedId: embeddedId, siblingScopeName: siblingScopeName);
428+
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);
420429
}
421430

422431
public void Start(string currentOperation = null)
@@ -597,7 +606,31 @@ public void SetTimeout(TimeSpan? timeout)
597606
if (timeout != null)
598607
{
599608
_cancellationTokenSource.CancelAfter(timeout.Value);
609+
m_timeoutStartedAt = DateTime.UtcNow;
610+
m_timeout = timeout.Value;
611+
}
612+
}
613+
614+
DateTime? m_timeoutStartedAt;
615+
TimeSpan? m_timeout;
616+
public TimeSpan? GetRemainingTimeout()
617+
{
618+
if (m_timeoutStartedAt != null && m_timeout != null)
619+
{
620+
var elapsedSinceTimeoutSet = DateTime.UtcNow - m_timeoutStartedAt.Value;
621+
var remainingTimeout = m_timeout.Value - elapsedSinceTimeoutSet;
622+
if (remainingTimeout.Ticks > 0)
623+
{
624+
return remainingTimeout;
625+
}
626+
else
627+
{
628+
// there was a timeout and it has expired
629+
return TimeSpan.Zero;
630+
}
600631
}
632+
// no timeout was ever set
633+
return null;
601634
}
602635

603636
public void Progress(int percentage, string currentOperation = null)
@@ -1453,4 +1486,4 @@ public static class WellKnownTags
14531486
public static readonly string Notice = "##[notice]";
14541487
public static readonly string Debug = "##[debug]";
14551488
}
1456-
}
1489+
}

src/Runner.Worker/Handlers/CompositeActionHandler.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ private async Task RunStepsAsync(List<IStep> embeddedSteps, ActionRunStage stage
310310
// Mark job as cancelled
311311
ExecutionContext.Root.Result = TaskResult.Canceled;
312312
ExecutionContext.Root.JobContext.Status = ExecutionContext.Root.Result?.ToActionResult();
313+
step.ExecutionContext.SetGitHubContext("action_status", (ExecutionContext.Root.Result?.ToActionResult() ?? ActionResult.Cancelled).ToString().ToLowerInvariant());
313314

314315
step.ExecutionContext.Debug($"Re-evaluate condition on job cancellation for step: '{step.DisplayName}'.");
315316
var conditionReTestTraceWriter = new ConditionTraceWriter(Trace, null); // host tracing only
@@ -420,6 +421,8 @@ private async Task RunStepAsync(IStep step)
420421
{
421422
Trace.Info($"Starting: {step.DisplayName}");
422423
step.ExecutionContext.Debug($"Starting: {step.DisplayName}");
424+
// composite steps inherit the timeout from the parent, set by https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepstimeout-minutes
425+
step.ExecutionContext.SetTimeout(step.ExecutionContext.Parent.GetRemainingTimeout());
423426

424427
await Common.Util.EncodingUtil.SetEncoding(HostContext, Trace, step.ExecutionContext.CancellationToken);
425428

0 commit comments

Comments
 (0)