From 1c4d4f692fc84690e8e255c94b1dfa93bb1ce88e Mon Sep 17 00:00:00 2001 From: Platform Engineering Bot Date: Thu, 2 Jul 2026 00:24:28 +0000 Subject: [PATCH] =?UTF-8?q?Update=20patches:=20c814d7c=20=E2=86=92=204c6d8?= =?UTF-8?q?5cf=20[ppc64le,s390x]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- patches/last_processed_commit.txt | 2 +- patches/runner-main-sdk8-ppc64le.patch | 4 +- patches/runner-main-sdk8-s390x.patch | 4 +- src/Misc/externals.sh | 2 +- src/Runner.Worker/ActionManager.cs | 109 +++++++++++++++++++++++-- src/Test/L0/Worker/ActionManagerL0.cs | 65 +++++++++++++++ 6 files changed, 174 insertions(+), 12 deletions(-) diff --git a/patches/last_processed_commit.txt b/patches/last_processed_commit.txt index e573e42dc10..4bd8cc74b6e 100644 --- a/patches/last_processed_commit.txt +++ b/patches/last_processed_commit.txt @@ -1 +1 @@ -c814d7ca46f403a860f84c4e54b78c5a2d17e045 +4c6d85cfc08ee95c04bf0d7f7756eede55ac5713 diff --git a/patches/runner-main-sdk8-ppc64le.patch b/patches/runner-main-sdk8-ppc64le.patch index a8bfc6b6c96..d41a15dbb77 100644 --- a/patches/runner-main-sdk8-ppc64le.patch +++ b/patches/runner-main-sdk8-ppc64le.patch @@ -16,7 +16,7 @@ index 9c069b12..d26b0dc2 100644 diff --git a/src/Misc/externals.sh b/src/Misc/externals.sh -index 46384bb4..fc2a9456 100755 +index 4947a9bd..8103a2db 100755 --- a/src/Misc/externals.sh +++ b/src/Misc/externals.sh @@ -187,3 +187,13 @@ fi @@ -284,4 +284,4 @@ index 056a312e..3f9a3679 100644 -# From upstream commit: c814d7ca46f403a860f84c4e54b78c5a2d17e045 +# From upstream commit: 4c6d85cfc08ee95c04bf0d7f7756eede55ac5713 diff --git a/patches/runner-main-sdk8-s390x.patch b/patches/runner-main-sdk8-s390x.patch index a8bfc6b6c96..d41a15dbb77 100644 --- a/patches/runner-main-sdk8-s390x.patch +++ b/patches/runner-main-sdk8-s390x.patch @@ -16,7 +16,7 @@ index 9c069b12..d26b0dc2 100644 diff --git a/src/Misc/externals.sh b/src/Misc/externals.sh -index 46384bb4..fc2a9456 100755 +index 4947a9bd..8103a2db 100755 --- a/src/Misc/externals.sh +++ b/src/Misc/externals.sh @@ -187,3 +187,13 @@ fi @@ -284,4 +284,4 @@ index 056a312e..3f9a3679 100644 -# From upstream commit: c814d7ca46f403a860f84c4e54b78c5a2d17e045 +# From upstream commit: 4c6d85cfc08ee95c04bf0d7f7756eede55ac5713 diff --git a/src/Misc/externals.sh b/src/Misc/externals.sh index 46384bb4845..4947a9bd43c 100755 --- a/src/Misc/externals.sh +++ b/src/Misc/externals.sh @@ -7,7 +7,7 @@ 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. # Follow the instructions here: https://github.com/actions/alpine_nodejs?tab=readme-ov-file#getting-started NODE20_VERSION="20.20.2" -NODE24_VERSION="24.17.0" +NODE24_VERSION="24.18.0" get_abs_path() { # exploits the fact that pwd will print abs path when no args diff --git a/src/Runner.Worker/ActionManager.cs b/src/Runner.Worker/ActionManager.cs index dea9e7dc032..49f9d3e739e 100644 --- a/src/Runner.Worker/ActionManager.cs +++ b/src/Runner.Worker/ActionManager.cs @@ -228,7 +228,30 @@ public sealed class ActionManager : RunnerService, IActionManager { throw new Exception($"Missing download info for {lookupKey}"); } - await DownloadRepositoryActionAsync(executionContext, downloadInfo); + + Exception downloadFailure = null; + try + { + await DownloadRepositoryActionAsync(executionContext, downloadInfo); + } + catch (Exception ex) + { + // record the exception for telemetry, and rethrow the original exception to fail the step. + downloadFailure = ex; + throw; + } + finally + { + executionContext.Global.JobTelemetry.Add(new JobTelemetry() + { + Type = JobTelemetryType.General, + Message = $"resolve_download_actions_telemetry:{StringUtil.ConvertToJson(new ActionTelemetryPayload + { + Operation = "download_action", + Result = downloadFailure == null ? "succeeded" : downloadFailure.GetType().Name + }, Newtonsoft.Json.Formatting.None)}" + }); + } } // Parse action.yml and collect composite sub-actions for batched @@ -398,7 +421,30 @@ public sealed class ActionManager : RunnerService, IActionManager if (repositoryActions.Count > 0) { // Get the download info - var downloadInfos = await GetDownloadInfoAsync(executionContext, repositoryActions); + IDictionary downloadInfos = null; + Exception resolveFailure = null; + try + { + downloadInfos = await GetDownloadInfoAsync(executionContext, repositoryActions); + } + catch (Exception ex) + { + // record the exception for telemetry, and rethrow the original exception to fail the step. + resolveFailure = ex; + throw; + } + finally + { + executionContext.Global.JobTelemetry.Add(new JobTelemetry() + { + Type = JobTelemetryType.General, + Message = $"resolve_download_actions_telemetry:{StringUtil.ConvertToJson(new ActionTelemetryPayload + { + Operation = "resolve_actions", + Result = resolveFailure == null ? "succeeded" : resolveFailure.GetType().Name + }, Newtonsoft.Json.Formatting.None)}" + }); + } // Download each action foreach (var action in repositoryActions) @@ -414,7 +460,29 @@ public sealed class ActionManager : RunnerService, IActionManager throw new Exception($"Missing download info for {lookupKey}"); } - await DownloadRepositoryActionAsync(executionContext, downloadInfo); + Exception downloadFailure = null; + try + { + await DownloadRepositoryActionAsync(executionContext, downloadInfo); + } + catch (Exception ex) + { + // record the exception for telemetry, and rethrow the original exception to fail the step. + downloadFailure = ex; + throw; + } + finally + { + executionContext.Global.JobTelemetry.Add(new JobTelemetry() + { + Type = JobTelemetryType.General, + Message = $"resolve_download_actions_telemetry:{StringUtil.ConvertToJson(new ActionTelemetryPayload + { + Operation = "download_action", + Result = downloadFailure == null ? "succeeded" : downloadFailure.GetType().Name + }, Newtonsoft.Json.Formatting.None)}" + }); + } } // More preparation based on content in the repository (action.yml) @@ -980,10 +1048,33 @@ private async Task ResolveNewActionsAsync(IExecutionContext executionContext, Li if (actionsToResolve.Count > 0) { - var downloadInfos = await GetDownloadInfoAsync(executionContext, actionsToResolve); - foreach (var kvp in downloadInfos) + IDictionary downloadInfos = null; + Exception resolveFailure = null; + try { - resolvedDownloadInfos[kvp.Key] = kvp.Value; + downloadInfos = await GetDownloadInfoAsync(executionContext, actionsToResolve); + foreach (var kvp in downloadInfos) + { + resolvedDownloadInfos[kvp.Key] = kvp.Value; + } + } + catch (Exception ex) + { + // record the exception for telemetry, and rethrow the original exception to fail the step. + resolveFailure = ex; + throw; + } + finally + { + executionContext.Global.JobTelemetry.Add(new JobTelemetry() + { + Type = JobTelemetryType.General, + Message = $"resolve_download_actions_telemetry:{StringUtil.ConvertToJson(new ActionTelemetryPayload + { + Operation = "resolve_actions", + Result = resolveFailure == null ? "succeeded" : resolveFailure.GetType().Name + }, Newtonsoft.Json.Formatting.None)}" + }); } } } @@ -1209,6 +1300,12 @@ private async Task DownloadRepositoryActionAsync(IExecutionContext executionCont private string GetWatermarkFilePath(string directory) => directory + ".completed"; + private sealed class ActionTelemetryPayload + { + public string Operation { get; set; } + public string Result { get; set; } + } + private ActionSetupInfo PrepareRepositoryActionAsync(IExecutionContext executionContext, Pipelines.ActionStep repositoryAction) { var repositoryReference = repositoryAction.Reference as Pipelines.RepositoryPathReference; diff --git a/src/Test/L0/Worker/ActionManagerL0.cs b/src/Test/L0/Worker/ActionManagerL0.cs index c612ac9d0fa..05c69845a4f 100644 --- a/src/Test/L0/Worker/ActionManagerL0.cs +++ b/src/Test/L0/Worker/ActionManagerL0.cs @@ -90,6 +90,11 @@ public async void PrepareActions_DownloadActionFromDotCom_OnPremises_Legacy() var actionYamlFile = Path.Combine(_hc.GetDirectory(WellKnownDirectory.Actions), ActionName, "main", "action.yml"); Assert.True(File.Exists(actionYamlFile)); + + var telemetryMessages = GetTelemetryMessages(); + Assert.True(ContainsTelemetry(telemetryMessages, "resolve_actions")); + Assert.True(ContainsTelemetry(telemetryMessages, "succeeded")); + Assert.True(ContainsTelemetry(telemetryMessages, "download_action")); _hc.GetTrace().Info(File.ReadAllText(actionYamlFile)); } finally @@ -148,6 +153,11 @@ public async void PrepareActions_DownloadActionFromDotCom_ZipFileError() // Act + Assert await Assert.ThrowsAsync(async () => await _actionManager.PrepareActionsAsync(_ec.Object, actions)); + + var telemetryMessages = GetTelemetryMessages(); + Assert.True(ContainsTelemetry(telemetryMessages, "resolve_actions")); + Assert.True(ContainsTelemetry(telemetryMessages, "download_action")); + Assert.True(ContainsTelemetry(telemetryMessages, "InvalidActionArchiveException")); } finally { @@ -215,6 +225,51 @@ public async void PrepareActions_DownloadUnknownActionFromGraph_OnPremises_Legac } } + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Worker")] + public async Task PrepareActions_ResolveActionDownloadInfo_RecordsTelemetry_OnFailure() + { + try + { + // Arrange + Setup(); + _ec.Object.Global.Variables.Set(Constants.Variables.System.JobRequestType, "RunnerJobRequest"); + + _launchServer + .Setup(x => x.ResolveActionsDownloadInfoAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .ThrowsAsync(new Exception("resolve failed")); + + var actions = new List + { + new Pipelines.ActionStep() + { + Name = "action", + Id = Guid.NewGuid(), + Reference = new Pipelines.RepositoryPathReference() + { + Name = "actions/checkout", + Ref = "v4", + RepositoryType = "GitHub" + } + } + }; + + // Act + Assert + await Assert.ThrowsAsync(async () => await _actionManager.PrepareActionsAsync(_ec.Object, actions)); + + var telemetryMessages = GetTelemetryMessages(); + Assert.Equal(1, telemetryMessages.Count(message => + message.Contains("resolve_actions", StringComparison.OrdinalIgnoreCase) + && !message.Contains("\"result\":\"succeeded\"", StringComparison.OrdinalIgnoreCase))); + Assert.False(ContainsTelemetry(telemetryMessages, "resolve_actions\",\"result\":\"succeeded")); + } + finally + { + Teardown(); + } + } + #if OS_LINUX [Fact] [Trait("Level", "L0")] @@ -3333,6 +3388,16 @@ private void Teardown() } } + private IList GetTelemetryMessages() + { + return _ec.Object.Global.JobTelemetry.Select(x => x.Message).ToList(); + } + + private static bool ContainsTelemetry(IList telemetryMessages, string expectedFragment) + { + return telemetryMessages.Any(message => message.Contains(expectedFragment, StringComparison.OrdinalIgnoreCase)); + } + [Fact] [Trait("Level", "L0")] [Trait("Category", "Worker")]