fix(copilot): robust diff computation for cloud agent environments (#709)

The cloud agent checks out a branch like copilot/review-pr-NNN which
may not have upstream/main or origin/main refs available for merge-base.

Changes:
- Use gh pr diff as primary method (always works in PR context)
- Fall back to git merge-base for local non-PR usage
- Remove path filters (*.rs *.toml examples/) — review full diff
- Remove head -2000 truncation — let agents see everything
- Explicitly fetch origin/main in copilot-setup-steps.yml as backup

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Anand Krishnamoorthi
2026-05-18 15:12:29 -05:00
committed by GitHub
parent d2c483e93e
commit be3fde7706
3 changed files with 60 additions and 29 deletions

View File

@@ -8,3 +8,5 @@ steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: with:
fetch-depth: 0 # full history needed for git diff against main fetch-depth: 0 # full history needed for git diff against main
- run: git fetch origin main:refs/remotes/origin/main
name: Ensure origin/main ref is available for diff computation

View File

@@ -25,15 +25,21 @@ Key constraints (details in copilot-instructions.md):
## Step 1: Get the Diff ## Step 1: Get the Diff
```bash ```bash
BASE=$(git merge-base upstream/main HEAD 2>/dev/null \ # Primary: use gh pr diff (works in cloud agent + any PR context).
|| git merge-base origin/main HEAD 2>/dev/null) # Fallback: git merge-base for local non-PR usage.
if [ -z "$BASE" ]; then if gh pr diff --name-only >/dev/null 2>&1; then
echo "ERROR: Cannot find upstream/main or origin/main. Cannot determine review scope." echo "---STAT---"
exit 1 gh pr diff --name-only
echo "---DIFF---"
gh pr diff
else
BASE=$(git merge-base upstream/main HEAD 2>/dev/null \
|| git merge-base origin/main HEAD 2>/dev/null \
|| git merge-base main HEAD 2>/dev/null)
echo "Reviewing changes since: $BASE"
git diff "$BASE"..HEAD --stat
git diff "$BASE"..HEAD
fi fi
echo "Reviewing changes since: $BASE"
git diff "$BASE"..HEAD --stat
git diff "$BASE"..HEAD -- '*.rs' '*.toml' 'examples/'
``` ```
If the diff is empty, stop and report: "No changes found to review." If the diff is empty, stop and report: "No changes found to review."
@@ -196,3 +202,9 @@ one pass. If any were skipped, note them and briefly assess.
### Summary ### Summary
X findings (N critical, N high, N medium, N low). One sentence overall assessment. X findings (N critical, N high, N medium, N low). One sentence overall assessment.
### Output
After generating the report above, write the COMPLETE report to `/tmp/code-review-report.md`
using the `create` tool or shell. This ensures the full report is preserved even if
display output is truncated.

View File

@@ -40,22 +40,25 @@ Use `read_agent` with `wait: true` to wait for each background agent.
## Step 1: Get the Diff and Build Inventory ## Step 1: Get the Diff and Build Inventory
```bash ```bash
BASE=$(git merge-base upstream/main HEAD 2>/dev/null \ # Primary: use gh pr diff (works in cloud agent + any PR context).
|| git merge-base origin/main HEAD 2>/dev/null) # Fallback: git merge-base for local non-PR usage.
if [ -z "$BASE" ]; then if gh pr diff --name-only >/dev/null 2>&1; then
echo "ERROR: Cannot find upstream/main or origin/main." echo "---STAT---"
exit 1 gh pr diff --name-only
echo "---DIFF---"
gh pr diff
else
BASE=$(git merge-base upstream/main HEAD 2>/dev/null \
|| git merge-base origin/main HEAD 2>/dev/null \
|| git merge-base main HEAD 2>/dev/null)
echo "Reviewing changes since: $BASE"
git diff "$BASE"..HEAD --stat
git diff "$BASE"..HEAD
fi fi
echo "Reviewing changes since: $BASE"
git diff "$BASE"..HEAD --stat
git diff "$BASE"..HEAD -- '*.rs' '*.toml' 'examples/' | head -2000
``` ```
If the diff is empty, stop and report: "No changes found to review." If the diff is empty, stop and report: "No changes found to review."
**Scope rule:** Focus on code files (`*.rs`, `*.toml`, examples). Do NOT pass
docs/config diffs to agents.
**Build a risk-classified inventory.** List every changed function, struct, **Build a risk-classified inventory.** List every changed function, struct,
impl, trait, pub item, and significant code block. Number them and tag with impl, trait, pub item, and significant code block. Number them and tag with
risk predicates: risk predicates:
@@ -106,8 +109,10 @@ Use `model: "gpt-5.4"` in the task tool call (provides model diversity).
> Get the diff: > Get the diff:
> ``` > ```
> BASE=$(git merge-base upstream/main HEAD 2>/dev/null \ > BASE=$(git merge-base upstream/main HEAD 2>/dev/null \
> || git merge-base origin/main HEAD 2>/dev/null) > || git merge-base origin/main HEAD 2>/dev/null \
> git diff "$BASE"..HEAD -- '*.rs' '*.toml' 'examples/' > || git merge-base main HEAD 2>/dev/null)
> # If no merge-base, use: gh pr diff
> git diff "$BASE"..HEAD # or: gh pr diff
> ``` > ```
> >
> Key regorus constraints: > Key regorus constraints:
@@ -161,8 +166,10 @@ Use `model: "claude-opus-4.6"` in the task tool call.
> Get the diff AND read full source files for context: > Get the diff AND read full source files for context:
> ``` > ```
> BASE=$(git merge-base upstream/main HEAD 2>/dev/null \ > BASE=$(git merge-base upstream/main HEAD 2>/dev/null \
> || git merge-base origin/main HEAD 2>/dev/null) > || git merge-base origin/main HEAD 2>/dev/null \
> git diff "$BASE"..HEAD -- '*.rs' '*.toml' 'examples/' > || git merge-base main HEAD 2>/dev/null)
> # If no merge-base, use: gh pr diff
> git diff "$BASE"..HEAD # or: gh pr diff
> ``` > ```
> Then use `view` to read the full source files that were changed. > Then use `view` to read the full source files that were changed.
> >
@@ -219,8 +226,10 @@ Use the default model (no `model` parameter).
> Get the diff: > Get the diff:
> ``` > ```
> BASE=$(git merge-base upstream/main HEAD 2>/dev/null \ > BASE=$(git merge-base upstream/main HEAD 2>/dev/null \
> || git merge-base origin/main HEAD 2>/dev/null) > || git merge-base origin/main HEAD 2>/dev/null \
> git diff "$BASE"..HEAD -- '*.rs' '*.toml' 'examples/' > || git merge-base main HEAD 2>/dev/null)
> # If no merge-base, use: gh pr diff
> git diff "$BASE"..HEAD # or: gh pr diff
> ``` > ```
> Use `view` to read surrounding context. > Use `view` to read surrounding context.
> >
@@ -439,8 +448,10 @@ Launch **1 general-purpose agent in background mode**.
> Get the diff: > Get the diff:
> ``` > ```
> BASE=$(git merge-base upstream/main HEAD 2>/dev/null \ > BASE=$(git merge-base upstream/main HEAD 2>/dev/null \
> || git merge-base origin/main HEAD 2>/dev/null) > || git merge-base origin/main HEAD 2>/dev/null \
> git diff "$BASE"..HEAD -- '*.rs' '*.toml' 'examples/' > || git merge-base main HEAD 2>/dev/null)
> # If no merge-base, use: gh pr diff
> git diff "$BASE"..HEAD # or: gh pr diff
> ``` > ```
> Use `view` to read full source files. > Use `view` to read full source files.
> >
@@ -481,8 +492,8 @@ Launch **1 general-purpose agent in background mode**.
## Step 5: Synthesize and Report ## Step 5: Synthesize and Report
**IMPORTANT:** This is the primary output. Everything above was preparation. **CRITICAL:** Write the report to `/tmp/deep-review-report.md` FIRST, then display it.
Keep the report COMPACT — one finding per block, no filler prose. Use a shell command to write the file before any other output in this step.
Apply verdicts from the adversarial verifier: Apply verdicts from the adversarial verifier:
- **CONFIRMED**: keep at stated severity - **CONFIRMED**: keep at stated severity
@@ -522,3 +533,9 @@ would catch it. If not, name the minimal test that should exist.
X findings (N critical, N high, N medium, N low). Y "likely" findings. X findings (N critical, N high, N medium, N low). Y "likely" findings.
Z dropped (one-line reasons). Z dropped (one-line reasons).
Risk assessment in one sentence. Risk assessment in one sentence.
---
**Remember:** The report above MUST be written to `/tmp/deep-review-report.md` at the
START of Step 5 (before displaying it). Use shell: `cat > /tmp/deep-review-report.md << 'REPORT_EOF'`
... report content ... `REPORT_EOF`