Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions .github/workflows/dispatch-review.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Runs the dispatch GATE for AI code reviews on this repo's PRs.
# Forwards to the shared decider workflow in nsheaps/agents, which evaluates
# whether to dispatch a review and (if yes) fires a repository_dispatch to the
# target agent repo's dispatch-receiver-review.yaml.
#
# This file is a template — copy into your repo at
# `.github/workflows/dispatch-review.yaml`. Synced via `nsheaps/.github` CI
# automation when configured; until then, copy-paste.
#
# Spec: https://github.com/nsheaps/agents/blob/main/plugins/claude-code/review-utils/specs/review-dispatch.md
#
# Requirements (provisioned via nsheaps/.github/secret-sync.yaml):
# - AUTOMATION_GITHUB_APP_ID
# - AUTOMATION_GITHUB_APP_PRIVATE_KEY (automation-nsheaps[bot]; installed on
# THIS repo for label edit + check_run
# posting, AND on the target agent repo
# so it can fire repository_dispatch)
#
# Why automation creds (not REVIEW_GITHUB_APP_*)? The gate is routing only —
# it never speaks AS the reviewer. It edits a label, posts a queued check, and
# fires a repository_dispatch. The reviewer-identity (REVIEW_GITHUB_APP_*) is
# owned by the target agent's `dispatch-receiver-review.yaml`, where the review
# actually executes. See plugins/claude-code/review-utils/specs/review-dispatch.md
# §Secrets for the gate-vs-receiver creds rationale.
#
# LLM-auth secrets (REVIEW_ANTHROPIC_API_KEY / CLAUDE_CODE_OAUTH_TOKEN) are
# NOT needed here — owned by the target agent's receiver for the same reason.

name: Dispatch PR Review

on:
pull_request:
types: [opened, reopened, synchronize, ready_for_review, labeled]

# Explicit top-level permissions (mirrors the job-level grant below) so
# checkov's CKV2_GHA_1 ("top-level permissions not write-all") is satisfied.
permissions:
contents: read
pull-requests: write
checks: write

jobs:
review:
# Gate: review fires automatically on any OPEN, non-draft PR event
# (opened, reopened, synchronize, ready_for_review) -- no label needed.
# The `request-review` label only matters to FORCE a review on a DRAFT
# PR (apply the label while it's still a draft). `converted_to_draft`
# does NOT fire a review by itself -- a PR converted to draft is simply
# not reviewed until it's marked ready again or explicitly labeled. If
# you change the request label name, update the literal in the `==`
# comparison below.
if: |
github.event.pull_request.state == 'open' &&
(
github.event.pull_request.draft != true ||
(github.event.action == 'labeled' && github.event.label.name == 'request-review')
)
# Explicit permissions: default_workflow_permissions is "read" in many
# repos but the called workflow needs pull-requests + checks write.
permissions:
contents: read
pull-requests: write
checks: write
# @main = rolling updates: any change merged to nsheaps/agents takes effect
# on the next PR event in repos using this template. This is intentional —
# operators who need pinned stability should replace @main with a commit SHA
# and update it in lock-step with plugin version bumps.
uses: nsheaps/agents/.github/workflows/review-dispatch.yaml@31622503be5de83437594476b86d3c500b4af7c2 # main
# secrets: inherit doesn't pass cross-repo (GitHub limitation).
secrets:
AUTOMATION_GITHUB_APP_ID: ${{ secrets.AUTOMATION_GITHUB_APP_ID }}
Comment on lines +67 to +71

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.

❔ P2 — comment contradicts the actual pin.

The comment describes "@main = rolling updates" but the uses: line is pinned to a specific SHA (31622503…) with just a trailing # main marker. The two don't match: if org-sync bumps the SHA automatically on every nsheaps/agents main push, the behavior is effectively rolling but implemented via SHA rewrites — not @main. If sync does not rewrite the SHA, the comment is simply wrong and this is pinned stability.

Either way, the "@main" in the explanatory text no longer appears in the ref. Suggest describing the actual mechanism (e.g. "pinned to a SHA; org-sync bumps on every nsheaps/agents main push — override by replacing the SHA and dropping the # main marker"). Not blocking — doc-only.

AUTOMATION_GITHUB_APP_PRIVATE_KEY: ${{ secrets.AUTOMATION_GITHUB_APP_PRIVATE_KEY }}
# Optional overrides (uncomment to use):
# with:
# target-repo: nsheaps/.ai-agent-henry # default
# event-type: pr-review # default repository_dispatch event_type
Comment on lines +73 to +76

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.

⚠️ P1 — commented example breaks the workflow if uncommented.

event-type is not a workflow_call input in the pinned reusable workflow (nsheaps/agents/.github/workflows/review-dispatch.yaml@31622503). Its only input is target-repo. The dispatched event-type is hardcoded upstream to ${{ github.event_name }}/${{ github.event.action }} (e.g. pull_request/opened), so a value like pr-review is never what gets sent on the wire.

If an operator follows this template literally and uncomments the block, the workflow fails validation with:

Invalid input, 'event-type' is not defined in the referenced workflow

Suggest dropping that line (or converting it to a prose note that the event-type is derived upstream, not configurable here):

Suggested change
# Optional overrides (uncomment to use):
# with:
# target-repo: nsheaps/.ai-agent-henry # default
# event-type: pr-review # default repository_dispatch event_type
# Optional overrides (uncomment to use):
# with:
# target-repo: nsheaps/.ai-agent-henry # default
# Note: the repository_dispatch event-type is derived upstream from
# `${{ github.event_name }}/${{ github.event.action }}` and is not
# a configurable input of this reusable workflow.

Loading