Bulk reviewer assignment
The Scripting guide covers batch approval. Assigning reviewers across many pull requests (PRs) in one pass is a separate workflow — team rotations, onboarding new reviewers, and enforcing minimum reviewer coverage on existing PRs.
Identifying reviewers
Section titled “Identifying reviewers”bb pr reviewers add takes an account ID (712020:3cfed7e0-…) or a braced UUID ({c1cb1bb5-…}). Bitbucket Cloud no longer resolves login names here, so a pool of alice bob charlie fails with a 404 on every call. See Identifying users for how to look the IDs up once.
Pick one form and use it consistently — an account ID never equals a UUID, so a pool that mixes the two breaks any comparison you do against PR author fields.
Recipe: assign a fixed reviewer list
Section titled “Recipe: assign a fixed reviewer list”Adds every account ID in REVIEWERS to every open PR in WORKSPACE/REPO. Existing reviewers are not removed; if a reviewer is already assigned, bb pr reviewers add is a no-op.
#!/bin/bashset -euo pipefail
WORKSPACE="${WORKSPACE:-myworkspace}"REPO="${REPO:-myrepo}"# Space-separated Bitbucket account IDs (not usernames, not display names).REVIEWERS="${REVIEWERS:?set REVIEWERS to space-separated account IDs}"
# Optional: skip PRs authored by a reviewer (you can't review your own PR)SKIP_SELF_REVIEW="${SKIP_SELF_REVIEW:-true}"
# --all: without it, bb pr list stops at 25 and says nothing about it under --json.# External `jq -r`: the built-in --jq has no raw mode, so this filter would# return a JSON-quoted string with a two-character \t instead of a real tab.open_prs=$(bb pr list -w "$WORKSPACE" -r "$REPO" --all --json \ | jq -r '.pullRequests[] | "\(.id)\t\(.author.account_id)"')
while IFS=$'\t' read -r pr_id author; do [ -n "$pr_id" ] || continue echo "PR #$pr_id (by $author)"
for reviewer in $REVIEWERS; do if [ "$SKIP_SELF_REVIEW" = "true" ] && [ "$reviewer" = "$author" ]; then echo " - skip $reviewer (PR author)" continue fi
if bb pr reviewers add "$pr_id" "$reviewer" \ -w "$WORKSPACE" -r "$REPO" >/dev/null 2>&1; then echo " + added $reviewer" else echo " ! failed to add $reviewer (bad account ID, or permissions)" >&2 fi
sleep 1 # rate-limit cushion donedone <<< "$open_prs"WORKSPACE=myworkspace REPO=myrepo \ REVIEWERS="712020:3cfed7e0-0ed6-49fc-bb35-410a00ccee6f 712020:9ab1f22c-51de-4e7d-9f0e-2b7a10cd3311" \ ./bulk-assign-reviewers.shEach bb pr reviewers add costs three API requests: one to resolve the user, then a GET and a PUT on the pull request. At PRs × reviewers × 3 that adds up quickly — see Handling rate limits below.
Recipe: rotation by hash bucket
Section titled “Recipe: rotation by hash bucket”To give each PR one reviewer from a pool — a round-robin team rotation — hash the PR ID into the pool. The assignment is stable and reproducible without a database.
#!/bin/bashset -euo pipefail
WORKSPACE="${WORKSPACE:-myworkspace}"REPO="${REPO:-myrepo}"# Account IDs, same rule as above.POOL=( "712020:3cfed7e0-0ed6-49fc-bb35-410a00ccee6f" "712020:9ab1f22c-51de-4e7d-9f0e-2b7a10cd3311" "712020:c40be5aa-7c19-4a0b-83f2-6d1e94ab7702")
open_prs=$(bb pr list -w "$WORKSPACE" -r "$REPO" --all --json --jq '.pullRequests[].id')
for pr_id in $open_prs; do idx=$(( pr_id % ${#POOL[@]} )) reviewer="${POOL[$idx]}" echo "PR #$pr_id -> $reviewer" bb pr reviewers add "$pr_id" "$reviewer" -w "$WORKSPACE" -r "$REPO" || true sleep 1doneHandling rate limits
Section titled “Handling rate limits”The CLI already retries 429 responses up to 3 times automatically. For very large bulk operations (hundreds of PRs × multiple reviewers), prefer:
- A larger sleep between PRs (
sleep 2orsleep 3). - Bounding each run: swap
--allfor--limit 50so one pass can’t stretch for hours. There is no offset flag, so a plain re-run sees the same 50 PRs — record the IDs you have already handled and skip them next time. - Splitting the run across cron windows.
- Wrapping individual
bbcalls in the retry wrapper for the rare case of persistent 429s.
Related
Section titled “Related”bb pr reviewers add— single-PR command this recipe wrapsbb repo default-reviewers— repo-level defaults applied at PR creation time, often a better fit if you want this on new PRs only- Reviewers reference — full subcommand reference