From 4342a1b8f0412f649caa099b7a99a10fe0016ad3 Mon Sep 17 00:00:00 2001 From: Salman Muin Kayser Chishti Date: Fri, 10 Apr 2026 13:51:29 +0000 Subject: [PATCH] fix: use /.github/workflows/ marker for derivation parsing Fixes incorrect parsing for repos named .github (e.g. octo-org/.github). The old /.github/ marker would match too early, deriving the wrong repository name. Also treats empty-string fields as unset during derivation. --- src/Runner.Worker/JobContext.cs | 18 ++++++++++-------- src/Test/L0/Worker/JobContextL0.cs | 25 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/Runner.Worker/JobContext.cs b/src/Runner.Worker/JobContext.cs index 0ce869011..beff55d77 100644 --- a/src/Runner.Worker/JobContext.cs +++ b/src/Runner.Worker/JobContext.cs @@ -159,25 +159,27 @@ namespace GitHub.Runner.Worker return; } - // Format: owner/repo/path/to/file.yml@ref + // Format: owner/repo/.github/workflows/file.yml@ref var atIndex = workflowRef.IndexOf('@'); var pathPart = atIndex >= 0 ? workflowRef.Substring(0, atIndex) : workflowRef; - // Split into owner/repo and file path at the .github/ boundary - var githubDirIndex = pathPart.IndexOf("/.github/"); - if (githubDirIndex < 0) + // Split at /.github/workflows/ to correctly handle repos named ".github" + // e.g. "octo-org/.github/.github/workflows/ci.yml" → repo="octo-org/.github" + var marker = "/.github/workflows/"; + var markerIndex = pathPart.IndexOf(marker); + if (markerIndex < 0) { return; } - if (WorkflowRepository == null) + if (WorkflowRepository == null || WorkflowRepository == "") { - WorkflowRepository = pathPart.Substring(0, githubDirIndex); + WorkflowRepository = pathPart.Substring(0, markerIndex); } - if (WorkflowFilePath == null) + if (WorkflowFilePath == null || WorkflowFilePath == "") { - WorkflowFilePath = pathPart.Substring(githubDirIndex + 1); // skip leading '/' + WorkflowFilePath = pathPart.Substring(markerIndex + 1); // skip leading '/' } } } diff --git a/src/Test/L0/Worker/JobContextL0.cs b/src/Test/L0/Worker/JobContextL0.cs index 1a2206ab0..f1b1be6ec 100644 --- a/src/Test/L0/Worker/JobContextL0.cs +++ b/src/Test/L0/Worker/JobContextL0.cs @@ -194,5 +194,30 @@ namespace GitHub.Runner.Common.Tests.Worker Assert.Equal("my-org/my-repo", ctx.WorkflowRepository); Assert.Equal(".github/workflows/deploy.yml", ctx.WorkflowFilePath); } + + [Fact] + public void DeriveWorkflowRefComponents_HandlesDotGithubRepoName() + { + // Repos can be named ".github" — the marker must be /.github/workflows/ not /.github/ + var ctx = new JobContext(); + ctx.WorkflowRef = "octo-org/.github/.github/workflows/ci.yml@refs/heads/main"; + ctx.DeriveWorkflowRefComponents(); + + Assert.Equal("octo-org/.github", ctx.WorkflowRepository); + Assert.Equal(".github/workflows/ci.yml", ctx.WorkflowFilePath); + } + + [Fact] + public void DeriveWorkflowRefComponents_TreatsEmptyStringAsUnset() + { + var ctx = new JobContext(); + ctx.WorkflowRef = "my-org/my-repo/.github/workflows/deploy.yml@refs/heads/main"; + ctx.WorkflowRepository = ""; + ctx.WorkflowFilePath = ""; + ctx.DeriveWorkflowRefComponents(); + + Assert.Equal("my-org/my-repo", ctx.WorkflowRepository); + Assert.Equal(".github/workflows/deploy.yml", ctx.WorkflowFilePath); + } } }