feat(#143): fetch doc-map config from trusted VCS ref #153

Merged
rodin merged 2 commits from issue-143 into main 2026-05-15 12:09:20 +00:00
3 changed files with 50 additions and 3 deletions
Showing only changes of commit 02dfc12141 - Show all commits
+5 -2
View File
1
@@ -174,9 +174,12 @@ func main() {
os.Exit(1) os.Exit(1)
Review

[NIT] The resolvedDocMapFile variable is declared at a wide scope and left as the zero value (empty string) when *docMapTrustedRef != "". It is then used later in the else branch of the trusted-ref check. This is correct — the empty string is only used in the else branch — but it is slightly fragile. A future refactor could accidentally use resolvedDocMapFile in the trusted-ref path. A comment noting that resolvedDocMapFile is intentionally empty when docMapTrustedRef is set would improve clarity, or the variable could be moved into the else block. No bug here.

**[NIT]** The `resolvedDocMapFile` variable is declared at a wide scope and left as the zero value (empty string) when `*docMapTrustedRef != ""`. It is then used later in the `else` branch of the trusted-ref check. This is correct — the empty string is only used in the else branch — but it is slightly fragile. A future refactor could accidentally use `resolvedDocMapFile` in the trusted-ref path. A comment noting that `resolvedDocMapFile` is intentionally empty when `docMapTrustedRef` is set would improve clarity, or the variable could be moved into the `else` block. No bug here.
} }
// Early validation of filesystem-path flags (fail fast before network I/O) // Early validation of filesystem-path flags (fail fast before network I/O).
// Skip local-path validation when --doc-map-trusted-ref is set: the flag
// value is used as a VCS API path, not a local filesystem path, and the
// file may not exist in the local checkout (sparse, PR-deleted, etc.).
var resolvedDocMapFile string var resolvedDocMapFile string
if *docMapFile != "" { if *docMapFile != "" && *docMapTrustedRef == "" {
resolved, err := validateWorkspacePath(*docMapFile, "doc-map") resolved, err := validateWorkspacePath(*docMapFile, "doc-map")
if err != nil { if err != nil {
slog.Error("invalid doc-map path", "error", err) slog.Error("invalid doc-map path", "error", err)
+44
View File
@@ -1578,3 +1578,47 @@ func TestMainSubprocess_InvalidDocMapFile(t *testing.T) {
t.Errorf("expected error about failed resolution, got: %s", output) t.Errorf("expected error about failed resolution, got: %s", output)
} }
} }
// TestMainSubprocess_DocMapTrustedRefSkipsLocalValidation confirms that
// --doc-map-trusted-ref bypasses local filesystem validation for --doc-map.
// When the trusted-ref flag is set, the doc-map value is used as a VCS API
// path; a nonexistent local file must not cause an early exit before network I/O.
func TestMainSubprocess_DocMapTrustedRefSkipsLocalValidation(t *testing.T) {
if os.Getenv("TEST_SUBPROCESS_MAIN") == "1" {
flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
os.Args = []string{"review-bot",
"--vcs-url", "https://gitea.example.com",
"--repo", "owner/repo",
"--pr", "1",
"--reviewer-token", "tok",
"--llm-base-url", "https://api.example.com",
"--llm-api-key", "key",
"--llm-model", "gpt-4",
"--doc-map", "nonexistent-local.yml",
"--doc-map-trusted-ref", "main",
}
main()
return
}
cmd := exec.Command(os.Args[0], "-test.run=TestMainSubprocess_DocMapTrustedRefSkipsLocalValidation")
cmd.Env = append(cleanEnv(),
"TEST_SUBPROCESS_MAIN=1",
"GITHUB_WORKSPACE="+t.TempDir(),
)
out, err := cmd.CombinedOutput()
output := string(out)
// The test must fail (network I/O or VCS API failure) but must NOT
// fail with the local filesystem validation error.
// "failed to resolve" would indicate the early validateWorkspacePath ran —
// that would be the bug this test is catching.
if strings.Contains(output, "failed to resolve") {
t.Errorf("--doc-map-trusted-ref should skip local path validation, but got filesystem error: %s", output)
}
// It must still exit non-zero (real VCS call to example.com will fail).
if err == nil {
t.Fatal("expected non-zero exit when VCS API is unreachable, got success")
}
}
+1 -1
View File
@@ -57,7 +57,7 @@ func ParseDocMapConfig(localPath string) (*DocMapConfig, error) {
// ParseDocMapConfigContent parses a doc-map YAML config from an in-memory // ParseDocMapConfigContent parses a doc-map YAML config from an in-memory
// string. The source parameter is used only for error messages and log entries // string. The source parameter is used only for error messages and log entries
// (e.g. "main:main@<ref>"). // (e.g. "owner/repo@main:.review-bot/doc-map.yml").
// //
// Use this when the config content has been fetched from a trusted VCS ref // Use this when the config content has been fetched from a trusted VCS ref
// rather than read from the local workspace. // rather than read from the local workspace.
3