fix(pr-analysis): on large diff and reduce gh pr calls (#35734)

* fix(pr-analysis): on large diff and reduce gh pr calls

* address comments
This commit is contained in:
sabril
2026-03-23 17:51:18 +08:00
committed by GitHub
parent b416344931
commit ae1691a368
+41 -20
View File
@@ -50,25 +50,40 @@ jobs:
id: pr-info
env:
GH_TOKEN: ${{ github.token }}
# Pass event data via env vars to avoid script injection from PR body
EVENT_PR_NUMBER: ${{ github.event.pull_request.number }}
EVENT_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
EVENT_REPO_OWNER: ${{ github.repository_owner }}
EVENT_REPO_NAME: ${{ github.event.repository.name }}
EVENT_PR_BODY: ${{ github.event.pull_request.body }}
EVENT_BASE_REF: ${{ github.event.pull_request.base.ref }}
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
PR_NUMBER="${{ inputs.pr_number }}"
PR_JSON=$(gh pr view "$PR_NUMBER" --repo "${{ env.REPO }}" --json headRefOid,headRepository,headRepositoryOwner --jq '{sha: .headRefOid, repo: .headRepository.name, owner: .headRepositoryOwner.login}')
HEAD_SHA=$(echo "$PR_JSON" | jq -r '.sha')
HEAD_REPO_OWNER=$(echo "$PR_JSON" | jq -r '.owner')
HEAD_REPO_NAME=$(echo "$PR_JSON" | jq -r '.repo')
PR_JSON=$(gh pr view "$PR_NUMBER" --repo "${{ env.REPO }}" --json headRefOid,headRepository,headRepositoryOwner,body,baseRefName)
HEAD_SHA=$(echo "$PR_JSON" | jq -r '.headRefOid')
HEAD_REPO_OWNER=$(echo "$PR_JSON" | jq -r '.headRepositoryOwner.login')
HEAD_REPO_NAME=$(echo "$PR_JSON" | jq -r '.headRepository.name')
PR_BODY=$(echo "$PR_JSON" | jq -r '.body // ""')
BASE_BRANCH=$(echo "$PR_JSON" | jq -r '.baseRefName')
else
PR_NUMBER="${{ github.event.pull_request.number }}"
HEAD_SHA="${{ github.event.pull_request.head.sha }}"
HEAD_REPO_OWNER="${{ github.repository_owner }}"
HEAD_REPO_NAME="${{ github.event.repository.name }}"
PR_NUMBER="$EVENT_PR_NUMBER"
HEAD_SHA="$EVENT_HEAD_SHA"
HEAD_REPO_OWNER="$EVENT_REPO_OWNER"
HEAD_REPO_NAME="$EVENT_REPO_NAME"
PR_BODY="$EVENT_PR_BODY"
BASE_BRANCH="$EVENT_BASE_REF"
fi
{
echo "pr_number=${PR_NUMBER}"
echo "head_sha=${HEAD_SHA}"
echo "head_repo=${HEAD_REPO_OWNER}/${HEAD_REPO_NAME}"
echo "base_branch=${BASE_BRANCH}"
} >> "$GITHUB_OUTPUT"
# Write PR body to a temp path that survives checkout
printf '%s\n' "$PR_BODY" > "$RUNNER_TEMP/pr_body.txt"
# Required: claude-code-action needs a git directory to initialize.
- name: ci/checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -77,15 +92,24 @@ jobs:
- name: ci/prep-analysis-data
id: prep
env:
GH_TOKEN: ${{ github.token }}
run: |
PR_NUM=${{ steps.pr-info.outputs.pr_number }}
# Fetch core data
gh pr view "$PR_NUM" --repo "$REPO" --json body --jq '.body' > pr_body.txt
BASE_BRANCH=${{ steps.pr-info.outputs.base_branch }}
# Get all changed files
gh pr diff "$PR_NUM" --repo "$REPO" --name-only > all_files.txt
# Copy PR body from temp path (written before checkout)
cp "$RUNNER_TEMP/pr_body.txt" pr_body.txt
# Fetch the PR head and base branch, then diff locally (no API size limits)
git fetch origin "$BASE_BRANCH" "pull/$PR_NUM/head:pr-$PR_NUM" --depth=50
if ! MERGE_BASE=$(git merge-base "origin/$BASE_BRANCH" "pr-$PR_NUM" 2>/dev/null); then
echo "Merge base not found in shallow history — fetching full history"
git fetch --unshallow origin "$BASE_BRANCH" "pull/$PR_NUM/head:pr-$PR_NUM"
MERGE_BASE=$(git merge-base "origin/$BASE_BRANCH" "pr-$PR_NUM")
fi
git diff "$MERGE_BASE" "pr-$PR_NUM" > full_diff.diff
# Derive file list from the diff (avoids a second API call)
grep '^diff --git' full_diff.diff | sed 's|.*b/||' > all_files.txt
# Extract Test Files (based on your conventions)
grep -E "_test\.go|\.test\.(ts|tsx|js)|e2e-tests/|detox/|e2e/" all_files.txt > test_files.txt || true
@@ -97,10 +121,7 @@ jobs:
cat prod_files.txt test_files.txt | sort | uniq > relevant_files.txt
if [ -s relevant_files.txt ]; then
# Fetch the full diff, then filter to keep only hunks for relevant files
gh pr diff "$PR_NUM" --repo "$REPO" > full_diff.diff
# Use awk to extract only diff sections whose header matches a relevant file
# Filter the already-fetched diff to keep only hunks for relevant files
awk '
BEGIN { while ((getline line < "relevant_files.txt") > 0) files[line]=1 }
/^diff --git/ {
@@ -109,12 +130,12 @@ jobs:
}
printing { print }
' full_diff.diff > filtered_diff.diff
rm -f full_diff.diff
else
touch filtered_diff.diff
fi
rm -f full_diff.diff
- name: ci/analyze-tests
id: ai-analysis
continue-on-error: true