[CI Visibility] Fix CODEOWNERS parser correctness and normalize CI source paths - #9099
[CI Visibility] Fix CODEOWNERS parser correctness and normalize CI source paths#9099tonyredondo wants to merge 14 commits into
Conversation
Execution-Time Benchmarks Report ⏱️Execution-time results for samples comparing This PR (9099) and master. ✅ No regressions detected |
BenchmarksBenchmark execution time: 2026-08-22 18:51:49 Comparing candidate commit 29e64a5 in PR branch Found 0 performance improvements and 1 performance regressions! Performance is the same for 71 metrics, 0 unstable metrics, 61 known flaky benchmarks, 65 flaky benchmarks without significant changes.
|
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 29e64a5575
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // resolution fails, anchor the path by finding the longest suffix that exists under the | ||
| // CODEOWNERS root, independently of the CI provider layout that produced the prefix. | ||
| codeOwnersRelativePath = null; | ||
| if (StringUtil.IsNullOrWhiteSpace(sourceFilePath) || Path.IsPathRooted(sourceFilePath)) |
There was a problem hiding this comment.
Reject absolute URIs before suffix anchoring
When sourceFilePath is an absolute URI such as file:///outside/tracer/test/Foo.cs or an HTTP document URL, the outer method initially recognizes it as absolute, but after relative-path validation fails it calls this fallback. This guard checks only Path.IsPathRooted, so the URI is split into segments and can be re-anchored whenever its suffix exists in the checkout, falsely assigning repository CODEOWNERS to an external source. Apply the same Uri.TryCreate(..., UriKind.Absolute, ...) rejection used by the caller before attempting suffix matching.
Useful? React with 👍 / 👎.
| rx = rx.Replace("\\*", "[^/]*"); // single‑level wildcard | ||
| // A slash right after ** means it can match zero or more intermediate directories: | ||
| // `a/**/b` must also match `a/b`. | ||
| rx = rx.Replace("§§DOUBLESTAR§§/", "(?:.*/)?"); |
There was a problem hiding this comment.
Restrict zero-directory globstars to whole path components
When a CODEOWNERS pattern contains **/ inside a path component, such as /foo**/bar, this unconditional replacement treats it as a globstar directory component and makes the slash optional, so the rule incorrectly matches /foobar. Consecutive stars only have zero-or-more-directory semantics when ** is a complete path component; otherwise they are ordinary within-component wildcards and the following slash must remain required.
Useful? React with 👍 / 👎.
| // Patterns whose last segment is wildcard-free also own everything inside a matched | ||
| // directory (e.g. `**/logs` owns `/build/logs/error.txt`), while wildcard segments like | ||
| // `docs/*` match individual entries only. | ||
| return _isDirectoryPattern && MatchesAncestor(path); |
There was a problem hiding this comment.
Stop ancestor retries after a regex timeout
For a pathological GitHub directory-style rule and a deeply nested source path, IsMatch(path) converts a three-second timeout into an ordinary false, after which this branch retries the same regex once for every ancestor. A single rule can therefore block the instrumented customer process for roughly three seconds per path component, defeating the timeout's protection; propagate the timeout result so the entire entry evaluation stops instead of entering MatchesAncestor.
AGENTS.md reference: AGENTS.md:L219-L225
Useful? React with 👍 / 👎.
… and dead code cleanup
…ex, and move fallback tests to unit test project
…tor when anchoring - Honor useOSSeparator in TryAnchorPathToCodeOwnersRoot - Treat ? as a single non-slash character and ** as a globstar only when it is a whole path segment - Drop unused lineNo and fix the CompileGlob comment - Move fixture-based CodeOwnersTests into the unit-test project
Summary of changes
Reason for change
CI Visibility uses CODEOWNERS metadata to determine test ownership. The existing parser diverged from GitHub and GitLab behavior in several cases, which could assign incorrect owners.
Additionally, source paths recorded by compilers in CI can contain agent-specific relative prefixes, causing valid repository files to fall outside the CODEOWNERS root during path resolution.
Implementation details
Test coverage
Other details
No public API or dependency changes.