From 9c1718697b73570947db3004db6102fdc514f4d2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Jul 2026 19:44:44 +0000 Subject: [PATCH 1/2] Initial plan From dce245bed03ce61b12e4bdfe075993cbd9bcb360 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Jul 2026 20:09:06 +0000 Subject: [PATCH 2/2] feat: consolidate PR data pre-fetch across three skills-reviewer workflows Extract the duplicate pre-agent-steps from pr-code-quality-reviewer, impeccable-skills-reviewer, and mattpocock-skills-reviewer into a new shared/pr-diff-data-fetch.md component. Add a new pr-data-prefetch.yml (non-agentic) workflow that warms the Actions cache (key: pr-prefetch-) before reviewer agent jobs start, so all three reviewers can skip their GitHub API calls on cache hit. This reduces the three independent GitHub API fetch sets (~9 calls) to one shared fetch (~3 calls) per PR event, saving ~10k REST API quota/day. Closes #47345 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../impeccable-skills-reviewer.lock.yml | 24 ++--- .../workflows/impeccable-skills-reviewer.md | 36 +------- .../mattpocock-skills-reviewer.lock.yml | 25 +++--- .../workflows/mattpocock-skills-reviewer.md | 8 +- .../pr-code-quality-reviewer.lock.yml | 22 ++--- .github/workflows/pr-code-quality-reviewer.md | 36 +------- .github/workflows/pr-data-prefetch.yml | 66 ++++++++++++++ .../workflows/shared/pr-diff-data-fetch.md | 90 +++++++++++++++++++ 8 files changed, 198 insertions(+), 109 deletions(-) create mode 100644 .github/workflows/pr-data-prefetch.yml create mode 100644 .github/workflows/shared/pr-diff-data-fetch.md diff --git a/.github/workflows/impeccable-skills-reviewer.lock.yml b/.github/workflows/impeccable-skills-reviewer.lock.yml index 3feb4387503..c0f0418a68b 100644 --- a/.github/workflows/impeccable-skills-reviewer.lock.yml +++ b/.github/workflows/impeccable-skills-reviewer.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"078e036dc1a46842b6ba0c04f837c6f3b4cd5037fa233a6cdbf6372b59968afe","body_hash":"b435c26a5e5cef9f62e5753e0887491b004baa190720e8923247b24e075dd736","strict":true,"agent_id":"copilot","agent_model":"claude-sonnet-4.6","engine_versions":{"copilot":"1.0.73"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"dcc67503304dfe7aab4dc7fe8d2864e75cb1ab41de1cbaa581500f2dffe8f4cc","body_hash":"0df7a92b23cd4452a265ba08251279f34766f7852c439148505e48bd9493c02f","strict":true,"agent_id":"copilot","agent_model":"claude-sonnet-4.6","engine_versions":{"copilot":"1.0.73"}} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.37","digest":"sha256:0d35e8682845f183c1c634699a8e8a6cbe2c271b867031410df74533243c5f67","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.37@sha256:0d35e8682845f183c1c634699a8e8a6cbe2c271b867031410df74533243c5f67"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.37","digest":"sha256:fc2970aadaeae05993e76697d29f03dc8bfb9248ff87a8f3d8b0975485a4b317","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.37@sha256:fc2970aadaeae05993e76697d29f03dc8bfb9248ff87a8f3d8b0975485a4b317"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.37","digest":"sha256:1d5300d9b08e1c4f2ad1830860656a0656383a83280058f17e805a7c3ecda203","pinned_image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.37@sha256:1d5300d9b08e1c4f2ad1830860656a0656383a83280058f17e805a7c3ecda203"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.37","digest":"sha256:5abc51995e5901c5d1daeefc957301ee409980e2e607391ec22c06cb2513327b","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.37@sha256:5abc51995e5901c5d1daeefc957301ee409980e2e607391ec22c06cb2513327b"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.3","digest":"sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"}],"has_pull_request":true} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -30,6 +30,7 @@ # - shared/github-guard-policy.md # - shared/otlp.md # - shared/pr-code-review-config.md +# - shared/pr-diff-data-fetch.md # - shared/pr-review-base.md # - shared/reporting.md # @@ -298,20 +299,20 @@ jobs: run: | bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { - cat << 'GH_AW_PROMPT_6cb4a7bbd64e8acd_EOF' + cat << 'GH_AW_PROMPT_1ecd0bff414ab596_EOF' - GH_AW_PROMPT_6cb4a7bbd64e8acd_EOF + GH_AW_PROMPT_1ecd0bff414ab596_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_6cb4a7bbd64e8acd_EOF' + cat << 'GH_AW_PROMPT_1ecd0bff414ab596_EOF' Tools: add_comment, create_pull_request_review_comment(max:10), submit_pull_request_review, create_check_run, missing_tool, missing_data, noop - GH_AW_PROMPT_6cb4a7bbd64e8acd_EOF + GH_AW_PROMPT_1ecd0bff414ab596_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_6cb4a7bbd64e8acd_EOF' + cat << 'GH_AW_PROMPT_1ecd0bff414ab596_EOF' The following GitHub context information is available for this workflow: {{#if github.actor}} @@ -340,16 +341,17 @@ jobs: {{/if}} - GH_AW_PROMPT_6cb4a7bbd64e8acd_EOF + GH_AW_PROMPT_1ecd0bff414ab596_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/cli_proxy_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_6cb4a7bbd64e8acd_EOF' + cat << 'GH_AW_PROMPT_1ecd0bff414ab596_EOF' {{#runtime-import .github/workflows/shared/reporting.md}} {{#runtime-import .github/workflows/shared/otlp.md}} + {{#runtime-import .github/workflows/shared/pr-diff-data-fetch.md}} {{#runtime-import .github/workflows/shared/github-guard-policy.md}} {{#runtime-import .github/workflows/shared/pr-code-review-config.md}} {{#runtime-import .github/workflows/impeccable-skills-reviewer.md}} - GH_AW_PROMPT_6cb4a7bbd64e8acd_EOF + GH_AW_PROMPT_1ecd0bff414ab596_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -593,9 +595,9 @@ jobs: EXPR_GITHUB_REPOSITORY: ${{ github.repository }} GH_TOKEN: ${{ github.token }} PR_DIFF_MAX_LINES: "3000" - PR_NUMBER: ${{ github.event.pull_request.number }} + PR_NUMBER: ${{ github.event.issue.number || github.event.pull_request.number }} name: Pre-fetch PR diff and review comments - run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/agent\n# Skip fetch if cache already populated this data (actions/cache restore)\nif [ -f /tmp/gh-aw/agent/pr-diff.patch ] && [ -f /tmp/gh-aw/agent/pr-meta.json ] && [ -f /tmp/gh-aw/agent/pr-review-comments.json ]; then\n LINES=$(wc -l < /tmp/gh-aw/agent/pr-diff.patch)\n COMMENT_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-review-comments.json)\n echo \"Cache hit: using pre-fetched PR data (${LINES} diff lines, ${COMMENT_COUNT} review comments)\"\nelse\n { gh pr diff \"$PR_NUMBER\" --repo $EXPR_GITHUB_REPOSITORY \\\n --exclude '**/*.lock.yml' \\\n --exclude '**/generated/**' \\\n --exclude '**/dist/**' \\\n --exclude '**/build/**' \\\n || true; } | head -n \"${PR_DIFF_MAX_LINES}\" > /tmp/gh-aw/agent/pr-diff.patch\n LINES=$(wc -l < /tmp/gh-aw/agent/pr-diff.patch)\n gh pr view \"$PR_NUMBER\" \\\n --repo $EXPR_GITHUB_REPOSITORY \\\n --json number,title,body,headRefName,additions,deletions,changedFiles,files \\\n > /tmp/gh-aw/agent/pr-meta.json\n gh api \"repos/$EXPR_GITHUB_REPOSITORY/pulls/$PR_NUMBER/comments\" \\\n --paginate \\\n --jq '.[] | {id, path, line: (.line // .original_line), body: .body[:200], user: .user.login}' \\\n 2>/dev/null | jq -s '.' > /tmp/gh-aw/agent/pr-review-comments.json \\\n || echo '[]' > /tmp/gh-aw/agent/pr-review-comments.json\n COMMENT_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-review-comments.json)\n echo \"Pre-fetched PR diff (${LINES} lines), metadata, and ${COMMENT_COUNT} existing review comments\"\nfi" + run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/agent\n# Skip fetch if cache already populated this data (actions/cache restore)\nif [ -f /tmp/gh-aw/agent/pr-diff.patch ] && [ -f /tmp/gh-aw/agent/pr-meta.json ] && [ -f /tmp/gh-aw/agent/pr-review-comments.json ]; then\n LINES=$(wc -l < /tmp/gh-aw/agent/pr-diff.patch)\n COMMENT_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-review-comments.json)\n echo \"Cache hit: using pre-fetched PR data (${LINES} diff lines, ${COMMENT_COUNT} review comments)\"\nelse\n { gh pr diff \"$PR_NUMBER\" --repo $EXPR_GITHUB_REPOSITORY \\\n --exclude '**/*.lock.yml' \\\n --exclude '**/generated/**' \\\n --exclude '**/dist/**' \\\n --exclude '**/build/**' \\\n || true; } | head -n \"${PR_DIFF_MAX_LINES}\" > /tmp/gh-aw/agent/pr-diff.patch\n LINES=$(wc -l < /tmp/gh-aw/agent/pr-diff.patch)\n gh pr view \"$PR_NUMBER\" \\\n --repo $EXPR_GITHUB_REPOSITORY \\\n --json number,title,body,headRefName,additions,deletions,changedFiles,files \\\n > /tmp/gh-aw/agent/pr-meta.json\n gh api \"repos/$EXPR_GITHUB_REPOSITORY/pulls/$PR_NUMBER/comments\" \\\n --paginate \\\n --jq '.[] | {id, path, line: (.line // .original_line), body: .body[:200], user: .user.login}' \\\n 2>/dev/null | jq -s '.' > /tmp/gh-aw/agent/pr-review-comments.json \\\n || echo '[]' > /tmp/gh-aw/agent/pr-review-comments.json\n COMMENT_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-review-comments.json)\n echo \"Pre-fetched PR diff (${LINES} lines), metadata, and ${COMMENT_COUNT} existing review comments\"\nfi\n" - name: Download container images run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.37@sha256:0d35e8682845f183c1c634699a8e8a6cbe2c271b867031410df74533243c5f67 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.37@sha256:fc2970aadaeae05993e76697d29f03dc8bfb9248ff87a8f3d8b0975485a4b317 ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.37@sha256:1d5300d9b08e1c4f2ad1830860656a0656383a83280058f17e805a7c3ecda203 ghcr.io/github/gh-aw-firewall/squid:0.27.37@sha256:5abc51995e5901c5d1daeefc957301ee409980e2e607391ec22c06cb2513327b ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 diff --git a/.github/workflows/impeccable-skills-reviewer.md b/.github/workflows/impeccable-skills-reviewer.md index e5c65343c75..66385969935 100644 --- a/.github/workflows/impeccable-skills-reviewer.md +++ b/.github/workflows/impeccable-skills-reviewer.md @@ -31,41 +31,7 @@ imports: min-integrity: approved - shared/reporting.md - shared/otlp.md -pre-agent-steps: - - name: Pre-fetch PR diff and review comments - env: - GH_TOKEN: ${{ github.token }} - PR_NUMBER: ${{ github.event.pull_request.number }} - EXPR_GITHUB_REPOSITORY: ${{ github.repository }} - PR_DIFF_MAX_LINES: "3000" - run: | - set -euo pipefail - mkdir -p /tmp/gh-aw/agent - # Skip fetch if cache already populated this data (actions/cache restore) - if [ -f /tmp/gh-aw/agent/pr-diff.patch ] && [ -f /tmp/gh-aw/agent/pr-meta.json ] && [ -f /tmp/gh-aw/agent/pr-review-comments.json ]; then - LINES=$(wc -l < /tmp/gh-aw/agent/pr-diff.patch) - COMMENT_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-review-comments.json) - echo "Cache hit: using pre-fetched PR data (${LINES} diff lines, ${COMMENT_COUNT} review comments)" - else - { gh pr diff "$PR_NUMBER" --repo $EXPR_GITHUB_REPOSITORY \ - --exclude '**/*.lock.yml' \ - --exclude '**/generated/**' \ - --exclude '**/dist/**' \ - --exclude '**/build/**' \ - || true; } | head -n "${PR_DIFF_MAX_LINES}" > /tmp/gh-aw/agent/pr-diff.patch - LINES=$(wc -l < /tmp/gh-aw/agent/pr-diff.patch) - gh pr view "$PR_NUMBER" \ - --repo $EXPR_GITHUB_REPOSITORY \ - --json number,title,body,headRefName,additions,deletions,changedFiles,files \ - > /tmp/gh-aw/agent/pr-meta.json - gh api "repos/$EXPR_GITHUB_REPOSITORY/pulls/$PR_NUMBER/comments" \ - --paginate \ - --jq '.[] | {id, path, line: (.line // .original_line), body: .body[:200], user: .user.login}' \ - 2>/dev/null | jq -s '.' > /tmp/gh-aw/agent/pr-review-comments.json \ - || echo '[]' > /tmp/gh-aw/agent/pr-review-comments.json - COMMENT_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-review-comments.json) - echo "Pre-fetched PR diff (${LINES} lines), metadata, and ${COMMENT_COUNT} existing review comments" - fi + - shared/pr-diff-data-fetch.md tools: cli-proxy: true github: diff --git a/.github/workflows/mattpocock-skills-reviewer.lock.yml b/.github/workflows/mattpocock-skills-reviewer.lock.yml index 0beeb34a34c..45a29339f7d 100644 --- a/.github/workflows/mattpocock-skills-reviewer.lock.yml +++ b/.github/workflows/mattpocock-skills-reviewer.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"969935ad2761c6daf7158f7830cc4e1401f4f9a681fe22f46727fce79de514fb","body_hash":"c3f13ade4281614d5d35cd7ef735b734cbaa16e58f505b5b3e6670f75b405b42","strict":true,"agent_id":"copilot","agent_model":"claude-sonnet-4.6","engine_versions":{"copilot":"1.0.73"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"abd182c5f361df971b0e3c98e6648ca7bdf0f41a7f4db09563dc917970e665c9","body_hash":"c3f13ade4281614d5d35cd7ef735b734cbaa16e58f505b5b3e6670f75b405b42","strict":true,"agent_id":"copilot","agent_model":"claude-sonnet-4.6","engine_versions":{"copilot":"1.0.73"}} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"skills":["mattpocock/skills/codebase-design@e9fcdf95b402d360f90f1db8d776d5dd450f9234","mattpocock/skills/diagnosing-bugs@e9fcdf95b402d360f90f1db8d776d5dd450f9234","mattpocock/skills/domain-modeling@e9fcdf95b402d360f90f1db8d776d5dd450f9234","mattpocock/skills/grill-with-docs@e9fcdf95b402d360f90f1db8d776d5dd450f9234","mattpocock/skills/improve-codebase-architecture@e9fcdf95b402d360f90f1db8d776d5dd450f9234","mattpocock/skills/tdd@e9fcdf95b402d360f90f1db8d776d5dd450f9234","mattpocock/skills/to-prd@e9fcdf95b402d360f90f1db8d776d5dd450f9234"],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.37","digest":"sha256:0d35e8682845f183c1c634699a8e8a6cbe2c271b867031410df74533243c5f67","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.37@sha256:0d35e8682845f183c1c634699a8e8a6cbe2c271b867031410df74533243c5f67"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.37","digest":"sha256:fc2970aadaeae05993e76697d29f03dc8bfb9248ff87a8f3d8b0975485a4b317","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.37@sha256:fc2970aadaeae05993e76697d29f03dc8bfb9248ff87a8f3d8b0975485a4b317"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.37","digest":"sha256:1d5300d9b08e1c4f2ad1830860656a0656383a83280058f17e805a7c3ecda203","pinned_image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.37@sha256:1d5300d9b08e1c4f2ad1830860656a0656383a83280058f17e805a7c3ecda203"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.37","digest":"sha256:5abc51995e5901c5d1daeefc957301ee409980e2e607391ec22c06cb2513327b","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.37@sha256:5abc51995e5901c5d1daeefc957301ee409980e2e607391ec22c06cb2513327b"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.3","digest":"sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"}],"has_pull_request":true} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -30,6 +30,7 @@ # - shared/github-guard-policy.md # - shared/otlp.md # - shared/pr-code-review-config.md +# - shared/pr-diff-data-fetch.md # - shared/pr-review-base.md # # Secrets used: @@ -440,20 +441,20 @@ jobs: run: | bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { - cat << 'GH_AW_PROMPT_ea16154323c40356_EOF' + cat << 'GH_AW_PROMPT_2cd9473c357e7085_EOF' - GH_AW_PROMPT_ea16154323c40356_EOF + GH_AW_PROMPT_2cd9473c357e7085_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_ea16154323c40356_EOF' + cat << 'GH_AW_PROMPT_2cd9473c357e7085_EOF' Tools: add_comment, create_pull_request_review_comment(max:10), submit_pull_request_review, create_check_run, missing_tool, missing_data, noop - GH_AW_PROMPT_ea16154323c40356_EOF + GH_AW_PROMPT_2cd9473c357e7085_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_ea16154323c40356_EOF' + cat << 'GH_AW_PROMPT_2cd9473c357e7085_EOF' The following GitHub context information is available for this workflow: {{#if github.actor}} @@ -482,18 +483,19 @@ jobs: {{/if}} - GH_AW_PROMPT_ea16154323c40356_EOF + GH_AW_PROMPT_2cd9473c357e7085_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/cli_proxy_with_safeoutputs_prompt.md" if [ "$GITHUB_EVENT_NAME" = "issue_comment" ] && [ -n "$GH_AW_IS_PR_COMMENT" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review" ]; then cat "${RUNNER_TEMP}/gh-aw/prompts/pr_context_prompt.md" fi - cat << 'GH_AW_PROMPT_ea16154323c40356_EOF' + cat << 'GH_AW_PROMPT_2cd9473c357e7085_EOF' {{#runtime-import .github/workflows/shared/otlp.md}} + {{#runtime-import .github/workflows/shared/pr-diff-data-fetch.md}} {{#runtime-import .github/workflows/shared/github-guard-policy.md}} {{#runtime-import .github/workflows/shared/pr-code-review-config.md}} {{#runtime-import .github/workflows/mattpocock-skills-reviewer.md}} - GH_AW_PROMPT_ea16154323c40356_EOF + GH_AW_PROMPT_2cd9473c357e7085_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -740,9 +742,10 @@ jobs: - env: EXPR_GITHUB_REPOSITORY: ${{ github.repository }} GH_TOKEN: ${{ github.token }} - PR_NUMBER: ${{ github.event.pull_request.number }} + PR_DIFF_MAX_LINES: "3000" + PR_NUMBER: ${{ github.event.issue.number || github.event.pull_request.number }} name: Pre-fetch PR diff and review comments - run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/agent\n# Skip fetch if cache already populated this data (actions/cache restore)\nif [ -f /tmp/gh-aw/agent/pr-diff.patch ] && [ -f /tmp/gh-aw/agent/pr-meta.json ] && [ -f /tmp/gh-aw/agent/pr-review-comments.json ]; then\n LINES=$(wc -l < /tmp/gh-aw/agent/pr-diff.patch)\n COMMENT_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-review-comments.json)\n echo \"Cache hit: using pre-fetched PR data (${LINES} diff lines, ${COMMENT_COUNT} review comments)\"\nelse\n { gh pr diff \"$PR_NUMBER\" --repo $EXPR_GITHUB_REPOSITORY \\\n --exclude '**/*.lock.yml' \\\n --exclude '**/generated/**' \\\n --exclude '**/dist/**' \\\n --exclude '**/build/**' \\\n || true; } | head -n 3000 > /tmp/gh-aw/agent/pr-diff.patch\n LINES=$(wc -l < /tmp/gh-aw/agent/pr-diff.patch)\n gh pr view \"$PR_NUMBER\" \\\n --repo $EXPR_GITHUB_REPOSITORY \\\n --json number,title,body,headRefName,additions,deletions,changedFiles,files \\\n > /tmp/gh-aw/agent/pr-meta.json\n gh api \"repos/$EXPR_GITHUB_REPOSITORY/pulls/$PR_NUMBER/comments\" \\\n --paginate \\\n --jq '.[] | {id, path, line: (.line // .original_line), body: .body[:200], user: .user.login}' \\\n 2>/dev/null | jq -s '.' > /tmp/gh-aw/agent/pr-review-comments.json \\\n || echo '[]' > /tmp/gh-aw/agent/pr-review-comments.json\n COMMENT_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-review-comments.json)\n echo \"Pre-fetched PR diff (${LINES} lines), metadata, and ${COMMENT_COUNT} existing review comments\"\nfi" + run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/agent\n# Skip fetch if cache already populated this data (actions/cache restore)\nif [ -f /tmp/gh-aw/agent/pr-diff.patch ] && [ -f /tmp/gh-aw/agent/pr-meta.json ] && [ -f /tmp/gh-aw/agent/pr-review-comments.json ]; then\n LINES=$(wc -l < /tmp/gh-aw/agent/pr-diff.patch)\n COMMENT_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-review-comments.json)\n echo \"Cache hit: using pre-fetched PR data (${LINES} diff lines, ${COMMENT_COUNT} review comments)\"\nelse\n { gh pr diff \"$PR_NUMBER\" --repo $EXPR_GITHUB_REPOSITORY \\\n --exclude '**/*.lock.yml' \\\n --exclude '**/generated/**' \\\n --exclude '**/dist/**' \\\n --exclude '**/build/**' \\\n || true; } | head -n \"${PR_DIFF_MAX_LINES}\" > /tmp/gh-aw/agent/pr-diff.patch\n LINES=$(wc -l < /tmp/gh-aw/agent/pr-diff.patch)\n gh pr view \"$PR_NUMBER\" \\\n --repo $EXPR_GITHUB_REPOSITORY \\\n --json number,title,body,headRefName,additions,deletions,changedFiles,files \\\n > /tmp/gh-aw/agent/pr-meta.json\n gh api \"repos/$EXPR_GITHUB_REPOSITORY/pulls/$PR_NUMBER/comments\" \\\n --paginate \\\n --jq '.[] | {id, path, line: (.line // .original_line), body: .body[:200], user: .user.login}' \\\n 2>/dev/null | jq -s '.' > /tmp/gh-aw/agent/pr-review-comments.json \\\n || echo '[]' > /tmp/gh-aw/agent/pr-review-comments.json\n COMMENT_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-review-comments.json)\n echo \"Pre-fetched PR diff (${LINES} lines), metadata, and ${COMMENT_COUNT} existing review comments\"\nfi\n" - name: Download container images run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.37@sha256:0d35e8682845f183c1c634699a8e8a6cbe2c271b867031410df74533243c5f67 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.37@sha256:fc2970aadaeae05993e76697d29f03dc8bfb9248ff87a8f3d8b0975485a4b317 ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.37@sha256:1d5300d9b08e1c4f2ad1830860656a0656383a83280058f17e805a7c3ecda203 ghcr.io/github/gh-aw-firewall/squid:0.27.37@sha256:5abc51995e5901c5d1daeefc957301ee409980e2e607391ec22c06cb2513327b ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 diff --git a/.github/workflows/mattpocock-skills-reviewer.md b/.github/workflows/mattpocock-skills-reviewer.md index 626fa9fac87..f961b788978 100644 --- a/.github/workflows/mattpocock-skills-reviewer.md +++ b/.github/workflows/mattpocock-skills-reviewer.md @@ -15,6 +15,7 @@ imports: with: min-integrity: approved - shared/otlp.md +- shared/pr-diff-data-fetch.md max-daily-ai-credits: 10000 "on": pull_request: @@ -36,13 +37,6 @@ permissions: contents: read copilot-requests: write pull-requests: read -pre-agent-steps: -- env: - EXPR_GITHUB_REPOSITORY: ${{ github.repository }} - GH_TOKEN: ${{ github.token }} - PR_NUMBER: ${{ github.event.pull_request.number }} - name: Pre-fetch PR diff and review comments - run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/agent\n# Skip fetch if cache already populated this data (actions/cache restore)\nif [ -f /tmp/gh-aw/agent/pr-diff.patch ] && [ -f /tmp/gh-aw/agent/pr-meta.json ] && [ -f /tmp/gh-aw/agent/pr-review-comments.json ]; then\n LINES=$(wc -l < /tmp/gh-aw/agent/pr-diff.patch)\n COMMENT_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-review-comments.json)\n echo \"Cache hit: using pre-fetched PR data (${LINES} diff lines, ${COMMENT_COUNT} review comments)\"\nelse\n { gh pr diff \"$PR_NUMBER\" --repo $EXPR_GITHUB_REPOSITORY \\\n --exclude '**/*.lock.yml' \\\n --exclude '**/generated/**' \\\n --exclude '**/dist/**' \\\n --exclude '**/build/**' \\\n || true; } | head -n 3000 > /tmp/gh-aw/agent/pr-diff.patch\n LINES=$(wc -l < /tmp/gh-aw/agent/pr-diff.patch)\n gh pr view \"$PR_NUMBER\" \\\n --repo $EXPR_GITHUB_REPOSITORY \\\n --json number,title,body,headRefName,additions,deletions,changedFiles,files \\\n > /tmp/gh-aw/agent/pr-meta.json\n gh api \"repos/$EXPR_GITHUB_REPOSITORY/pulls/$PR_NUMBER/comments\" \\\n --paginate \\\n --jq '.[] | {id, path, line: (.line // .original_line), body: .body[:200], user: .user.login}' \\\n 2>/dev/null | jq -s '.' > /tmp/gh-aw/agent/pr-review-comments.json \\\n || echo '[]' > /tmp/gh-aw/agent/pr-review-comments.json\n COMMENT_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-review-comments.json)\n echo \"Pre-fetched PR diff (${LINES} lines), metadata, and ${COMMENT_COUNT} existing review comments\"\nfi\n" private: true safe-outputs: add-comment: diff --git a/.github/workflows/pr-code-quality-reviewer.lock.yml b/.github/workflows/pr-code-quality-reviewer.lock.yml index 33d32653f30..74df6cfc1d1 100644 --- a/.github/workflows/pr-code-quality-reviewer.lock.yml +++ b/.github/workflows/pr-code-quality-reviewer.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"0c69e6deb2f09caf40c0be4b50c85cfaab267aa309a6dba5f814f206f1ce8bb4","body_hash":"4d55b623130b9bead500146cadaa2e5eca54cc42cee576aee4c10ed8414d3a61","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.73","copilot-sdk":"1.0.7"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"d007a0c73e765f7ec52a80be0da757eb62e04678741ee889512feffc7ca64fc3","body_hash":"4890b58adb822a064eec8f86b1770258890fab221abd2308d69ebb840746adda","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.73","copilot-sdk":"1.0.7"}} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.37","digest":"sha256:0d35e8682845f183c1c634699a8e8a6cbe2c271b867031410df74533243c5f67","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.37@sha256:0d35e8682845f183c1c634699a8e8a6cbe2c271b867031410df74533243c5f67"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.37","digest":"sha256:fc2970aadaeae05993e76697d29f03dc8bfb9248ff87a8f3d8b0975485a4b317","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.37@sha256:fc2970aadaeae05993e76697d29f03dc8bfb9248ff87a8f3d8b0975485a4b317"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.37","digest":"sha256:1d5300d9b08e1c4f2ad1830860656a0656383a83280058f17e805a7c3ecda203","pinned_image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.37@sha256:1d5300d9b08e1c4f2ad1830860656a0656383a83280058f17e805a7c3ecda203"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.37","digest":"sha256:5abc51995e5901c5d1daeefc957301ee409980e2e607391ec22c06cb2513327b","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.37@sha256:5abc51995e5901c5d1daeefc957301ee409980e2e607391ec22c06cb2513327b"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.3","digest":"sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"}],"has_pull_request":true} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -30,6 +30,7 @@ # - shared/github-guard-policy.md # - shared/otlp.md # - shared/pr-code-review-config.md +# - shared/pr-diff-data-fetch.md # - shared/pr-review-base.md # # Secrets used: @@ -326,21 +327,21 @@ jobs: run: | bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { - cat << 'GH_AW_PROMPT_88dd0adb3937cc31_EOF' + cat << 'GH_AW_PROMPT_896d10e6e512745a_EOF' - GH_AW_PROMPT_88dd0adb3937cc31_EOF + GH_AW_PROMPT_896d10e6e512745a_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_88dd0adb3937cc31_EOF' + cat << 'GH_AW_PROMPT_896d10e6e512745a_EOF' Tools: create_pull_request_review_comment(max:10), submit_pull_request_review, create_check_run, missing_tool, missing_data, noop - GH_AW_PROMPT_88dd0adb3937cc31_EOF + GH_AW_PROMPT_896d10e6e512745a_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_88dd0adb3937cc31_EOF' + cat << 'GH_AW_PROMPT_896d10e6e512745a_EOF' The following GitHub context information is available for this workflow: {{#if github.actor}} @@ -369,18 +370,19 @@ jobs: {{/if}} - GH_AW_PROMPT_88dd0adb3937cc31_EOF + GH_AW_PROMPT_896d10e6e512745a_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/cli_proxy_with_safeoutputs_prompt.md" if [ "$GITHUB_EVENT_NAME" = "issue_comment" ] && [ -n "$GH_AW_IS_PR_COMMENT" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review" ]; then cat "${RUNNER_TEMP}/gh-aw/prompts/pr_context_prompt.md" fi - cat << 'GH_AW_PROMPT_88dd0adb3937cc31_EOF' + cat << 'GH_AW_PROMPT_896d10e6e512745a_EOF' {{#runtime-import .github/workflows/shared/otlp.md}} + {{#runtime-import .github/workflows/shared/pr-diff-data-fetch.md}} {{#runtime-import .github/workflows/shared/github-guard-policy.md}} {{#runtime-import .github/workflows/shared/pr-code-review-config.md}} {{#runtime-import .github/workflows/pr-code-quality-reviewer.md}} - GH_AW_PROMPT_88dd0adb3937cc31_EOF + GH_AW_PROMPT_896d10e6e512745a_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -654,7 +656,7 @@ jobs: PR_DIFF_MAX_LINES: "3000" PR_NUMBER: ${{ github.event.issue.number || github.event.pull_request.number }} name: Pre-fetch PR diff and review comments - run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/agent\n# Skip fetch if cache already populated this data (actions/cache restore)\nif [ -f /tmp/gh-aw/agent/pr-diff.patch ] && [ -f /tmp/gh-aw/agent/pr-meta.json ] && [ -f /tmp/gh-aw/agent/pr-review-comments.json ]; then\n LINES=$(wc -l < /tmp/gh-aw/agent/pr-diff.patch)\n COMMENT_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-review-comments.json)\n echo \"Cache hit: using pre-fetched PR data (${LINES} diff lines, ${COMMENT_COUNT} review comments)\"\nelse\n { gh pr diff \"$PR_NUMBER\" --repo $EXPR_GITHUB_REPOSITORY \\\n --exclude '**/*.lock.yml' \\\n --exclude '**/generated/**' \\\n --exclude '**/dist/**' \\\n --exclude '**/build/**' \\\n || true; } | head -n \"${PR_DIFF_MAX_LINES}\" > /tmp/gh-aw/agent/pr-diff.patch\n LINES=$(wc -l < /tmp/gh-aw/agent/pr-diff.patch)\n gh pr view \"$PR_NUMBER\" \\\n --repo $EXPR_GITHUB_REPOSITORY \\\n --json number,title,body,headRefName,additions,deletions,changedFiles,files \\\n > /tmp/gh-aw/agent/pr-meta.json\n gh api \"repos/$EXPR_GITHUB_REPOSITORY/pulls/$PR_NUMBER/comments\" \\\n --paginate \\\n --jq '.[] | {id, path, line: (.line // .original_line), body: .body[:200], user: .user.login}' \\\n 2>/dev/null | jq -s '.' > /tmp/gh-aw/agent/pr-review-comments.json \\\n || echo '[]' > /tmp/gh-aw/agent/pr-review-comments.json\n COMMENT_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-review-comments.json)\n echo \"Pre-fetched PR diff (${LINES} lines), metadata, and ${COMMENT_COUNT} existing review comments\"\nfi" + run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/agent\n# Skip fetch if cache already populated this data (actions/cache restore)\nif [ -f /tmp/gh-aw/agent/pr-diff.patch ] && [ -f /tmp/gh-aw/agent/pr-meta.json ] && [ -f /tmp/gh-aw/agent/pr-review-comments.json ]; then\n LINES=$(wc -l < /tmp/gh-aw/agent/pr-diff.patch)\n COMMENT_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-review-comments.json)\n echo \"Cache hit: using pre-fetched PR data (${LINES} diff lines, ${COMMENT_COUNT} review comments)\"\nelse\n { gh pr diff \"$PR_NUMBER\" --repo $EXPR_GITHUB_REPOSITORY \\\n --exclude '**/*.lock.yml' \\\n --exclude '**/generated/**' \\\n --exclude '**/dist/**' \\\n --exclude '**/build/**' \\\n || true; } | head -n \"${PR_DIFF_MAX_LINES}\" > /tmp/gh-aw/agent/pr-diff.patch\n LINES=$(wc -l < /tmp/gh-aw/agent/pr-diff.patch)\n gh pr view \"$PR_NUMBER\" \\\n --repo $EXPR_GITHUB_REPOSITORY \\\n --json number,title,body,headRefName,additions,deletions,changedFiles,files \\\n > /tmp/gh-aw/agent/pr-meta.json\n gh api \"repos/$EXPR_GITHUB_REPOSITORY/pulls/$PR_NUMBER/comments\" \\\n --paginate \\\n --jq '.[] | {id, path, line: (.line // .original_line), body: .body[:200], user: .user.login}' \\\n 2>/dev/null | jq -s '.' > /tmp/gh-aw/agent/pr-review-comments.json \\\n || echo '[]' > /tmp/gh-aw/agent/pr-review-comments.json\n COMMENT_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-review-comments.json)\n echo \"Pre-fetched PR diff (${LINES} lines), metadata, and ${COMMENT_COUNT} existing review comments\"\nfi\n" - name: Download container images run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.37@sha256:0d35e8682845f183c1c634699a8e8a6cbe2c271b867031410df74533243c5f67 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.37@sha256:fc2970aadaeae05993e76697d29f03dc8bfb9248ff87a8f3d8b0975485a4b317 ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.37@sha256:1d5300d9b08e1c4f2ad1830860656a0656383a83280058f17e805a7c3ecda203 ghcr.io/github/gh-aw-firewall/squid:0.27.37@sha256:5abc51995e5901c5d1daeefc957301ee409980e2e607391ec22c06cb2513327b ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 diff --git a/.github/workflows/pr-code-quality-reviewer.md b/.github/workflows/pr-code-quality-reviewer.md index 32e7c37fcd3..b2e4ccfd688 100644 --- a/.github/workflows/pr-code-quality-reviewer.md +++ b/.github/workflows/pr-code-quality-reviewer.md @@ -39,6 +39,7 @@ imports: with: min-integrity: approved - shared/otlp.md + - shared/pr-diff-data-fetch.md tools: cli-proxy: true github: @@ -60,41 +61,6 @@ safe-outputs: run-started: "🔎 [{workflow_name}]({run_url}) is reviewing code quality for this {event_type}..." run-success: "✅ [{workflow_name}]({run_url}) completed the code quality review." run-failure: "⚠️ [{workflow_name}]({run_url}) {status} during code quality review." -pre-agent-steps: - - name: Pre-fetch PR diff and review comments - env: - GH_TOKEN: ${{ github.token }} - PR_NUMBER: ${{ github.event.issue.number || github.event.pull_request.number }} - EXPR_GITHUB_REPOSITORY: ${{ github.repository }} - PR_DIFF_MAX_LINES: "3000" - run: | - set -euo pipefail - mkdir -p /tmp/gh-aw/agent - # Skip fetch if cache already populated this data (actions/cache restore) - if [ -f /tmp/gh-aw/agent/pr-diff.patch ] && [ -f /tmp/gh-aw/agent/pr-meta.json ] && [ -f /tmp/gh-aw/agent/pr-review-comments.json ]; then - LINES=$(wc -l < /tmp/gh-aw/agent/pr-diff.patch) - COMMENT_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-review-comments.json) - echo "Cache hit: using pre-fetched PR data (${LINES} diff lines, ${COMMENT_COUNT} review comments)" - else - { gh pr diff "$PR_NUMBER" --repo $EXPR_GITHUB_REPOSITORY \ - --exclude '**/*.lock.yml' \ - --exclude '**/generated/**' \ - --exclude '**/dist/**' \ - --exclude '**/build/**' \ - || true; } | head -n "${PR_DIFF_MAX_LINES}" > /tmp/gh-aw/agent/pr-diff.patch - LINES=$(wc -l < /tmp/gh-aw/agent/pr-diff.patch) - gh pr view "$PR_NUMBER" \ - --repo $EXPR_GITHUB_REPOSITORY \ - --json number,title,body,headRefName,additions,deletions,changedFiles,files \ - > /tmp/gh-aw/agent/pr-meta.json - gh api "repos/$EXPR_GITHUB_REPOSITORY/pulls/$PR_NUMBER/comments" \ - --paginate \ - --jq '.[] | {id, path, line: (.line // .original_line), body: .body[:200], user: .user.login}' \ - 2>/dev/null | jq -s '.' > /tmp/gh-aw/agent/pr-review-comments.json \ - || echo '[]' > /tmp/gh-aw/agent/pr-review-comments.json - COMMENT_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-review-comments.json) - echo "Pre-fetched PR diff (${LINES} lines), metadata, and ${COMMENT_COUNT} existing review comments" - fi timeout-minutes: 15 evals: - id: review_posted diff --git a/.github/workflows/pr-data-prefetch.yml b/.github/workflows/pr-data-prefetch.yml new file mode 100644 index 00000000000..a94dbb8f62e --- /dev/null +++ b/.github/workflows/pr-data-prefetch.yml @@ -0,0 +1,66 @@ +name: PR Data Prefetch +# Fetches PR diff, metadata, and review comments once per commit and saves to +# the Actions cache (key: pr-prefetch-), so the three PR reviewer workflows +# can restore from cache rather than each independently calling the GitHub API. +# +# Because this workflow has no AI engine, it completes in ~30-60 s — before the +# reviewer workflows' activation jobs finish. When the reviewer agent jobs start +# and restore the pr-prefetch- cache they get a hit and skip their own fetch. + +on: + pull_request: + types: [ready_for_review] + paths-ignore: + - '*.md' + - 'docs/**' + - '.changeset/**' + - 'socials/**' + - 'scratchpad/**' + +permissions: + contents: read + pull-requests: read + +concurrency: + # One prefetch per commit; do not cancel to avoid a gap between save and reviewer restore. + group: pr-data-prefetch-${{ github.event.pull_request.head.sha }} + cancel-in-progress: false + +jobs: + prefetch: + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Pre-fetch PR diff and review comments + env: + GH_TOKEN: ${{ github.token }} + PR_NUMBER: ${{ github.event.pull_request.number }} + GITHUB_REPOSITORY: ${{ github.repository }} + PR_DIFF_MAX_LINES: "3000" + run: | + set -euo pipefail + mkdir -p /tmp/gh-aw/agent + { gh pr diff "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" \ + --exclude '**/*.lock.yml' \ + --exclude '**/generated/**' \ + --exclude '**/dist/**' \ + --exclude '**/build/**' \ + || true; } | head -n "${PR_DIFF_MAX_LINES}" > /tmp/gh-aw/agent/pr-diff.patch + LINES=$(wc -l < /tmp/gh-aw/agent/pr-diff.patch) + gh pr view "$PR_NUMBER" \ + --repo "$GITHUB_REPOSITORY" \ + --json number,title,body,headRefName,additions,deletions,changedFiles,files \ + > /tmp/gh-aw/agent/pr-meta.json + gh api "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER/comments" \ + --paginate \ + --jq '.[] | {id, path, line: (.line // .original_line), body: .body[:200], user: .user.login}' \ + 2>/dev/null | jq -s '.' > /tmp/gh-aw/agent/pr-review-comments.json \ + || echo '[]' > /tmp/gh-aw/agent/pr-review-comments.json + COMMENT_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-review-comments.json) + echo "Pre-fetched PR diff (${LINES} lines), metadata, and ${COMMENT_COUNT} existing review comments" + + - name: Save PR data to cache + uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + key: pr-prefetch-${{ github.event.pull_request.head.sha }} + path: /tmp/gh-aw/agent diff --git a/.github/workflows/shared/pr-diff-data-fetch.md b/.github/workflows/shared/pr-diff-data-fetch.md new file mode 100644 index 00000000000..22c462ea27b --- /dev/null +++ b/.github/workflows/shared/pr-diff-data-fetch.md @@ -0,0 +1,90 @@ +--- +# Shared pre-agent-steps for pre-fetching PR diff, metadata, and review comments. +# Works for both pull_request events and slash_command (issue) events on PRs. +# +# Outputs written to: +# /tmp/gh-aw/agent/pr-diff.patch — unified diff (up to 3000 lines) +# /tmp/gh-aw/agent/pr-meta.json — PR metadata (number, title, body, etc.) +# /tmp/gh-aw/agent/pr-review-comments.json — existing inline review comments +# +# Skip-check: if all three files already exist (cache hit), fetch is skipped. +# +# Usage: +# cache: +# key: pr-prefetch-${{ github.event.pull_request.head.sha || github.event.issue.number }} +# path: /tmp/gh-aw/agent +# restore-keys: +# - pr-prefetch-${{ github.event.pull_request.number || github.event.issue.number }}- +# imports: +# - shared/pr-diff-data-fetch.md + +pre-agent-steps: + - name: Pre-fetch PR diff and review comments + env: + GH_TOKEN: ${{ github.token }} + PR_NUMBER: ${{ github.event.issue.number || github.event.pull_request.number }} + EXPR_GITHUB_REPOSITORY: ${{ github.repository }} + PR_DIFF_MAX_LINES: "3000" + run: | + set -euo pipefail + mkdir -p /tmp/gh-aw/agent + # Skip fetch if cache already populated this data (actions/cache restore) + if [ -f /tmp/gh-aw/agent/pr-diff.patch ] && [ -f /tmp/gh-aw/agent/pr-meta.json ] && [ -f /tmp/gh-aw/agent/pr-review-comments.json ]; then + LINES=$(wc -l < /tmp/gh-aw/agent/pr-diff.patch) + COMMENT_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-review-comments.json) + echo "Cache hit: using pre-fetched PR data (${LINES} diff lines, ${COMMENT_COUNT} review comments)" + else + { gh pr diff "$PR_NUMBER" --repo $EXPR_GITHUB_REPOSITORY \ + --exclude '**/*.lock.yml' \ + --exclude '**/generated/**' \ + --exclude '**/dist/**' \ + --exclude '**/build/**' \ + || true; } | head -n "${PR_DIFF_MAX_LINES}" > /tmp/gh-aw/agent/pr-diff.patch + LINES=$(wc -l < /tmp/gh-aw/agent/pr-diff.patch) + gh pr view "$PR_NUMBER" \ + --repo $EXPR_GITHUB_REPOSITORY \ + --json number,title,body,headRefName,additions,deletions,changedFiles,files \ + > /tmp/gh-aw/agent/pr-meta.json + gh api "repos/$EXPR_GITHUB_REPOSITORY/pulls/$PR_NUMBER/comments" \ + --paginate \ + --jq '.[] | {id, path, line: (.line // .original_line), body: .body[:200], user: .user.login}' \ + 2>/dev/null | jq -s '.' > /tmp/gh-aw/agent/pr-review-comments.json \ + || echo '[]' > /tmp/gh-aw/agent/pr-review-comments.json + COMMENT_COUNT=$(jq 'length' /tmp/gh-aw/agent/pr-review-comments.json) + echo "Pre-fetched PR diff (${LINES} lines), metadata, and ${COMMENT_COUNT} existing review comments" + fi +--- + +