feat: add default reviewers to pr edit#150
Conversation
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
avivsinai
left a comment
There was a problem hiding this comment.
Feature is solid, refactor is clean, one real blocker on the Cloud path.
Blocking
Cloud mixed-identity handling is incomplete in the explicit --reviewer/--remove-reviewer path, plus a silent data-loss bug on AccountID-only reviewers.
The new helpers (cloudUserKeys, sameCloudUser, mergeCloudPRReviewers, cloudReviewerIDs) reconcile all three identity formats and are used for the default-reviewer merge and author exclusion. But matchesCloudUser at pkg/cmd/pr/pr.go:794-799 still only checks UUID or username, and editCloudReviewers at pr.go:808-880 uses it exclusively. The runtime flow at pr.go:1573-1591 merges defaults first (identity-aware), then calls editCloudReviewers (not identity-aware) against the merged reviewer list — so the brittleness surfaces in the explicit add/remove path even when the merge worked.
Repro against the diff:
- Reviewer returned as
{UUID: "x", AccountID: "abc", Username: ""}— real for GDPR-era Cloud accounts that never had a username --with-default-reviewers --remove-reviewer alice(alice hasaccount_id: "abc"):matchesCloudUserreturns false for every check → remove is a silent no-op, alice stays on the PR--with-default-reviewers --reviewer alicesame case:alreadyOnPRis false → alice appended as a duplicate entry
Plus a silent-drop bug at pr.go:842-857:
if u.UUID != "" {
result = append(result, u.UUID)
} else if u.Username != "" {
result = append(result, u.Username)
}Reviewers with only AccountID populated are silently dropped from the result. cloudReviewerIDs at pr.go:1378-1408 has the same drop. bbcloud.User at pkg/bbcloud/client.go:55-61 confirms all four fields are optional JSON with no guarantees.
Fix: plumb sameCloudUser through editCloudReviewers (replace matchesCloudUser calls), and extend the keep-loop + cloudReviewerIDs serialization to fall back to AccountID when UUID and Username are both empty. Extend the mixed-identity tests you already added (pr_test.go 3116-3156, 4466-4519) to the explicit --reviewer/--remove-reviewer flow.
Non-blocking
-
Author exclusion fragility (
pr.go:1575-1579). If Cloud returns an author with no usable identity (rare but possible),cloudUserKeys(excluded)is empty →sameCloudUserreturns false → author not filtered → Cloud rejects server-side. Worth a warning + fallback toclient.CurrentUser(ctx). -
Spurious "already on this pull request" warnings at
pr.go:1518-1520(DC) and1586-1591(Cloud).--with-default-reviewers --reviewer alicewhere alice is already in the default set produces noisy stderr. Correct behavior, bad UX — consider suppressing when the overlap is only with freshly-merged defaults, not with pre-existing reviewers. -
ios, _ := f.Streams()atpr.go:1469breaks codebase convention — every otherrunXdoesios, err := f.Streams(); if err != nil { return err }. Thevar err erroron line 1472 reads like a workaround for the dropped shadow.Streams()currently never returns a non-nil error so it's harmless today, but please restore the pattern. -
Four merge functions (
mergeReviewers,mergeCloudReviewers,mergeDCPRReviewers,mergeCloudPRReviewers) with different shapes all called "merge reviewers" — rename for callsite clarity. -
TestRunEditDataCenterReviewersPUT-body assertion is shallow — only checkslen(reviewers) == 3, not the actual names. Could miss a regression where the merge produces the right count but the wrong set.
What's done well
--with-default-reviewers=falseis exactly right — tests verify the endpoint is NOT called AND that the Cloud PUT body has noreviewersfield.- DC uses the PR's actual
FromRef.ID/ToRef.ID(not repo defaults) — spec-correct. - Cloud preserves existing reviewer UUIDs in the update payload — matches Cloud's stable identity model.
- Explicit
--reviewer/--remove-reviewerapplies AFTER the default merge on both backends — explicit user intent wins. - Default-reviewer fetch errors abort the edit rather than silently continuing.
Once editCloudReviewers and cloudReviewerIDs pick up the account_id-aware logic that the rest of the diff already introduces, this is an approve.
a8a5569 to
bfb1912
Compare
- matchesCloudUser now checks AccountID in addition to UUID/Username - Serialization fallback to AccountID when UUID and Username are empty - Author exclusion falls back to CurrentUser when author has no identity - Suppress spurious "already on PR" warnings for default-merged reviewers - Restore ios error check in runEdit to match codebase convention - Rename merge functions for callsite clarity (create vs edit) - Strengthen DC reviewer PUT-body assertion to check actual names
|
All points addressed in b6d708a: Blocking — Cloud mixed-identity handling:
Non-blocking 1 — Author exclusion fragility: Non-blocking 2 — Spurious warnings: Non-blocking 3 — Non-blocking 4 — Merge function names: Non-blocking 5 — Shallow PUT-body assertion: |
avivsinai
left a comment
There was a problem hiding this comment.
Blocking issue still left in the Cloud edit path.
pkg/cmd/pr/pr.go now preserves/emits AccountID reviewer identities (editCloudReviewers, cloudReviewerIDs), but pkg/bbcloud/pullrequests.go:346-352 still serializes every non-UUID reviewer as {\"username\": reviewer}. For AccountID-only reviewers, bkt pr edit --with-default-reviewers / --remove-reviewer will send an account ID under the username field instead of account_id, which can 400 or silently lose reviewers on Cloud repos that no longer expose usernames.
Please fix the serializer so the update payload emits account_id when the reviewer token is an account ID, and add an end-to-end request-shape test covering the edit flow so this path is exercised outside the helper-level tests.
The UpdatePullRequest and CreatePullRequest serializers only handled UUID
vs username, sending AccountID-only reviewers under the wrong field.
Add LooksLikeAccountID detection and a shared reviewerIdentity helper
so the API payload emits {"account_id": ...} for Atlassian Account IDs.
|
Fixed in dcd8da4. Added Tests added:
|
avivsinai
left a comment
There was a problem hiding this comment.
Re-reviewed the latest head after the serializer fix. The Cloud reviewer identity path now correctly emits account_id for AccountID-only reviewers, the create/update serializers are aligned through a shared helper, and the request-shape coverage is in place. LGTM.
Summary
This change adds
--with-default-reviewerssupport tobkt pr editfor both Bitbucket Data Center and Bitbucket Cloud so existing pull requests can be updated to include repository defaults without recreating them. It reuses the existing default-reviewer lookup behavior frombkt pr create, preserves current reviewer-edit semantics, and fixes the boolean flag handling so--with-default-reviewers=falsedoes not trigger reviewer changes.Changes
--with-default-reviewerstobkt pr edit.pr editnow fetches default reviewers using the PR's current source and target refs and merges them into the existing reviewer set.pr editnow fetches effective default reviewers, excludes the PR author, preserves reviewer UUIDs in update payloads, and applies explicit--reviewer/--remove-reviewerchanges on top.pr createandpr edituse the same host-specific helper paths instead of duplicating the behavior.--with-default-reviewers=falsecase so explicit false values do not trigger reviewer mutations.bktskill docs so thepr editreference now includes the new flag and example usage.Testing
pre-commit run --files pkg/bbcloud/pullrequests.go pkg/cmd/pr/pr.go pkg/cmd/pr/pr_test.go skills/bkt/rules/pr.mdgo test ./...Risks
pr edit, especially the Cloud path that excludes the PR author and preserves UUID-based reviewers.--with-default-reviewers=falsehandling is covered by regression tests.