Skip to content

Bulk reviewer assignment

Assign reviewers to existing open pull requests without removing the reviewers already there. Use repository default reviewers if you only need assignments on new PRs.

bb pr reviewers add takes a nickname, display name, email, @me, account ID (712020:3cfed7e0-...) or braced UUID ({c1cb1bb5-...}). Names cost a workspace member lookup on every call, so the scripts below keep the pool as account IDs. See Identifying users for the rules and for how to look the IDs up.

These scripts use account IDs only and compare them with author.account_id. Do not mix UUIDs or display names into the pool. Missing author IDs stop the run before any assignments.

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.

bulk-assign-reviewers.sh
#!/bin/bash
set -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}"
open_prs=$(bb pr list -w "$WORKSPACE" -r "$REPO" --all --json \
| jq -er '
if all(.pullRequests[];
.author.account_id | type == "string" and length > 0)
then [.pullRequests[] | "\(.id)\t\(.author.account_id)"] | join("\n")
else error("Missing PR author account ID") end
')
failed=0
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 [ "$reviewer" = "$author" ]; then
echo " - skip $reviewer (PR author)"
continue
fi
if bb pr reviewers add "$pr_id" "$reviewer" \
-w "$WORKSPACE" -r "$REPO" >/dev/null; then
echo " + added $reviewer"
else
echo " ! failed to add $reviewer" >&2
failed=1
fi
sleep 1 # rate-limit cushion
done
done <<< "$open_prs"
exit "$failed"
Terminal window
WORKSPACE=myworkspace REPO=myrepo \
REVIEWERS="712020:3cfed7e0-0ed6-49fc-bb35-410a00ccee6f 712020:9ab1f22c-51de-4e7d-9f0e-2b7a10cd3311" \
./bulk-assign-reviewers.sh

Each assignment may resolve the user, fetch the PR and update it. A bulk run can make several requests per reviewer. Both scripts continue after individual assignment failures and exit nonzero if any failed.

To select one reviewer per PR, take its ID modulo the eligible pool size. The author is always excluded. With the same pool and author, the selection is stable; changing either can select someone else. Existing reviewers remain assigned.

rotation-assign.sh
#!/bin/bash
set -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 -er '
if all(.pullRequests[];
.author.account_id | type == "string" and length > 0)
then [.pullRequests[] | "\(.id)\t\(.author.account_id)"] | join("\n")
else error("Missing PR author account ID") end
')
failed=0
while IFS=$'\t' read -r pr_id author; do
[ -n "$pr_id" ] || continue
eligible=()
for reviewer in "${POOL[@]}"; do
[ "$reviewer" = "$author" ] || eligible+=("$reviewer")
done
if [ "${#eligible[@]}" -eq 0 ]; then
echo "PR #$pr_id: no eligible reviewer" >&2
failed=1
continue
fi
idx=$(( pr_id % ${#eligible[@]} ))
reviewer="${eligible[$idx]}"
if ! bb pr reviewers add "$pr_id" "$reviewer" -w "$WORKSPACE" -r "$REPO"; then
failed=1
fi
sleep 1
done <<< "$open_prs"
exit "$failed"

The CLI already retries 429 responses up to 3 times automatically. For large bulk operations, use a larger delay or bound each run with --limit 50. There is no offset flag, so track handled IDs to avoid repeatedly processing the same page.

Split large runs across scheduled jobs. Use the retry wrapper only when rate limits persist beyond the built-in retries.