From f4ac048955f0e730dec2e98ba9ed2d1161ce4b7f Mon Sep 17 00:00:00 2001 From: Matt Miller Date: Tue, 2 Jun 2026 11:01:51 -0700 Subject: [PATCH] feat: add assign-prs-to-author reusable workflow Extracts the housekeeping workflow that assigns every open PR with no assignees to its author into a reusable workflow_call, so consumer repos carry only a thin scheduled caller instead of a copy. Bot-authored PRs are skipped by default (skip-bots input). Uses the caller's GITHUB_TOKEN, so the calling job grants pull-requests: write + issues: write. --- .github/workflows/assign-prs-to-author.yml | 74 ++++++++++++++++++++++ README.md | 1 + 2 files changed, 75 insertions(+) create mode 100644 .github/workflows/assign-prs-to-author.yml diff --git a/.github/workflows/assign-prs-to-author.yml b/.github/workflows/assign-prs-to-author.yml new file mode 100644 index 0000000..783e903 --- /dev/null +++ b/.github/workflows/assign-prs-to-author.yml @@ -0,0 +1,74 @@ +name: Assign PRs to Author (reusable) + +# Reusable workflow that assigns every open PR with no assignees to its +# author. Useful when a team tracks PR ownership via assignees (rather than +# reviewers) — unassigned PRs get routed back to whoever opened them. +# +# By default, PRs opened by bot accounts (Dependabot, Renovate, app tokens) +# are skipped; set `skip-bots: false` to assign those too. +# +# The caller's GITHUB_TOKEN is used (no secrets to pass), so the calling job +# MUST grant `pull-requests: write` and `issues: write` — assignees are set +# through the issues API. +# +# Caller pattern (place in your repo at .github/workflows/assign-prs-to-author.yml): +# +# name: Housekeeping - Assign PRs to Author +# on: +# schedule: +# - cron: "0 2 * * *" # daily at 02:00 UTC +# workflow_dispatch: +# jobs: +# assign: +# permissions: +# pull-requests: write +# issues: write +# uses: Comfy-Org/github-workflows/.github/workflows/assign-prs-to-author.yml@ # v1 + +on: + workflow_call: + inputs: + skip-bots: + description: >- + Skip PRs opened by bot accounts (Dependabot, Renovate, app tokens). + Set to false to assign those to their bot author as well. + type: boolean + required: false + default: true + +jobs: + assign: + name: Assign unassigned PRs + runs-on: ubuntu-latest + permissions: + pull-requests: write + issues: write + steps: + - name: Assign unassigned PRs to their authors + uses: actions/github-script@v9 + with: + script: | + const skipBots = ${{ inputs.skip-bots }}; + const pulls = await github.paginate(github.rest.pulls.list, { + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + per_page: 100, + }); + + for (const pr of pulls) { + // Already owned, or no resolvable author — leave it alone. + if (pr.assignees.length > 0 || !pr.user) continue; + if (skipBots && pr.user.type === 'Bot') continue; + try { + console.log(`Assigning PR #${pr.number} to ${pr.user.login}`); + await github.rest.issues.addAssignees({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + assignees: [pr.user.login], + }); + } catch (error) { + console.warn(`Failed to assign PR #${pr.number}: ${error.message}`); + } + } diff --git a/README.md b/README.md index 99d7873..c6dcfc4 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ This repo is **public** so any repo — public or private, inside or outside the |---|---| | [`detect-unreviewed-merge.yml`](.github/workflows/detect-unreviewed-merge.yml) | SOC 2 compliance — detects PRs merged without prior approval and opens a tracking issue in [`Comfy-Org/unreviewed-merges`](https://github.com/Comfy-Org/unreviewed-merges). | | [`cursor-review.yml`](.github/workflows/cursor-review.yml) | Label-triggered multi-model code review. A 4-lab × 2-review-type cursor-agent panel runs adversarial + edge-case passes, a judge model consolidates them into one PR review with per-finding severity badges, and the triggerer gets Slack start/complete DMs. Prompts and scripts live in [`.github/cursor-review/`](.github/cursor-review) — the single source of truth, so consumer repos carry only a thin caller. Requires `CURSOR_API_KEY` (+ optional `SLACK_BOT_TOKEN`). | +| [`assign-prs-to-author.yml`](.github/workflows/assign-prs-to-author.yml) | Housekeeping — assigns every open PR with no assignees to its author (bot-authored PRs skipped by default). Run on a schedule from a thin caller; useful when a team tracks PR ownership via assignees. The calling job needs `pull-requests: write` and `issues: write`. | ## Usage