From 3a80a78cae14dd3e2603ab728ac85674ec80d086 Mon Sep 17 00:00:00 2001 From: eric sciple Date: Fri, 30 Jan 2026 09:24:06 -0600 Subject: [PATCH] Fix local action display name showing `Run /./` instead of `Run ./` (#4218) --- src/Runner.Worker/ActionRunner.cs | 9 ++- src/Test/L0/Worker/ActionRunnerL0.cs | 90 +++++++++++++++++++++++++++- 2 files changed, 97 insertions(+), 2 deletions(-) diff --git a/src/Runner.Worker/ActionRunner.cs b/src/Runner.Worker/ActionRunner.cs index da967468a..4c84c1942 100644 --- a/src/Runner.Worker/ActionRunner.cs +++ b/src/Runner.Worker/ActionRunner.cs @@ -379,7 +379,14 @@ namespace GitHub.Runner.Worker { prefix = PipelineTemplateConstants.RunDisplayPrefix; var repositoryReference = action.Reference as RepositoryPathReference; - var pathString = string.IsNullOrEmpty(repositoryReference.Path) ? string.Empty : $"/{repositoryReference.Path}"; + var pathString = string.Empty; + if (!string.IsNullOrEmpty(repositoryReference.Path)) + { + // For local actions (Name is empty), don't prepend "/" to avoid "/./" + pathString = string.IsNullOrEmpty(repositoryReference.Name) + ? repositoryReference.Path + : $"/{repositoryReference.Path}"; + } var repoString = string.IsNullOrEmpty(repositoryReference.Ref) ? $"{repositoryReference.Name}{pathString}" : $"{repositoryReference.Name}{pathString}@{repositoryReference.Ref}"; tokenToParse = new StringToken(null, null, null, repoString); diff --git a/src/Test/L0/Worker/ActionRunnerL0.cs b/src/Test/L0/Worker/ActionRunnerL0.cs index 8186e25b6..2c1bd46bc 100644 --- a/src/Test/L0/Worker/ActionRunnerL0.cs +++ b/src/Test/L0/Worker/ActionRunnerL0.cs @@ -316,6 +316,94 @@ namespace GitHub.Runner.Common.Tests.Worker Assert.Equal("${{ matrix.node }}", _actionRunner.DisplayName); } + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Worker")] + public void EvaluateDisplayNameForLocalAction() + { + // Arrange + Setup(); + var actionId = Guid.NewGuid(); + var action = new Pipelines.ActionStep() + { + Name = "action", + Id = actionId, + Reference = new Pipelines.RepositoryPathReference() + { + RepositoryType = Pipelines.PipelineConstants.SelfAlias, + Path = "./" + } + }; + _actionRunner.Action = action; + + // Act + var validDisplayName = _actionRunner.EvaluateDisplayName(_context, _actionRunner.ExecutionContext, out bool updated); + + // Assert + Assert.True(validDisplayName); + Assert.True(updated); + Assert.Equal("Run ./", _actionRunner.DisplayName); // NOT "Run /./" + } + + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Worker")] + public void EvaluateDisplayNameForLocalActionWithPath() + { + // Arrange + Setup(); + var actionId = Guid.NewGuid(); + var action = new Pipelines.ActionStep() + { + Name = "action", + Id = actionId, + Reference = new Pipelines.RepositoryPathReference() + { + RepositoryType = Pipelines.PipelineConstants.SelfAlias, + Path = "./.github/actions/my-action" + } + }; + _actionRunner.Action = action; + + // Act + var validDisplayName = _actionRunner.EvaluateDisplayName(_context, _actionRunner.ExecutionContext, out bool updated); + + // Assert + Assert.True(validDisplayName); + Assert.True(updated); + Assert.Equal("Run ./.github/actions/my-action", _actionRunner.DisplayName); + } + + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Worker")] + public void EvaluateDisplayNameForRemoteActionWithPath() + { + // Arrange + Setup(); + var actionId = Guid.NewGuid(); + var action = new Pipelines.ActionStep() + { + Name = "action", + Id = actionId, + Reference = new Pipelines.RepositoryPathReference() + { + Name = "owner/repo", + Path = "subdir", + Ref = "v1" + } + }; + _actionRunner.Action = action; + + // Act + var validDisplayName = _actionRunner.EvaluateDisplayName(_context, _actionRunner.ExecutionContext, out bool updated); + + // Assert + Assert.True(validDisplayName); + Assert.True(updated); + Assert.Equal("Run owner/repo/subdir@v1", _actionRunner.DisplayName); + } + [Fact] [Trait("Level", "L0")] [Trait("Category", "Worker")] @@ -459,7 +547,7 @@ namespace GitHub.Runner.Common.Tests.Worker _handlerFactory = new Mock(); _defaultStepHost = new Mock(); - + var actionManifestLegacy = new ActionManifestManagerLegacy(); actionManifestLegacy.Initialize(_hc); _hc.SetSingleton(actionManifestLegacy);