Skip to content

ci(guardian): post reviews as the codegraph-brain GitHub App when configured - #735

Merged
zaebee merged 4 commits into
mainfrom
ci/734-guardian-app-token
Oct 22, 2026
Merged

zaebee merged 4 commits into
mainfrom
ci/734-guardian-app-token

Conversation

@zaebee

@zaebee zaebee commented Oct 22, 2026

Copy link
Copy Markdown
Owner

Closes #734.

Change

  • New step Mint GitHub App token: actions/create-github-app-token v3.2.0, pinned to its SHA.
    • It runs only when vars.GUARDIAN_APP_CLIENT_ID is set.
    • The token is scoped to this repository (repositories: ${{ github.event.repository.name }}) and to permission-pull-requests: write only.
    • It is minted after every step that touches pr/.
  • Both posting paths use steps.app-token.outputs.token || github.token: GH_TOKEN for the inline review, token: for the fallback comment.
  • Unconfigured case: with no variable, the step is skipped and the job behaves exactly as today.
  • Tests: 4 new workflow tests pin the condition, the SHA pin, the scope and permissions, the fallback on both paths and the ordering.

To switch it on (maintainer)

  1. In the app settings, generate a private key and copy the Client ID.
  2. Install the app on zaebee/codegraph-brain. With the variables set but no installation, the mint step fails the job loudly.
  3. Set the key and the client id:
    • gh secret set GUARDIAN_APP_PRIVATE_KEY --repo zaebee/codegraph-brain < key.pem
    • gh variable set GUARDIAN_APP_CLIENT_ID --repo zaebee/codegraph-brain --body <Client ID>
  4. Optional: lower the app's contents permission from write to read. Nothing here needs it.

🤖 Generated with Claude Code

…figured

With vars.GUARDIAN_APP_CLIENT_ID and secrets.GUARDIAN_APP_PRIVATE_KEY set,
the review job mints an installation token (actions/create-github-app-token
v3.2.0, pinned) and both posting paths use it, so reviews come from
codegraph-brain[bot]. Without them the step is skipped and posting falls
back to GITHUB_TOKEN, as before.

The app's key reaches every repository the app is installed on, so the
token is narrowed to this repository and to pull-requests: write, and it is
minted after every step that touches the PR checkout. The workflow tests pin
the condition, the pin, the scope, the permissions, the fallback on both
posting paths and the ordering.

Closes #734

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request adds unit tests to tests/unit/test_guardian_workflow.py to verify the behavior, scoping, and execution order of the GitHub App token minting process in the Guardian workflow. The review feedback suggests a more robust and simplified approach to finding the index of the minted step directly from the steps list instead of mapping and looking up by name.

Comment thread tests/unit/test_guardian_workflow.py Outdated
zaebee and others added 2 commits October 22, 2026 09:53
Review of #735: the ordering test missed a token handed to the ingest step
and a mint placed before it. A new test pins that only the two posting
steps reference steps.app-token; the ordering test now also counts steps
that name pr/ in their command. Both misses were seen failing.

The workflow comment no longer claims a silent fallback: with the variable
set, a missing or wrong key or a missing installation fails the job before
any LLM call. It also notes the token's one-hour lifetime.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From Gemini's review of #735.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@zaebee

zaebee commented Oct 22, 2026

Copy link
Copy Markdown
Owner Author

/guardian review

@github-actions github-actions Bot 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.

Summary: Checked the app-token gating: the if condition, the fallback to github.token when the step is skipped, and the posting steps all resolve correctly. Checked that the new tests reference only the posting steps and are ordered after the PR checkout steps. The main open question is whether the narrowed token permissions cover everything the review step reads.


🤖 claude-haiku-5-5 · 10,543 prompt + 3,056 completion = 13,599 tokens · graph 0/2 files (0%)

# provider's default ("low"). #246 J measured the finder at "medium".
GUARDIAN_ANTHROPIC_EFFORT: ${{ vars.GUARDIAN_ANTHROPIC_EFFORT }}
GH_TOKEN: ${{ github.token }}
GH_TOKEN: ${{ steps.app-token.outputs.token || github.token }}

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.

🟠 [Library Contract] — App token narrowed to pull-requests only may break the review step's GitHub reads

The minted app token requests only permission-pull-requests: write, so any contents read the review step performs through GH_TOKEN (for example gh api on repository files) would fail once the app token is in use, while github.token worked before.

Fix: Confirm every gh call in the Run Guardian Review step needs only pull-request access, or add permission-contents: read to the create-github-app-token step and extend the permissions test accordingly.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

No change needed. The only GitHub call the review step makes with GH_TOKEN is POST repos/{repo}/pulls/{pr}/reviews (src/cgis/guardian/github_poster.py:128). The diff and the files come from local git in pr/. GitHub's permission table lists that endpoint under Pull requests: write, and the fallback issues.createComment on a PR is covered by the same permission. The independent review of this PR checked both against the docs.

if: steps.guardian.outputs.posted_inline != 'true'
uses: peter-evans/create-or-update-comment@a111a2c3bacd7be7898ee22d0d71d9aec2bb972c # v4
with:
token: ${{ steps.app-token.outputs.token || github.token }}

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.

🟡 [Logic Bug] — Token expiry can silently drop the fallback comment for long reviews

The app token is minted before the review and lasts one hour, so a review that runs past that window would leave both the inline post and the fallback comment failing with an authentication error and no report posted.

Fix: Mint the token immediately before each posting step, or have the fallback step fall back to github.token when the app token request fails.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in fc9daf5: the review job has timeout-minutes: 45, below the token's 60-minute lifetime, so a review cannot outlive the token it posts with. Pinned by test_the_review_job_ends_before_the_app_token_expires.

github-actions Bot added a commit that referenced this pull request Oct 22, 2026
From guardian's review of #735: a review running past the installation
token's hour would fail both posting paths. The job now has
timeout-minutes: 45, pinned by a test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@zaebee
zaebee merged commit d52843a into main Oct 22, 2026
3 checks passed
@zaebee
zaebee deleted the ci/734-guardian-app-token branch October 22, 2026 10:19
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.

ci(guardian): post reviews as the codegraph-brain GitHub App

1 participant