Skip to content

Commit 94e3855

Browse files
committed
Add telemetry tracking for deprecated set-output and save-state commands
- Add HasDeprecatedSetOutputCommand and HasDeprecatedSaveStateCommand flags to GlobalContext - Emit JobTelemetry once per job when deprecated commands are used - Add unit tests verifying once-per-job telemetry behavior
1 parent 3ffedab commit 94e3855

File tree

3 files changed

+74
-0
lines changed

3 files changed

+74
-0
lines changed

src/Runner.Worker/ActionCommandManager.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,17 @@ public void ProcessCommand(IExecutionContext context, string line, ActionCommand
318318
context.AddIssue(issue, ExecutionContextLogOptions.Default);
319319
}
320320

321+
if (!context.Global.HasDeprecatedSetOutputCommand)
322+
{
323+
context.Global.HasDeprecatedSetOutputCommand = true;
324+
var telemetry = new JobTelemetry
325+
{
326+
Type = JobTelemetryType.ActionCommand,
327+
Message = "DeprecatedCommand: set-output"
328+
};
329+
context.Global.JobTelemetry.Add(telemetry);
330+
}
331+
321332
if (!command.Properties.TryGetValue(SetOutputCommandProperties.Name, out string outputName) || string.IsNullOrEmpty(outputName))
322333
{
323334
throw new Exception("Required field 'name' is missing in ##[set-output] command.");
@@ -353,6 +364,17 @@ public void ProcessCommand(IExecutionContext context, string line, ActionCommand
353364
context.AddIssue(issue, ExecutionContextLogOptions.Default);
354365
}
355366

367+
if (!context.Global.HasDeprecatedSaveStateCommand)
368+
{
369+
context.Global.HasDeprecatedSaveStateCommand = true;
370+
var telemetry = new JobTelemetry
371+
{
372+
Type = JobTelemetryType.ActionCommand,
373+
Message = "DeprecatedCommand: save-state"
374+
};
375+
context.Global.JobTelemetry.Add(telemetry);
376+
}
377+
356378
if (!command.Properties.TryGetValue(SaveStateCommandProperties.Name, out string stateName) || string.IsNullOrEmpty(stateName))
357379
{
358380
throw new Exception("Required field 'name' is missing in ##[save-state] command.");

src/Runner.Worker/GlobalContext.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,7 @@ public sealed class GlobalContext
3131
public JObject ContainerHookState { get; set; }
3232
public bool HasTemplateEvaluatorMismatch { get; set; }
3333
public bool HasActionManifestMismatch { get; set; }
34+
public bool HasDeprecatedSetOutputCommand { get; set; }
35+
public bool HasDeprecatedSaveStateCommand { get; set; }
3436
}
3537
}

src/Test/L0/Worker/ActionCommandManagerL0.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,8 @@ private TestHostContext CreateTestContext([CallerMemberName] string testName = "
457457
new SetEnvCommandExtension(),
458458
new WarningCommandExtension(),
459459
new AddMaskCommandExtension(),
460+
new SetOutputCommandExtension(),
461+
new SaveStateCommandExtension(),
460462
};
461463
foreach (var command in commands)
462464
{
@@ -499,5 +501,53 @@ private DictionaryContextData GetExpressionValues()
499501
};
500502
}
501503

504+
[Fact]
505+
[Trait("Level", "L0")]
506+
[Trait("Category", "Worker")]
507+
public void SetOutputCommand_EmitsTelemetryOnce()
508+
{
509+
using (TestHostContext hc = CreateTestContext())
510+
{
511+
_ec.Object.Global.JobTelemetry = new List<JobTelemetry>();
512+
var reference = string.Empty;
513+
_ec.Setup(x => x.SetOutput(It.IsAny<string>(), It.IsAny<string>(), out reference));
514+
515+
// First set-output should add telemetry
516+
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "::set-output name=foo::bar", null));
517+
Assert.Single(_ec.Object.Global.JobTelemetry);
518+
Assert.Equal(JobTelemetryType.ActionCommand, _ec.Object.Global.JobTelemetry[0].Type);
519+
Assert.Equal("DeprecatedCommand: set-output", _ec.Object.Global.JobTelemetry[0].Message);
520+
Assert.True(_ec.Object.Global.HasDeprecatedSetOutputCommand);
521+
522+
// Second set-output should not add another telemetry entry
523+
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "::set-output name=foo2::bar2", null));
524+
Assert.Single(_ec.Object.Global.JobTelemetry);
525+
}
526+
}
527+
528+
[Fact]
529+
[Trait("Level", "L0")]
530+
[Trait("Category", "Worker")]
531+
public void SaveStateCommand_EmitsTelemetryOnce()
532+
{
533+
using (TestHostContext hc = CreateTestContext())
534+
{
535+
_ec.Object.Global.JobTelemetry = new List<JobTelemetry>();
536+
_ec.Setup(x => x.IsEmbedded).Returns(false);
537+
_ec.Setup(x => x.IntraActionState).Returns(new Dictionary<string, string>());
538+
539+
// First save-state should add telemetry
540+
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "::save-state name=foo::bar", null));
541+
Assert.Single(_ec.Object.Global.JobTelemetry);
542+
Assert.Equal(JobTelemetryType.ActionCommand, _ec.Object.Global.JobTelemetry[0].Type);
543+
Assert.Equal("DeprecatedCommand: save-state", _ec.Object.Global.JobTelemetry[0].Message);
544+
Assert.True(_ec.Object.Global.HasDeprecatedSaveStateCommand);
545+
546+
// Second save-state should not add another telemetry entry
547+
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "::save-state name=foo2::bar2", null));
548+
Assert.Single(_ec.Object.Global.JobTelemetry);
549+
}
550+
}
551+
502552
}
503553
}

0 commit comments

Comments
 (0)