Skip to content

[bug-hunter] PR Review (Fork) example omits required permissions for reusable workflow #1819

Closed as not planned

Description

@github-actions

Impact

Users who copy gh-agent-workflows/pr-review-fork/example.yml get a PR review workflow that cannot grant all permissions expected by the called reusable workflow. This causes deterministic runtime breakage for fork PR reviews (notably missing Copilot request scope), so reviews fail instead of posting results.

Reproduction Steps

  1. Create and run this minimal reproduction script:
#!/usr/bin/env python3
from __future__ import annotations

from pathlib import Path
import re
import sys

REPO = Path("/home/runner/work/ai-github-actions/ai-github-actions")
FORK_EXAMPLE = REPO / "gh-agent-workflows/pr-review-fork/example.yml"
PR_REVIEW_MD = REPO / ".github/workflows/gh-aw-pr-review.md"


def parse_permissions_block_from_yaml_text(text: str) -> dict[str, str]:
    lines = text.splitlines()
    permissions: dict[str, str] = {}
    in_permissions = False

    for line in lines:
        if not in_permissions:
            if re.match(r"^permissions:\\s*$", line):
                in_permissions = True
            continue

        if line.strip() == "" or line.lstrip().startswith("#"):
            continue

        if re.match(r"^[^\\s#].*", line):
            break

        m = re.match(r"^\\s{2}([A-Za-z0-9_-]+):\\s*([A-Za-z-]+)", line)
        if m:
            permissions[m.group(1)] = m.group(2)

    return permissions


def read_frontmatter(path: Path) -> str:
    text = path.read_text(encoding="utf-8")
    m = re.match(r"^---\\n(.*?)\\n---\\n", text, re.DOTALL)
    if not m:
        raise RuntimeError(f"Could not parse frontmatter from {path}")
    return m.group(1)


def main() -> int:
    caller_permissions = parse_permissions_block_from_yaml_text(
        FORK_EXAMPLE.read_text(encoding="utf-8")
    )
    callee_permissions = parse_permissions_block_from_yaml_text(read_frontmatter(PR_REVIEW_MD))

    required = {k: v for k, v in callee_permissions.items() if v != "none"}
    missing = {k: v for k, v in required.items() if k not in caller_permissions}

    print("caller permissions:", caller_permissions)
    print("callee required permissions:", required)
    print("missing in caller:", missing)

    if missing:
        return 1
    return 0


if __name__ == "__main__":
    sys.exit(main())
  1. Run:
python3 /tmp/gh-aw/agent/repro_pr_review_fork_permissions.py

Expected vs Actual

Expected: Fork PR review example grants all required permissions for the called reusable workflow.

Actual: The example omits required scopes; reproduction exits non-zero with:

caller permissions: {'contents': 'read', 'issues': 'write', 'pull-requests': 'write'}
callee required permissions: {'copilot-requests': 'write', 'actions': 'read', 'contents': 'read', 'pull-requests': 'read', 'issues': 'read'}
missing in caller: {'copilot-requests': 'write', 'actions': 'read'}

Failing Test

The script above is a minimal failing test: it compares permissions required by .github/workflows/gh-aw-pr-review.md against those granted in gh-agent-workflows/pr-review-fork/example.yml, and fails when required entries are missing.

Evidence

  • gh-agent-workflows/pr-review-fork/example.yml:27-30 defines:
    • contents: read
    • issues: write
    • pull-requests: write
  • .github/workflows/gh-aw-pr-review.md:79-84 requires:
    • copilot-requests: write
    • actions: read
    • plus contents/pull-requests/issues
  • Standard PR review example already includes copilot-requests: write:
    • gh-agent-workflows/pr-review/example.yml:6-11

Suggested fix: add the missing required permissions (at minimum copilot-requests: write and actions: read) to gh-agent-workflows/pr-review-fork/example.yml so the fork trigger matches reusable workflow requirements.


What is this? | From workflow: Trigger Bug Hunter

Give us feedback! React with 🚀 if perfect, 👍 if helpful, 👎 if not.

  • expires on Aug 20, 2026, 11:30 AM UTC

Activity

  1. added a commit that references this issue on Aug 13, 2026
    3bd653f
  2. github-actions commented on Aug 20, 2026

    @github-actions
    ContributorAuthor

    This issue was automatically closed because it expired on 2026-08-20T11:30:52.311Z.

    Closed by Workflow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions