Repository navigation
feat: implement issue #235 — Phase 4: Cross-org deployment of gh-aw workflows - #302
Conversation
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (5)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Dev-Lead — human-pr (no-changes)No changes were needed for this PR. |
There was a problem hiding this comment.
Code Review
This pull request implements the architecture for cross-organization deployment of GitHub Agentic Workflows. It introduces a documentation guide, a listener workflow template for target repositories, and test fixtures for issue triage and CI failure events. Feedback focuses on optimizing the PR resolution logic in the listener template, specifically recommending fork filtering, the use of a more efficient GitHub API endpoint for commit-associated PRs, and improved parameter handling in jq.
| pr_number=$(echo "$CHECK_RUN_PRS" \ | ||
| | jq -r 'first // empty | .number // empty') | ||
|
|
||
| if [ -z "$pr_number" ]; then | ||
| # Fallback: search open PRs with this head SHA from this repo (not a fork). | ||
| pr_number=$(gh api \ | ||
| "repos/${REPO}/pulls?state=open&per_page=100" \ | ||
| --jq "[.[] | select(.head.sha == \"$HEAD_SHA\" and .head.repo.full_name == \"$REPO\")] | first | .number // empty" \ | ||
| 2>/dev/null || true) | ||
| fi |
There was a problem hiding this comment.
The PR resolution logic can be optimized for efficiency and correctness:
- Fork Filtering: The fast path (lines 108-109) should verify that the PR is not from a fork (i.e., the head repository matches the base repository) to ensure the agent only operates on internal branches, as intended.
- Efficient Fallback: Instead of listing all open PRs and filtering them (which is slow and limited to the first 100 PRs), use the specific GitHub API endpoint for listing PRs associated with a commit SHA:
GET /repos/{owner}/{repo}/commits/{commit_sha}/pulls. - Robustness: Use
--argto pass variables tojqinstead of shell interpolation within the filter string to avoid potential issues with special characters.
# Prefer the pull_requests array embedded in the check_run payload (fastest path).
# Filter for non-fork PRs (head repo matches base repo).
pr_number=$(echo "$CHECK_RUN_PRS" \
| jq -r '.[] | select(.head.repo.id == .base.repo.id) | .number' \
| head -n 1)
if [ -z "$pr_number" ]; then
# Fallback: search PRs associated with this commit SHA.
# This is more efficient than listing all open PRs and avoids the 100-PR limit.
pr_number=$(gh api "repos/${REPO}/commits/${HEAD_SHA}/pulls" \
--arg repo "$REPO" \
--jq ".[] | select(.head.repo.full_name == \$repo) | .number" \
2>/dev/null | head -n 1)
fi
Dev-Lead — fix-bot-comment (no-changes)Engine ran but made no changes. |
There was a problem hiding this comment.
Pull request overview
Implements Phase 4 of the gh-aw rollout (#235) by enabling cross-repo triggers via an org-dispatch architecture: lightweight “listener” workflows in org repos emit repository_dispatch events to a central dispatcher workflow in petry-projects/.github-private, which then runs the existing dev-lead handlers against the target repo.
Changes:
- Added a central cross-org dispatcher workflow (
gh-aw-cross-org.yml) that validates source repo and runs the appropriate dev-lead handler in the checked-out target repo. - Added a deployable listener workflow template for org repos (
templates/gh-aw-org-listener.yml) to relayissues:labeledand failingcheck_runevents. - Added documentation and test fixtures for the new
repository_dispatchevent schemas.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
tests/dev-lead/fixtures/events/repository_dispatch_gh_aw_issue_triage.json |
Adds a fixture payload for cross-org issue triage dispatch events. |
tests/dev-lead/fixtures/events/repository_dispatch_gh_aw_ci_failure.json |
Adds a fixture payload for cross-org CI failure dispatch events. |
templates/gh-aw-org-listener.yml |
Introduces a thin listener template to be deployed into org repos to dispatch events to .github-private. |
docs/aw/cross-org-deployment.md |
Documents the decision gate outcome and the cross-org dispatch architecture and payload schemas. |
.github/workflows/gh-aw-cross-org.yml |
Adds the central dispatcher workflow that executes gh-aw capabilities against target repos. |
Comments suppressed due to low confidence (2)
templates/gh-aw-org-listener.yml:110
- The fast path that reads
check_run.pull_requestsdoes not verify the PR is non-fork before dispatching. Indev-lead-ci-relay.sh, fork PRs are filtered by comparingpull_requests[0].head.repo.urlto the expected base repo URL; without a similar check here, fork PR failures can be relayed cross-org (and then fail downstream or cause unintended behavior). Add an explicit non-fork validation for the embeddedpull_requestsentry (and keep the existing SHA search fallback for cases where the array is empty).
# Prefer the pull_requests array embedded in the check_run payload (fastest path).
pr_number=$(echo "$CHECK_RUN_PRS" \
| jq -r 'first // empty | .number // empty')
docs/aw/cross-org-deployment.md:113
- This doc says the
GH_PAT_WORKFLOWSorg secret is inherited automatically by all org repos. In GitHub Actions, org secrets must be explicitly made available to target repositories. Please adjust the wording to reflect that repos need to be granted access, and consider noting the PAT needsread:orgfor the org-membership trust gate used by the listener.
1. Copy `templates/gh-aw-org-listener.yml` to the target repo as `.github/workflows/gh-aw-listener.yml`.
2. Ensure the repo has access to the `GH_PAT_WORKFLOWS` org secret (it is org-level, so all org repos inherit it automatically).
3. Open a PR in the target repo with the new workflow file. Merge it.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # GH_PAT_WORKFLOWS org secret — cross-repo dispatch and API calls | ||
| # (inherited automatically from the petry-projects org) |
| | Capability | Trigger | Handler script | | ||
| |---|---|---| | ||
| | **Issue Triage** | `issues[labeled]` (org-member labeler) | `dev-lead-fix-issue.sh` | | ||
| | **CI Failure Analyst** | `check_run[completed, conclusion=failure]` | `dev-lead-fix-ci.sh` | | ||
|
|
| env: | ||
| SOURCE_REPO: ${{ github.event.client_payload.source_repo }} | ||
| BOT_USER: ${{ vars.BOT_USER || 'donpetry-bot' }} | ||
| DEV_LEAD_ENGINE: ${{ vars.DEV_LEAD_ENGINE || 'claude' }} | ||
| DEV_LEAD_DRY_RUN: ${{ vars.DEV_LEAD_DRY_RUN || 'false' }} | ||
| GH_TOKEN: ${{ secrets.GH_PAT_WORKFLOWS || secrets.GITHUB_TOKEN }} | ||
|
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2d69aadd71
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| pr_number=$(echo "$CHECK_RUN_PRS" \ | ||
| | jq -r 'first // empty | .number // empty') |
There was a problem hiding this comment.
Enforce non-fork check before relaying CI failures
The fast path takes check_run.pull_requests[0].number directly, but never verifies that the PR head repo matches the current repo. This bypasses the stated "non-fork PR" requirement and can dispatch fork-originated failures to .github-private, where gh-aw-cross-org.yml will try to run fix automation with write credentials against an unpushable fork branch. The existing in-repo relay logic (scripts/dev-lead-ci-relay.sh) performs this fork check explicitly, so dropping it here is a behavioral regression for fork PR check runs.
Useful? React with 👍 / 👎.
| # Fires when an org member labels an issue. Routes to the gh-aw Issue Triage | ||
| # capability in .github-private, which will open a PR implementing the issue. | ||
| issue-triage: | ||
| if: github.event_name == 'issues' |
There was a problem hiding this comment.
Restrict issue-triage trigger to real issues
issues events also fire when labels are added to pull requests, and this job currently runs for all issues events. Without checking github.event.issue.pull_request == null, labeling a PR will incorrectly dispatch gh-aw-issue-triage and attempt issue-implementation automation against a PR number, creating noisy or invalid triage runs whenever maintainers label PRs.
Useful? React with 👍 / 👎.
| "repos/${REPO}/pulls?state=open&per_page=100" \ | ||
| --jq "[.[] | select(.head.sha == \"$HEAD_SHA\" and .head.repo.full_name == \"$REPO\")] | first | .number // empty" \ |
There was a problem hiding this comment.
Page through PR lookup when resolving check-run SHA
The fallback lookup only calls repos/${REPO}/pulls?state=open&per_page=100 once, so in repos with more than 100 open PRs the matching PR for HEAD_SHA can be on a later page and never found. In that case has_pr=false is emitted and CI-failure dispatch is skipped, causing silent misses for valid failures on busy repositories.
Useful? React with 👍 / 👎.
| # Fallback: search open PRs with this head SHA from this repo (not a fork). | ||
| pr_number=$(gh api \ | ||
| "repos/${REPO}/pulls?state=open&per_page=100" \ | ||
| --jq "[.[] | select(.head.sha == \"$HEAD_SHA\" and .head.repo.full_name == \"$REPO\")] | first | .number // empty" \ |
There was a problem hiding this comment.
Resolve PR by commit membership, not only current PR head
The fallback requires .head.sha == "$HEAD_SHA", which only matches when the failing check's SHA is still the PR's latest commit. External checks can complete after a newer commit is pushed, so the related PR remains open but no longer has that SHA at its head; this path then emits has_pr=false and drops a real CI-failure relay. The existing scripts/dev-lead-ci-relay.sh avoids this by using the commits-to-pulls API instead of head-SHA equality.
Useful? React with 👍 / 👎.
Dev-Lead — fix-bot-comment (no-changes)Engine ran but made no changes. |
|
@dev-lead please fix the Lint CI failure — yamllint errors in |
Dev-Lead — fix-bot-comment (no-changes)Engine ran but made no changes. |
Dev-Lead — human-pr (applied)Changes committed and pushed. |
Dev-Lead — fix-bot-comment (no-changes)Engine ran but made no changes. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c69eb2046c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| --arg repo "$REPO" \ | ||
| --jq '.[] | select(.head.repo.full_name == $repo) | .number' \ |
There was a problem hiding this comment.
Drop unsupported
--arg from gh api PR lookup
The fallback PR-resolution command uses gh api ... --arg repo "$REPO" --jq ..., but gh api does not support a --arg flag (its filtering options are --jq, --field, and --raw-field), so this call exits non-zero and is silently swallowed by || true. In runs where check_run.pull_requests is empty (the exact case this fallback is meant to handle, such as external checks), pr_number stays empty and the workflow always skips CI relay, causing real failures to be dropped.
Useful? React with 👍 / 👎.
| check_run: | ||
| types: [completed] |
There was a problem hiding this comment.
Trigger CI relay from an event that fires for Actions checks
This listener is wired to on: check_run, but GitHub Actions suppresses check_run-triggered workflows when the check suite was created by GitHub Actions (to prevent recursion). As a result, ordinary failed CI jobs produced by GitHub Actions in target repos will not execute this listener at all, so the cross-org CI-failure dispatch path is skipped for the primary CI source.
Useful? React with 👍 / 👎.
| # handles external checks that complete after a newer commit is pushed. | ||
| pr_number=$(gh api "repos/${REPO}/commits/${HEAD_SHA}/pulls" \ | ||
| --arg repo "$REPO" \ | ||
| --jq '.[] | select(.head.repo.full_name == $repo) | .number' \ |
There was a problem hiding this comment.
Filter commit-to-PR fallback to open pull requests
The commits-to-pulls fallback selects the first same-repo PR by head repo name but never checks PR state, so it can pick a merged/closed PR. GitHub documents that this endpoint can return merged PRs for commits on the default branch, which means failed checks from branch pushes can be relayed against closed PR numbers and send the fixer down an invalid target path.
Useful? React with 👍 / 👎.
|



Closes #235
Implemented by dev-lead agent. Please review.