fix: preserve existing reviewers when updating PR without specifying reviewers

- Modified handleUpdatePullRequest to include existing reviewers when reviewers parameter is omitted
- Preserves approval status for existing reviewers when updating reviewer list
- Updated tool documentation to clarify reviewer preservation behavior
- Enhanced README with detailed explanation of reviewer handling
- Bumped version to 0.9.1

This prevents accidentally removing reviewers when only updating PR title or description.
This commit is contained in:
pdogra1299 2025-06-27 19:56:38 +05:30
parent f602840c97
commit e21f2dcfe8
6 changed files with 49 additions and 7 deletions

View file

@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.9.1] - 2025-01-27
### Fixed
- **Fixed `update_pull_request` reviewer preservation**:
- When updating a PR without specifying reviewers, existing reviewers are now preserved
- Previously, omitting the `reviewers` parameter would clear all reviewers
- Now properly includes existing reviewers in the API request when not explicitly updating them
- When updating reviewers, approval status is preserved for existing reviewers
- This prevents accidentally removing reviewers when only updating PR title or description
### Changed
- Updated tool documentation to clarify reviewer behavior in `update_pull_request`
- Enhanced README with detailed explanation of reviewer handling
## [0.9.0] - 2025-01-26 ## [0.9.0] - 2025-01-26
### Added ### Added

View file

@ -264,11 +264,19 @@ Returns a paginated list of pull requests with:
"title": "Updated title", // Optional "title": "Updated title", // Optional
"description": "Updated description", // Optional "description": "Updated description", // Optional
"destination_branch": "develop", // Optional "destination_branch": "develop", // Optional
"reviewers": ["new.reviewer"] // Optional - replaces existing reviewers "reviewers": ["new.reviewer"] // Optional - see note below
} }
} }
``` ```
**Important Note on Reviewers:**
- When updating a PR without specifying the `reviewers` parameter, existing reviewers and their approval status are preserved
- When providing the `reviewers` parameter:
- The reviewer list is replaced with the new list
- For reviewers that already exist on the PR, their approval status is preserved
- New reviewers are added without approval status
- This prevents accidentally removing reviewers when you only want to update the PR description or title
### Add Comment ### Add Comment
Add a comment to a pull request, either as a general comment or inline on specific code: Add a comment to a pull request, either as a general comment or inline on specific code:

View file

@ -1,6 +1,6 @@
{ {
"name": "@nexus2520/bitbucket-mcp-server", "name": "@nexus2520/bitbucket-mcp-server",
"version": "0.9.0", "version": "0.9.1",
"description": "MCP server for Bitbucket API integration - supports both Cloud and Server", "description": "MCP server for Bitbucket API integration - supports both Cloud and Server",
"type": "module", "type": "module",
"main": "./build/index.js", "main": "./build/index.js",

View file

@ -348,7 +348,7 @@ export class PullRequestHandlers {
// Bitbucket Server API // Bitbucket Server API
apiPath = `/rest/api/1.0/projects/${workspace}/repos/${repository}/pull-requests/${pull_request_id}`; apiPath = `/rest/api/1.0/projects/${workspace}/repos/${repository}/pull-requests/${pull_request_id}`;
// First get the current PR to get version number // First get the current PR to get version number and existing data
const currentPr = await this.apiClient.makeRequest<any>('get', apiPath); const currentPr = await this.apiClient.makeRequest<any>('get', apiPath);
requestBody.version = currentPr.version; requestBody.version = currentPr.version;
@ -365,8 +365,28 @@ export class PullRequestHandlers {
} }
}; };
} }
// Handle reviewers: preserve existing ones if not explicitly updating
if (reviewers !== undefined) { if (reviewers !== undefined) {
requestBody.reviewers = reviewers.map(r => ({ user: { name: r } })); // User wants to update reviewers
// Create a map of existing reviewers for preservation of approval status
const existingReviewersMap = new Map(
currentPr.reviewers.map((r: any) => [r.user.name, r])
);
requestBody.reviewers = reviewers.map(username => {
const existing = existingReviewersMap.get(username);
if (existing) {
// Preserve existing reviewer's full data including approval status
return existing;
} else {
// Add new reviewer (without approval status)
return { user: { name: username } };
}
});
} else {
// No reviewers provided - preserve existing reviewers with their full data
requestBody.reviewers = currentPr.reviewers;
} }
} else { } else {
// Bitbucket Cloud API // Bitbucket Cloud API

View file

@ -40,7 +40,7 @@ class BitbucketMCPServer {
this.server = new Server( this.server = new Server(
{ {
name: 'bitbucket-mcp-server', name: 'bitbucket-mcp-server',
version: '0.9.0', version: '0.9.1',
}, },
{ {
capabilities: { capabilities: {

View file

@ -101,7 +101,7 @@ export const toolDefinitions = [
}, },
{ {
name: 'update_pull_request', name: 'update_pull_request',
description: 'Update an existing pull request', description: 'Update an existing pull request. When updating without specifying reviewers, existing reviewers and their approval status will be preserved.',
inputSchema: { inputSchema: {
type: 'object', type: 'object',
properties: { properties: {
@ -132,7 +132,7 @@ export const toolDefinitions = [
reviewers: { reviewers: {
type: 'array', type: 'array',
items: { type: 'string' }, items: { type: 'string' },
description: 'New list of reviewer usernames/emails (optional)', description: 'New list of reviewer usernames/emails. If provided, replaces the reviewer list (preserving approval status for existing reviewers). If omitted, existing reviewers are preserved. (optional)',
}, },
}, },
required: ['workspace', 'repository', 'pull_request_id'], required: ['workspace', 'repository', 'pull_request_id'],