Reusable GitHub Action to automate cross-repo PR + Issue + Projects V2 workflows. This repo is set up for Sneha first, but the action is configurable for other repo pairs through .github/automation.yml.
- On PR
review_requestedorready_for_review- Add label
Ready For Reviewto the PR (if missing) - Parse
Targets: coloredcow-admin/sneha-lms#<issue_id>from PR body - Move Issue to
In reviewin Project V2SNEHA LMS - Audit comments on the Issue for changes that occurred
- Add label
- On PR
openedorsynchronize- Move Issue to
In Progressif not already at/afterIn review - Audit comments only if status changed
- Move Issue to
- If Issue is not in the Project, add it first
- No spam: comments are only posted when an actual change occurred
- If Targets line is missing/invalid, comment on the PR and exit
- A pull request template that includes a Targets line:
Targets: owner/repo#<issue_id>(cross-repo)Targets: #<issue_id>(same-repo)
- A GitHub Project V2 with a single-select Status field and options matching your config.
- Repository files:
.github/automation.yml.github/workflows/pr_automation.yml
- Create a classic PAT (recommended, works reliably with Projects V2):
- Settings -> Developer settings -> Personal access tokens -> Tokens (classic)
- Scopes:
reporead:projectwrite:projectNote: We tried fine-grained PATs, but Projects permissions are not always available there. Classic PATs work consistently for Projects V2.
- Add the token as a secret in the PR repo:
- Secret name:
GH_AUTOMATION_TOKEN
- Secret name:
- Add
.github/automation.ymland.github/workflows/pr_automation.yml(examples below).
name: PR Automation
on:
pull_request:
types: [opened, synchronize, ready_for_review, review_requested]
permissions:
contents: read
pull-requests: write
issues: write
jobs:
pr-automation:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run automation
uses: satendra-sr/github-project-automation@v1
with:
token: ${{ secrets.GH_AUTOMATION_TOKEN }}
config-path: .github/automation.ymlCreate .github/automation.yml in the consuming repo:
issue_repo:
owner: coloredcow-admin
name: sneha-lms
project:
owner: coloredcow-admin
name: SNEHA LMS
status_field: Status
status_order:
- Backlog
- Ready
- On Hold
- In Progress
- In review
- QA
- Completed
labels:
ready_for_review: Ready For Review
ready_for_review_any:
- Ready For Review
- "status: ready for review"
rules:
- on:
event: pull_request
actions: [opened, synchronize]
do:
- ensure_issue_in_project: true
- ensure_status_at_least: In Progress
- audit_on_change: true
- on:
event: pull_request
actions: [review_requested, ready_for_review]
do:
- add_pr_label_if_missing: Ready For Review
- ensure_issue_in_project: true
- ensure_status_at_least: In review
- audit_on_change: truetoken(required): Token with cross-repo + Projects V2 permissionsconfig-path(optional): Defaults to.github/automation.ymldry-run(optional): Defaults tofalseand skips writes when true
did_label_changedid_status_changeissue_numbertarget_status
Required in PR body:
Targets: coloredcow-admin/sneha-lms#123
This format is intentionally strict. The action will only accept a Targets line that matches the repo configured under issue_repo in .github/automation.yml. This keeps cross-repo automation explicit and safe.
Supported whitespace variants:
Targets:coloredcow-admin/sneha-lms#123Targets: coloredcow-admin/sneha-lms #123For same-repo cases, a short format is also accepted:Targets: #123
If missing or invalid, the action comments on the PR and exits.
GITHUB_TOKEN often lacks cross-repo + Projects V2 permissions. Use a secret token input named GH_AUTOMATION_TOKEN.
Required scopes:
repo(read/write issues + PRs)read:projectandwrite:project(Projects V2)
Grant access to both repos and:
- Issues: Read & write on
coloredcow-admin/sneha-lms - Pull requests: Read & write on
coloredcow-admin/sneha - Projects: Read & write (organization-level Projects V2)
Grant installation to both repos and add:
- Issues: write
- Pull requests: write
- Projects: read/write
This action is bundled via esbuild (CJS output) and committed to dist/index.js.
Runtime: Node.js 24 (set in action.yml).
npm run build
npm run bundle- Project not found: Ensure
project.ownerandproject.namematch exactly, or setproject.number. - Status option mismatch: Ensure
status_orderentries exactly match the Project Status options. - Missing Targets: Add
Targets: coloredcow-admin/sneha-lms#<issue_id>to the PR body. - Permissions errors: Use a token with cross-repo issue/PR write and Projects V2 read/write scopes.
See examples/coloredcow-admin-sneha/.github/workflows/pr_automation.yml and examples/coloredcow-admin-sneha/.github/automation.yml.