Skip to content

Commit 0f1c6d2

Browse files
authored
[enhancement](CI) Force inject required AGENTS guides into review prompt (#64536)
Problem Summary: Automated code review runs relied on the reviewer to infer which module-specific AGENTS.md files apply to a pull request. Recent Litefuse traces showed that reviews often skipped ancestor guides such as the repository root AGENTS.md, fe/AGENTS.md, and be/test/AGENTS.md even when the changed files made them applicable. This change fetches the PR changed file list, derives every existing AGENTS.md file from the changed file ancestor directories, records the list in the review context, and injects the required guide paths directly into the first Codex review prompt. We tested 5 PRs that did not read the AGENTS.md file during previous pipeline runs, and the new results are as follows: | Origin PR | Test PR | Run | Litefuse Trace | Result | |---|---:|---:|---|---| | #64478 | zclllyybb#36 | `27536249602` | `d76b77ac4e0d52d96f413b154c9f2571` | Read All | | #64458 | zclllyybb#37 | `27536258049` | `8db34388a8379acdcd9e48720f11225f` | Read All | | #64392 | zclllyybb#38 | `27536266784` | `a5e37fba03375a9517f7a67e33f70d39` | Read All | | #64489 | zclllyybb#39 | `27536275680` | `22ace18d70ece96b0ca7fa73123b62da` | Read All | | #64419 | zclllyybb#41 | `27538239601` | `1803c040e4140d61e840e4e1526190e7` | Read All |
1 parent 5cf768f commit 0f1c6d2

2 files changed

Lines changed: 144 additions & 0 deletions

File tree

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#!/usr/bin/env python3
2+
"""Prepare the AGENTS.md guide list for automated PR review prompts."""
3+
4+
from __future__ import annotations
5+
6+
import argparse
7+
from pathlib import Path, PurePosixPath
8+
9+
10+
def parse_args() -> argparse.Namespace:
11+
parser = argparse.ArgumentParser(description=__doc__)
12+
parser.add_argument(
13+
"--changed-files",
14+
required=True,
15+
type=Path,
16+
help="Newline-delimited PR changed file paths.",
17+
)
18+
parser.add_argument(
19+
"--required-agents",
20+
required=True,
21+
type=Path,
22+
help="Output file containing one required AGENTS.md path per line.",
23+
)
24+
parser.add_argument(
25+
"--prompt-block",
26+
required=True,
27+
type=Path,
28+
help="Output file containing the bullet list inserted into the review prompt.",
29+
)
30+
parser.add_argument(
31+
"--repo-root",
32+
default=Path("."),
33+
type=Path,
34+
help="Repository root. Defaults to the current working directory.",
35+
)
36+
return parser.parse_args()
37+
38+
39+
def valid_changed_path(path: str) -> PurePosixPath | None:
40+
value = path.strip()
41+
if not value:
42+
return None
43+
44+
candidate = PurePosixPath(value)
45+
if candidate.is_absolute() or ".." in candidate.parts:
46+
raise ValueError(f"Changed file path escapes the repository: {path!r}")
47+
return candidate
48+
49+
50+
def add_if_present(repo_root: Path, agents: list[str], seen: set[str], path: PurePosixPath) -> None:
51+
text_path = path.as_posix()
52+
if text_path in seen:
53+
return
54+
if (repo_root / Path(text_path)).is_file():
55+
agents.append(text_path)
56+
seen.add(text_path)
57+
58+
59+
def required_agents(repo_root: Path, changed_files: list[PurePosixPath]) -> list[str]:
60+
agents: list[str] = []
61+
seen: set[str] = set()
62+
63+
add_if_present(repo_root, agents, seen, PurePosixPath("AGENTS.md"))
64+
for changed_file in changed_files:
65+
for index in range(1, len(changed_file.parts)):
66+
directory = PurePosixPath(*changed_file.parts[:index])
67+
add_if_present(repo_root, agents, seen, directory / "AGENTS.md")
68+
69+
return agents
70+
71+
72+
def main() -> None:
73+
args = parse_args()
74+
repo_root = args.repo_root.resolve()
75+
changed_files = [
76+
path
77+
for path in (valid_changed_path(line) for line in args.changed_files.read_text().splitlines())
78+
if path is not None
79+
]
80+
agents = required_agents(repo_root, changed_files)
81+
82+
args.required_agents.write_text("".join(f"{path}\n" for path in agents))
83+
if agents:
84+
args.prompt_block.write_text("".join(f"- {path}\n" for path in agents))
85+
else:
86+
args.prompt_block.write_text("- No AGENTS.md files were found for the changed file ancestors.\n")
87+
88+
89+
if __name__ == "__main__":
90+
main()

.github/workflows/code-review-runner.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
name: Code Review Runner
22

33
on:
4+
workflow_dispatch:
5+
inputs:
6+
pr_number:
7+
required: true
8+
type: string
9+
head_sha:
10+
required: true
11+
type: string
12+
base_sha:
13+
required: true
14+
type: string
15+
review_focus:
16+
required: false
17+
type: string
18+
default: ''
419
workflow_call:
520
inputs:
621
pr_number:
@@ -199,6 +214,30 @@ jobs:
199214
printf 'No additional user-provided review focus.\n' > "$REVIEW_CONTEXT_DIR/review_focus.txt"
200215
fi
201216
217+
- name: Prepare required AGENTS guides
218+
env:
219+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
220+
REPO: ${{ github.repository }}
221+
PR_NUMBER: ${{ inputs.pr_number }}
222+
HELPER_REF: ${{ github.workflow_sha || github.sha }}
223+
run: |
224+
gh api --paginate "repos/${REPO}/pulls/${PR_NUMBER}/files" --jq '.[].filename' > "$REVIEW_CONTEXT_DIR/pr_changed_files.txt"
225+
226+
helper="$RUNNER_TEMP/prepare_review_agents.py"
227+
gh api \
228+
-H "Accept: application/vnd.github.raw" \
229+
"repos/${REPO}/contents/.github/scripts/prepare_review_agents.py?ref=${HELPER_REF}" \
230+
> "$helper"
231+
chmod 700 "$helper"
232+
233+
python3 "$helper" \
234+
--changed-files "$REVIEW_CONTEXT_DIR/pr_changed_files.txt" \
235+
--required-agents "$REVIEW_CONTEXT_DIR/required_agents.txt" \
236+
--prompt-block "$REVIEW_CONTEXT_DIR/required_agents_prompt.txt"
237+
238+
echo "Required AGENTS.md files for this review:"
239+
sed 's/^/ /' "$REVIEW_CONTEXT_DIR/required_agents.txt"
240+
202241
- name: Prepare review prompt
203242
run: |
204243
cat > "$REVIEW_CONTEXT_DIR/review_prompt.txt" <<'PROMPT'
@@ -216,8 +255,13 @@ jobs:
216255
- Existing inline review threads: PLACEHOLDER_CONTEXT_DIR/pr_review_threads.md
217256
- Raw inline review comments JSON: PLACEHOLDER_CONTEXT_DIR/pr_review_comments.json
218257
- User review focus: PLACEHOLDER_CONTEXT_DIR/review_focus.txt
258+
- PR changed files: PLACEHOLDER_CONTEXT_DIR/pr_changed_files.txt
259+
- Required AGENTS.md files: PLACEHOLDER_CONTEXT_DIR/required_agents.txt
219260
220261
Before reviewing any code, you MUST read and follow the code review skill in this repository. During review, you must strictly follow those instructions.
262+
Before inspecting the PR diff or related code, you MUST read the contents of every AGENTS.md file listed below. These paths are computed from the PR changed file ancestors in this checkout. Searching for or listing paths is not sufficient; read each listed file directly.
263+
Required AGENTS.md files for this PR:
264+
PLACEHOLDER_REQUIRED_AGENTS_BLOCK
221265
Before proposing any new issue, you MUST read PLACEHOLDER_CONTEXT_DIR/pr_review_threads.md and treat every existing inline comment thread and reply as already-known review context.
222266
Do NOT submit the same or substantially similar issue again if it has already been raised in the existing review threads, even if you would phrase it differently.
223267
Only raise a similar concern when the PR introduces a genuinely different instance in another location that is not already covered by the existing thread, and explain why it is distinct.
@@ -243,6 +287,16 @@ jobs:
243287
sed -i "s|PLACEHOLDER_HEAD_SHA|${HEAD_SHA}|g" "$REVIEW_CONTEXT_DIR/review_prompt.txt"
244288
sed -i "s|PLACEHOLDER_BASE_SHA|${BASE_SHA}|g" "$REVIEW_CONTEXT_DIR/review_prompt.txt"
245289
sed -i "s|PLACEHOLDER_CONTEXT_DIR|${REVIEW_CONTEXT_REL}|g" "$REVIEW_CONTEXT_DIR/review_prompt.txt"
290+
python3 - "$REVIEW_CONTEXT_DIR/review_prompt.txt" "$REVIEW_CONTEXT_DIR/required_agents_prompt.txt" <<'PY'
291+
import sys
292+
from pathlib import Path
293+
294+
prompt_path = Path(sys.argv[1])
295+
required_agents_path = Path(sys.argv[2])
296+
prompt = prompt_path.read_text()
297+
required_agents = required_agents_path.read_text().rstrip()
298+
prompt_path.write_text(prompt.replace("PLACEHOLDER_REQUIRED_AGENTS_BLOCK", required_agents))
299+
PY
246300
env:
247301
REPO: ${{ github.repository }}
248302
PR_NUMBER: ${{ inputs.pr_number }}

0 commit comments

Comments
 (0)