Skip to content

fix(ci): repost Copilot reviews as @claude comments#99

Merged
maxbec merged 1 commit into
mainfrom
fix/claude-code-copilot-repost
Apr 18, 2026
Merged

fix(ci): repost Copilot reviews as @claude comments#99
maxbec merged 1 commit into
mainfrom
fix/claude-code-copilot-repost

Conversation

@maxbec

@maxbec maxbec commented Apr 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Copilot PR reviews have been silently failing claude-code-action@v1 — its checkHumanActor step calls octokit.users.getByUsername('Copilot'), which 404s because Copilot is a virtual actor with no user record. No action input bypasses that lookup (upstream PRs #1018, #1030, #1144 are all still open).

Observed on navigaite/edilio#94 run 24551381827:

Checking permissions for actor: Copilot
GET /users/Copilot - 404
Action failed with error: Not Found

Fix

Proxy Copilot reviews into an issue_comment event that Claude's existing pipeline can handle:

  • New repost-copilot-review job in the reusable claude-code.yaml. Fires only when pull_request_review.user.type == 'Bot' and login contains copilot. Mints the Navigaite workflow App token, fetches the review's inline comments via GET /pulls/:n/reviews/:id/comments, and posts a single stitched @claude … comment on the PR.
  • Skip the claude job on Copilot reviews — it would hit the 404. The spawned issue_comment re-enters the job with github.actor == 'navigaite-workflow-app[bot]', a real bot user that resolves, so checkHumanActor's allowed_bots: * branch takes over.
  • Relax the issue_comment author-association gate (both the reusable workflow step and the caller template's if:) to admit comments from navigaite-workflow-app[bot]. Reposted comments have author_association: NONE by construction — trust is anchored in the fact that only our installed app can mint its own token.

Test plan

  • Merge, re-request Copilot review on an open PR in a consumer repo, confirm: (1) repost-copilot-review job succeeds, (2) an @claude … comment appears on the PR, (3) a follow-up issue_comment run of the claude job runs to completion without the users/Copilot 404.
  • Confirm human @claude comments still trigger Claude normally (unchanged path).
  • Confirm unrelated bot comments (Dependabot, github-actions) are still filtered out by the association gate.

🤖 Generated with Claude Code

Copilot PR reviews were silently failing claude-code-action@v1 because
its `checkHumanActor` calls `octokit.users.getByUsername('Copilot')`,
which 404s — Copilot is a virtual actor with no user record. No input
bypasses that lookup (see upstream #1018 / #1030 / #1144, all open).

Add a `repost-copilot-review` job that mints the Navigaite workflow
App token, stitches the Copilot review body + inline comments into a
single `@claude` issue comment, and posts it. The resulting
`issue_comment` event fires a fresh Claude run where
`github.actor == 'navigaite-workflow-app[bot]'` — a bot user that
resolves — so `checkHumanActor` takes its `allowed_bots: *` branch.

Also relax the `issue_comment` author-association gate (reusable
workflow + caller template) to admit the reposted comment from our
own app, which has `author_association: NONE` by construction.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 18, 2026 05:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the shared Claude Code reusable workflow to handle Copilot PR review events that currently fail inside claude-code-action@v1 due to GET /users/Copilot returning 404. It does so by proxying Copilot reviews into a normal issue_comment trigger path that the existing pipeline can process safely.

Changes:

  • Add a repost-copilot-review job to fetch a Copilot review + inline comments and post a single synthesized @claude … PR comment.
  • Skip running the main claude job directly on Copilot pull_request_review events to avoid the users.getByUsername('Copilot') 404.
  • Relax issue_comment author gating (in both reusable + caller/template) to trust comments authored by navigaite-workflow-app[bot].

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
.github/workflows/claude-code.yaml Adds the Copilot-review repost job, skips direct Claude execution for Copilot reviews, and admits navigaite-workflow-app[bot] through the author gate.
.github/workflows/claude-code-fix.yaml Updates the caller workflow if: gate to allow synthesized @claude comments from navigaite-workflow-app[bot].
.github/config/templates/claude-code-fix.yaml Mirrors the caller gating change in the bootstrap template used by consumer repos.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +124 to +140
contains(github.event.review.user.login, 'copilot')
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
pull-requests: write # post the @claude issue comment
steps:
- name: 🔍 Require app secrets
shell: bash
env:
APP_ID: ${{ secrets.WORKFLOW_APP_ID }}
APP_PRIVATE_KEY: ${{ secrets.WORKFLOW_APP_PRIVATE_KEY }}
run: |
if [[ -z "$APP_ID" || -z "$APP_PRIVATE_KEY" ]]; then
echo "::error::WORKFLOW_APP_ID/WORKFLOW_APP_PRIVATE_KEY required to repost Copilot reviews."
exit 1
fi

Copilot AI Apr 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow_call docs describe WORKFLOW_APP_ID / WORKFLOW_APP_PRIVATE_KEY as optional (with fallback behavior elsewhere in this workflow), but repost-copilot-review hard-fails when they are unset. That will make Copilot review events fail the check in repos that haven’t configured these secrets. Consider gating the job on the secrets being present (so it skips cleanly) or implementing a safe fallback path (e.g., using GITHUB_TOKEN and explicitly allowing the fallback actor in the comment-author gate).

Suggested change
contains(github.event.review.user.login, 'copilot')
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
pull-requests: write # post the @claude issue comment
steps:
- name: 🔍 Require app secrets
shell: bash
env:
APP_ID: ${{ secrets.WORKFLOW_APP_ID }}
APP_PRIVATE_KEY: ${{ secrets.WORKFLOW_APP_PRIVATE_KEY }}
run: |
if [[ -z "$APP_ID" || -z "$APP_PRIVATE_KEY" ]]; then
echo "::error::WORKFLOW_APP_ID/WORKFLOW_APP_PRIVATE_KEY required to repost Copilot reviews."
exit 1
fi
contains(github.event.review.user.login, 'copilot') &&
secrets.WORKFLOW_APP_ID != '' &&
secrets.WORKFLOW_APP_PRIVATE_KEY != ''
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
pull-requests: write # post the @claude issue comment
steps:

Copilot uses AI. Check for mistakes.
Comment on lines +163 to +164
--jq '[.[] | "- **`" + .path + (if .line then ":" + (.line|tostring) else "" end) + "`** — " + .body] | join("\n\n")' \
|| echo "")"

Copilot AI Apr 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inline-comment fetch swallows any gh api error via || echo "", which can hide real failures (e.g., auth/permission issues or API errors) and still post a synthesized @claude comment missing inline context. Prefer letting the step fail on unexpected errors, or only handling the specific “no inline comments” case explicitly (empty array) while surfacing other failures.

Suggested change
--jq '[.[] | "- **`" + .path + (if .line then ":" + (.line|tostring) else "" end) + "`** — " + .body] | join("\n\n")' \
|| echo "")"
--jq '[.[] | "- **`" + .path + (if .line then ":" + (.line|tostring) else "" end) + "`** — " + .body] | join("\n\n")')"

Copilot uses AI. Check for mistakes.
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
pull-requests: write # post the @claude issue comment

Copilot AI Apr 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

repost-copilot-review posts an issue comment (/issues/:number/comments), but the job only grants pull-requests: write to GITHUB_TOKEN. If this job ever falls back to GITHUB_TOKEN (or if create-github-app-token is replaced), it will lack the issues: write permission needed to create issue comments. Consider switching this to issues: write (or issues: write + pull-requests: read if you later need PR metadata) and updating the inline comment accordingly.

Suggested change
pull-requests: write # post the @claude issue comment
issues: write # post the synthesized @claude issue comment on the PR

Copilot uses AI. Check for mistakes.
@maxbec maxbec merged commit bf6d42e into main Apr 18, 2026
@maxbec maxbec deleted the fix/claude-code-copilot-repost branch April 18, 2026 07:07
navigaite-workflow-app Bot added a commit that referenced this pull request Apr 18, 2026
🤖 I have created a release *beep* *boop*
---


## [2.6.5](v2.6.4...v2.6.5)
(2026-04-18)


### 🐛 Bug Fixes

* **ci:** repost Copilot reviews as [@claude](https://github.com/claude)
comments ([#99](#99))
([bf6d42e](bf6d42e))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: navigaite-workflow-app[bot] <133966083+navigaite-workflow-app[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants