feat: default fromPath for problem matchers (#3802)

This commit is contained in:
David Sanders
2025-05-05 13:45:23 -07:00
committed by GitHub
parent 26eff8e55a
commit 1a092a24a3
4 changed files with 304 additions and 3 deletions

View File

@@ -896,5 +896,173 @@ namespace GitHub.Runner.Common.Tests.Worker
Assert.Equal("not-working", match.Message);
Assert.Equal("my-project.proj", match.FromPath);
}
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public void Matcher_SinglePattern_DefaultFromPath()
{
var config = JsonUtility.FromString<IssueMatchersConfig>(@"
{
""problemMatcher"": [
{
""owner"": ""myMatcher"",
""fromPath"": ""subdir/default-project.csproj"",
""pattern"": [
{
""regexp"": ""^file:(.+) line:(.+) column:(.+) severity:(.+) code:(.+) message:(.+)$"",
""file"": 1,
""line"": 2,
""column"": 3,
""severity"": 4,
""code"": 5,
""message"": 6
}
]
}
]
}
");
config.Validate();
var matcher = new IssueMatcher(config.Matchers[0], TimeSpan.FromSeconds(1));
var match = matcher.Match("file:my-file.cs line:123 column:45 severity:real-bad code:uh-oh message:not-working");
Assert.Equal("my-file.cs", match.File);
Assert.Equal("123", match.Line);
Assert.Equal("45", match.Column);
Assert.Equal("real-bad", match.Severity);
Assert.Equal("uh-oh", match.Code);
Assert.Equal("not-working", match.Message);
Assert.Equal("subdir/default-project.csproj", match.FromPath);
// Test that a pattern-specific fromPath overrides the default
config = JsonUtility.FromString<IssueMatchersConfig>(@"
{
""problemMatcher"": [
{
""owner"": ""myMatcher"",
""fromPath"": ""subdir/default-project.csproj"",
""pattern"": [
{
""regexp"": ""^file:(.+) line:(.+) column:(.+) severity:(.+) code:(.+) message:(.+) fromPath:(.+)$"",
""file"": 1,
""line"": 2,
""column"": 3,
""severity"": 4,
""code"": 5,
""message"": 6,
""fromPath"": 7
}
]
}
]
}
");
config.Validate();
matcher = new IssueMatcher(config.Matchers[0], TimeSpan.FromSeconds(1));
match = matcher.Match("file:my-file.cs line:123 column:45 severity:real-bad code:uh-oh message:not-working fromPath:my-project.proj");
Assert.Equal("my-file.cs", match.File);
Assert.Equal("123", match.Line);
Assert.Equal("45", match.Column);
Assert.Equal("real-bad", match.Severity);
Assert.Equal("uh-oh", match.Code);
Assert.Equal("not-working", match.Message);
Assert.Equal("my-project.proj", match.FromPath);
}
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public void Matcher_MultiplePatterns_DefaultFromPath()
{
var config = JsonUtility.FromString<IssueMatchersConfig>(@"
{
""problemMatcher"": [
{
""owner"": ""myMatcher"",
""fromPath"": ""subdir/default-project.csproj"",
""pattern"": [
{
""regexp"": ""^file:(.+)$"",
""file"": 1,
},
{
""regexp"": ""^severity:(.+)$"",
""severity"": 1
},
{
""regexp"": ""^line:(.+) column:(.+) code:(.+) message:(.+)$"",
""line"": 1,
""column"": 2,
""code"": 3,
""message"": 4
}
]
}
]
}
");
config.Validate();
var matcher = new IssueMatcher(config.Matchers[0], TimeSpan.FromSeconds(1));
var match = matcher.Match("file:my-file.cs");
Assert.Null(match);
match = matcher.Match("severity:real-bad");
Assert.Null(match);
match = matcher.Match("line:123 column:45 code:uh-oh message:not-working");
Assert.Equal("my-file.cs", match.File);
Assert.Equal("123", match.Line);
Assert.Equal("45", match.Column);
Assert.Equal("real-bad", match.Severity);
Assert.Equal("uh-oh", match.Code);
Assert.Equal("not-working", match.Message);
Assert.Equal("subdir/default-project.csproj", match.FromPath);
// Test that pattern-specific fromPath overrides the default
config = JsonUtility.FromString<IssueMatchersConfig>(@"
{
""problemMatcher"": [
{
""owner"": ""myMatcher"",
""fromPath"": ""subdir/default-project.csproj"",
""pattern"": [
{
""regexp"": ""^file:(.+) fromPath:(.+)$"",
""file"": 1,
""fromPath"": 2
},
{
""regexp"": ""^severity:(.+)$"",
""severity"": 1
},
{
""regexp"": ""^line:(.+) column:(.+) code:(.+) message:(.+)$"",
""line"": 1,
""column"": 2,
""code"": 3,
""message"": 4
}
]
}
]
}
");
config.Validate();
matcher = new IssueMatcher(config.Matchers[0], TimeSpan.FromSeconds(1));
match = matcher.Match("file:my-file.cs fromPath:my-project.proj");
Assert.Null(match);
match = matcher.Match("severity:real-bad");
Assert.Null(match);
match = matcher.Match("line:123 column:45 code:uh-oh message:not-working");
Assert.Equal("my-file.cs", match.File);
Assert.Equal("123", match.Line);
Assert.Equal("45", match.Column);
Assert.Equal("real-bad", match.Severity);
Assert.Equal("uh-oh", match.Code);
Assert.Equal("not-working", match.Message);
Assert.Equal("my-project.proj", match.FromPath);
}
}
}

View File

@@ -937,6 +937,62 @@ namespace GitHub.Runner.Common.Tests.Worker
}
}
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public async void MatcherDefaultFromPath()
{
var matchers = new IssueMatchersConfig
{
Matchers =
{
new IssueMatcherConfig
{
Owner = "my-matcher-1",
FromPath = "workflow-repo/some-project/some-project.proj",
Patterns = new[]
{
new IssuePatternConfig
{
Pattern = @"(.+): (.+)",
File = 1,
Message = 2,
},
},
},
},
};
using (var hostContext = Setup(matchers: matchers))
using (_outputManager)
{
// Setup github.workspace, github.repository
var workDirectory = hostContext.GetDirectory(WellKnownDirectory.Work);
ArgUtil.NotNullOrEmpty(workDirectory, nameof(workDirectory));
Directory.CreateDirectory(workDirectory);
var workspaceDirectory = Path.Combine(workDirectory, "workspace");
Directory.CreateDirectory(workspaceDirectory);
_executionContext.Setup(x => x.GetGitHubContext("workspace")).Returns(workspaceDirectory);
_executionContext.Setup(x => x.GetGitHubContext("repository")).Returns("my-org/workflow-repo");
// Setup a git repository
var repositoryPath = Path.Combine(workspaceDirectory, "workflow-repo");
await CreateRepository(hostContext, repositoryPath, "https://github.com/my-org/workflow-repo");
// Create a test file
var filePath = Path.Combine(repositoryPath, "some-project", "some-directory", "some-file.txt");
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
File.WriteAllText(filePath, "");
// Process
Process("some-directory/some-file.txt: some error");
Assert.Equal(1, _issues.Count);
Assert.Equal("some error", _issues[0].Item1.Message);
Assert.Equal("some-project/some-directory/some-file.txt", _issues[0].Item1.Data["file"]);
Assert.Equal(0, _commands.Count);
Assert.Equal(0, _messages.Count);
}
}
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]