@atlassian-dc-mcp/bitbucket 0.28.0 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +53 -1
  3. package/build/__tests__/bitbucket-service.test.js +25 -1
  4. package/build/__tests__/bitbucket-service.test.js.map +1 -1
  5. package/build/__tests__/bitbucket-token-optimization.test.js +11 -0
  6. package/build/__tests__/bitbucket-token-optimization.test.js.map +1 -1
  7. package/build/__tests__/merge-gateway.test.d.ts +2 -0
  8. package/build/__tests__/merge-gateway.test.d.ts.map +1 -0
  9. package/build/__tests__/merge-gateway.test.js +98 -0
  10. package/build/__tests__/merge-gateway.test.js.map +1 -0
  11. package/build/__tests__/pr-comment-mapper.test.js +91 -11
  12. package/build/__tests__/pr-comment-mapper.test.js.map +1 -1
  13. package/build/__tests__/pr-merge.test.d.ts +2 -0
  14. package/build/__tests__/pr-merge.test.d.ts.map +1 -0
  15. package/build/__tests__/pr-merge.test.js +166 -0
  16. package/build/__tests__/pr-merge.test.js.map +1 -0
  17. package/build/bitbucket-response-mapper.d.ts +10 -0
  18. package/build/bitbucket-response-mapper.d.ts.map +1 -1
  19. package/build/bitbucket-response-mapper.js +16 -0
  20. package/build/bitbucket-response-mapper.js.map +1 -1
  21. package/build/bitbucket-service.d.ts +53 -9
  22. package/build/bitbucket-service.d.ts.map +1 -1
  23. package/build/bitbucket-service.js +70 -15
  24. package/build/bitbucket-service.js.map +1 -1
  25. package/build/index.js +30 -4
  26. package/build/index.js.map +1 -1
  27. package/build/merge-gateway.d.ts +34 -0
  28. package/build/merge-gateway.d.ts.map +1 -0
  29. package/build/merge-gateway.js +86 -0
  30. package/build/merge-gateway.js.map +1 -0
  31. package/build/pr-comment-mapper.d.ts +3 -0
  32. package/build/pr-comment-mapper.d.ts.map +1 -1
  33. package/build/pr-comment-mapper.js +8 -3
  34. package/build/pr-comment-mapper.js.map +1 -1
  35. package/build/pr-merge.d.ts +23 -0
  36. package/build/pr-merge.d.ts.map +1 -0
  37. package/build/pr-merge.js +59 -0
  38. package/build/pr-merge.js.map +1 -0
  39. package/package.json +3 -3
  40. package/src/__tests__/bitbucket-service.test.ts +78 -1
  41. package/src/__tests__/bitbucket-token-optimization.test.ts +11 -0
  42. package/src/__tests__/merge-gateway.test.ts +119 -0
  43. package/src/__tests__/pr-comment-mapper.test.ts +95 -11
  44. package/src/__tests__/pr-merge.test.ts +206 -0
  45. package/src/bitbucket-response-mapper.ts +27 -0
  46. package/src/bitbucket-service.ts +75 -14
  47. package/src/index.ts +45 -6
  48. package/src/merge-gateway.ts +132 -0
  49. package/src/pr-comment-mapper.ts +11 -3
  50. package/src/pr-merge.ts +94 -0
  51. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,86 @@
1
+ const DISABLED = { enabled: false, repos: [], targetRefs: [] };
2
+ const REPO_ENTRY_RE = /^[^\s/]+\/[^\s/]+$/;
3
+ function readBool(env, name) {
4
+ const value = env[name]?.trim().toLowerCase();
5
+ return value === 'true' || value === '1' || value === 'yes';
6
+ }
7
+ function parseList(raw) {
8
+ return (raw ?? '').split(/[,;\s]+/).map(entry => entry.trim()).filter(Boolean);
9
+ }
10
+ function dedupe(values) {
11
+ return [...new Set(values)];
12
+ }
13
+ /**
14
+ * Accepts `PROJECT/repository-slug` or `PROJECT/*`. The project key is upper-cased and
15
+ * the slug lower-cased to match the casing the REST API uses, so comparisons are exact.
16
+ */
17
+ function normalizeRepoEntry(entry, warn) {
18
+ if (!REPO_ENTRY_RE.test(entry)) {
19
+ warn(`Ignoring merge repository entry that is not "PROJECT/repository-slug" or "PROJECT/*": "${entry}"`);
20
+ return undefined;
21
+ }
22
+ const [projectKey, slug] = entry.split('/');
23
+ if (projectKey === '*') {
24
+ warn(`Ignoring merge repository entry that would allow every project: "${entry}"`);
25
+ return undefined;
26
+ }
27
+ return `${projectKey.toUpperCase()}/${slug.toLowerCase()}`;
28
+ }
29
+ /** Bare branch names are expanded so operators can write `develop` instead of `refs/heads/develop`. */
30
+ function normalizeRefEntry(entry) {
31
+ return entry.startsWith('refs/') ? entry : `refs/heads/${entry}`;
32
+ }
33
+ function matchesPattern(value, pattern) {
34
+ return pattern.endsWith('*') ? value.startsWith(pattern.slice(0, -1)) : value === pattern;
35
+ }
36
+ /**
37
+ * Reads the merge gateway configuration from the environment. Merging only activates
38
+ * when the flag is set and at least one repository entry is valid; otherwise a warning
39
+ * is logged and the gateway stays disabled.
40
+ */
41
+ export function resolveMergeGateway(options) {
42
+ const env = options?.env ?? process.env;
43
+ const warn = options?.warn ?? ((message) => console.error(`[merge-gateway] ${message}`));
44
+ if (!readBool(env, 'BITBUCKET_MERGE_ENABLED')) {
45
+ return DISABLED;
46
+ }
47
+ const repos = dedupe(parseList(env.BITBUCKET_MERGE_ALLOWED_REPOS)
48
+ .map(entry => normalizeRepoEntry(entry, warn))
49
+ .filter((entry) => Boolean(entry)));
50
+ if (repos.length === 0) {
51
+ warn('Merging was enabled but no valid repository is configured (set BITBUCKET_MERGE_ALLOWED_REPOS ' +
52
+ 'to a list of "PROJECT/repository-slug" or "PROJECT/*" entries); the merge tool will stay disabled.');
53
+ return DISABLED;
54
+ }
55
+ return {
56
+ enabled: true,
57
+ repos,
58
+ targetRefs: dedupe(parseList(env.BITBUCKET_MERGE_ALLOWED_TARGET_REFS).map(normalizeRefEntry)),
59
+ };
60
+ }
61
+ /** Throws unless the gateway allows merging in this repository. No network call. */
62
+ export function assertRepoMergeAllowed(gateway, projectKey, repositorySlug) {
63
+ if (!gateway.enabled) {
64
+ throw new Error('Merging pull requests is disabled on this server. Enable it with BITBUCKET_MERGE_ENABLED ' +
65
+ 'and list the allowed repositories in BITBUCKET_MERGE_ALLOWED_REPOS.');
66
+ }
67
+ const target = `${projectKey.toUpperCase()}/${repositorySlug.toLowerCase()}`;
68
+ if (!gateway.repos.some(pattern => matchesPattern(target, pattern))) {
69
+ throw new Error(`Merging is not allowed in ${target} on this server. Allowed: ${gateway.repos.join(', ')}.`);
70
+ }
71
+ }
72
+ /** Throws unless the gateway allows merging into this target ref. A gateway with no ref restriction allows all. */
73
+ export function assertTargetRefMergeAllowed(gateway, targetRefId) {
74
+ if (gateway.targetRefs.length === 0) {
75
+ return;
76
+ }
77
+ if (!targetRefId) {
78
+ throw new Error('Could not determine the target branch of the pull request, and this server restricts which ' +
79
+ 'branches may be merged into (BITBUCKET_MERGE_ALLOWED_TARGET_REFS); refusing to merge.');
80
+ }
81
+ if (!gateway.targetRefs.some(pattern => matchesPattern(targetRefId, pattern))) {
82
+ throw new Error(`Merging into ${targetRefId} is not allowed on this server. ` +
83
+ `Allowed target refs: ${gateway.targetRefs.join(', ')}.`);
84
+ }
85
+ }
86
+ //# sourceMappingURL=merge-gateway.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge-gateway.js","sourceRoot":"","sources":["../src/merge-gateway.ts"],"names":[],"mappings":"AAqBA,MAAM,QAAQ,GAAiB,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;AAE7E,MAAM,aAAa,GAAG,oBAAoB,CAAC;AAE3C,SAAS,QAAQ,CAAC,GAAQ,EAAE,IAAY;IACtC,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC9C,OAAO,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,KAAK,CAAC;AAC9D,CAAC;AAED,SAAS,SAAS,CAAC,GAAuB;IACxC,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AACjF,CAAC;AAED,SAAS,MAAM,CAAC,MAAgB;IAC9B,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED;;;GAGG;AACH,SAAS,kBAAkB,CAAC,KAAa,EAAE,IAAU;IACnD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/B,IAAI,CAAC,0FAA0F,KAAK,GAAG,CAAC,CAAC;QACzG,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC5C,IAAI,UAAU,KAAK,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,oEAAoE,KAAK,GAAG,CAAC,CAAC;QACnF,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,GAAG,UAAU,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;AAC7D,CAAC;AAED,uGAAuG;AACvG,SAAS,iBAAiB,CAAC,KAAa;IACtC,OAAO,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,KAAK,EAAE,CAAC;AACnE,CAAC;AAED,SAAS,cAAc,CAAC,KAAa,EAAE,OAAe;IACpD,OAAO,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,OAAO,CAAC;AAC5F,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAoC;IACtE,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACxC,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,CAAC,CAAC,OAAe,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,mBAAmB,OAAO,EAAE,CAAC,CAAC,CAAC;IAEjG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,yBAAyB,CAAC,EAAE,CAAC;QAC9C,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAClB,SAAS,CAAC,GAAG,CAAC,6BAA6B,CAAC;SACzC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;SAC7C,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CACtD,CAAC;IAEF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,IAAI,CACF,+FAA+F;YAC7F,oGAAoG,CACvG,CAAC;QACF,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,OAAO;QACL,OAAO,EAAE,IAAI;QACb,KAAK;QACL,UAAU,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;KAC9F,CAAC;AACJ,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,sBAAsB,CAAC,OAAqB,EAAE,UAAkB,EAAE,cAAsB;IACtG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,2FAA2F;YACzF,qEAAqE,CACxE,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,GAAG,UAAU,CAAC,WAAW,EAAE,IAAI,cAAc,CAAC,WAAW,EAAE,EAAE,CAAC;IAC7E,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;QACpE,MAAM,IAAI,KAAK,CACb,6BAA6B,MAAM,6BAA6B,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAC5F,CAAC;IACJ,CAAC;AACH,CAAC;AAED,mHAAmH;AACnH,MAAM,UAAU,2BAA2B,CAAC,OAAqB,EAAE,WAA+B;IAChG,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO;IACT,CAAC;IACD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,6FAA6F;YAC3F,uFAAuF,CAC1F,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,cAAc,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;QAC9E,MAAM,IAAI,KAAK,CACb,gBAAgB,WAAW,kCAAkC;YAC3D,wBAAwB,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAC3D,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -26,6 +26,7 @@ interface SimplifiedComment {
26
26
  comments: SimplifiedComment[];
27
27
  threadResolved: boolean;
28
28
  state: string;
29
+ severity: string;
29
30
  }
30
31
  interface SimplifiedActivity {
31
32
  id: number;
@@ -43,6 +44,8 @@ export interface SimplifiedPRResponse {
43
44
  prAuthor?: SimplifiedUser;
44
45
  commentCount: number;
45
46
  unresolvedCount: number;
47
+ blockerCount: number;
48
+ unresolvedBlockerCount: number;
46
49
  };
47
50
  }
48
51
  export interface PullRequestCommentOptions {
@@ -1 +1 @@
1
- {"version":3,"file":"pr-comment-mapper.d.ts","sourceRoot":"","sources":["../src/pr-comment-mapper.ts"],"names":[],"mappings":"AAsHA,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAGD,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,iBAAiB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,cAAc,EAAE,OAAO,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,kBAAkB;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,kBAAkB,EAAE,CAAC;IACjC,OAAO,EAAE;QACP,eAAe,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,EAAE,cAAc,CAAC;QAC1B,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;CACH;AAED,MAAM,WAAW,yBAAyB;IACxC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AA2HD,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,sBAAsB,EAChC,OAAO,GAAE,yBAA8B,GACtC,sBAAsB,CAyBxB;AAeD,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,sBAAsB,EAChC,OAAO,GAAE,yBAA8B,GACtC,oBAAoB,GAAG,sBAAsB,CAkC/C;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,sBAAsB,EAAE,OAAO,GAAE,yBAA8B,GAAG,MAAM,EAAE,CAmBrH"}
1
+ {"version":3,"file":"pr-comment-mapper.d.ts","sourceRoot":"","sources":["../src/pr-comment-mapper.ts"],"names":[],"mappings":"AAsHA,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAGD,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,iBAAiB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,cAAc,EAAE,OAAO,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,kBAAkB;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,kBAAkB,EAAE,CAAC;IACjC,OAAO,EAAE;QACP,eAAe,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,EAAE,cAAc,CAAC;QAC1B,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;QACxB,YAAY,EAAE,MAAM,CAAC;QACrB,sBAAsB,EAAE,MAAM,CAAC;KAChC,CAAC;CACH;AAED,MAAM,WAAW,yBAAyB;IACxC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AA4HD,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,sBAAsB,EAChC,OAAO,GAAE,yBAA8B,GACtC,sBAAsB,CAyBxB;AAeD,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,sBAAsB,EAChC,OAAO,GAAE,yBAA8B,GACtC,oBAAoB,GAAG,sBAAsB,CAsC/C;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,sBAAsB,EAAE,OAAO,GAAE,yBAA8B,GAAG,MAAM,EAAE,CAmBrH"}
@@ -80,7 +80,8 @@ function simplifyComment(comment, ancestorIds = new Set()) {
80
80
  .filter(childComment => !nextAncestorIds.has(childComment.id))
81
81
  .map(childComment => simplifyComment(childComment, nextAncestorIds)),
82
82
  threadResolved: comment.threadResolved,
83
- state: comment.state
83
+ state: comment.state,
84
+ severity: comment.severity
84
85
  };
85
86
  }
86
87
  function filterComment(comment, includeResolved, ancestorIds = new Set()) {
@@ -149,9 +150,11 @@ export function simplifyBitbucketPRComments(response, options = {}) {
149
150
  }
150
151
  // Find PR author (usually the one who OPENED the PR)
151
152
  const prAuthor = activities.find(a => a.action === 'OPENED')?.user;
152
- // Count comments and unresolved threads
153
+ // Count comments, unresolved threads and blocker tasks
153
154
  const comments = activities.filter(a => a.action === 'COMMENTED' && a.comment);
154
155
  const unresolvedCount = comments.filter(a => a.comment && !a.comment.threadResolved).length;
156
+ const blockers = comments.filter(a => a.comment && a.comment.severity === 'BLOCKER');
157
+ const unresolvedBlockerCount = blockers.filter(a => a.comment && a.comment.state !== 'RESOLVED').length;
155
158
  return {
156
159
  isLastPage: filteredResponse.isLastPage ?? true,
157
160
  activities,
@@ -159,7 +162,9 @@ export function simplifyBitbucketPRComments(response, options = {}) {
159
162
  totalActivities: activities.length,
160
163
  ...(prAuthor && { prAuthor }),
161
164
  commentCount: comments.length,
162
- unresolvedCount
165
+ unresolvedCount,
166
+ blockerCount: blockers.length,
167
+ unresolvedBlockerCount
163
168
  }
164
169
  };
165
170
  }
@@ -1 +1 @@
1
- {"version":3,"file":"pr-comment-mapper.js","sourceRoot":"","sources":["../src/pr-comment-mapper.ts"],"names":[],"mappings":"AAgLA,oDAAoD;AACpD,SAAS,eAAe,CAAC,GAAY;IACnC,OAAO,CACL,OAAO,GAAG,KAAK,QAAQ;QACvB,GAAG,KAAK,IAAI;QACZ,OAAQ,GAAW,CAAC,IAAI,KAAK,QAAQ;QACrC,OAAQ,GAAW,CAAC,YAAY,KAAK,QAAQ;QAC7C,OAAQ,GAAW,CAAC,MAAM,KAAK,SAAS;QACxC,OAAQ,GAAW,CAAC,WAAW,KAAK,QAAQ;QAC5C,OAAQ,GAAW,CAAC,EAAE,KAAK,QAAQ;QACnC,OAAQ,GAAW,CAAC,IAAI,KAAK,QAAQ;QACrC,OAAQ,GAAW,CAAC,IAAI,KAAK,QAAQ;QACrC,OAAQ,GAAW,CAAC,KAAK,KAAK,QAAQ,CACvC,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,GAAY;IACnC,OAAO,CACL,OAAO,GAAG,KAAK,QAAQ;QACvB,GAAG,KAAK,IAAI;QACZ,OAAQ,GAAW,CAAC,QAAQ,KAAK,QAAQ;QACzC,OAAQ,GAAW,CAAC,MAAM,KAAK,QAAQ;QACvC,OAAQ,GAAW,CAAC,IAAI,KAAK,QAAQ;QACrC,OAAQ,GAAW,CAAC,QAAQ,KAAK,QAAQ;QACzC,OAAQ,GAAW,CAAC,QAAQ,KAAK,QAAQ;QACzC,OAAQ,GAAW,CAAC,IAAI,KAAK,QAAQ;QACrC,OAAQ,GAAW,CAAC,QAAQ,KAAK,QAAQ;QACzC,OAAQ,GAAW,CAAC,QAAQ,KAAK,SAAS,CAC3C,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,GAAY;IAC7B,OAAO,CACL,OAAO,GAAG,KAAK,QAAQ;QACvB,GAAG,KAAK,IAAI;QACZ,OAAQ,GAAW,CAAC,EAAE,KAAK,QAAQ;QACnC,OAAQ,GAAW,CAAC,OAAO,KAAK,QAAQ;QACxC,OAAQ,GAAW,CAAC,IAAI,KAAK,QAAQ;QACrC,eAAe,CAAE,GAAW,CAAC,MAAM,CAAC;QACpC,OAAQ,GAAW,CAAC,WAAW,KAAK,QAAQ;QAC5C,OAAQ,GAAW,CAAC,WAAW,KAAK,QAAQ;QAC5C,KAAK,CAAC,OAAO,CAAE,GAAW,CAAC,QAAQ,CAAC;QACpC,OAAQ,GAAW,CAAC,cAAc,KAAK,SAAS;QAChD,OAAQ,GAAW,CAAC,QAAQ,KAAK,QAAQ;QACzC,OAAQ,GAAW,CAAC,KAAK,KAAK,QAAQ;QACtC,OAAQ,GAAW,CAAC,UAAU,KAAK,QAAQ;QAC3C,OAAQ,GAAW,CAAC,mBAAmB,KAAK,QAAQ,CACrD,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,GAAY;IAChC,OAAO,CACL,OAAO,GAAG,KAAK,QAAQ;QACvB,GAAG,KAAK,IAAI;QACZ,OAAQ,GAAW,CAAC,EAAE,KAAK,QAAQ;QACnC,OAAQ,GAAW,CAAC,WAAW,KAAK,QAAQ;QAC5C,eAAe,CAAE,GAAW,CAAC,IAAI,CAAC;QAClC,OAAQ,GAAW,CAAC,MAAM,KAAK,QAAQ,CACxC,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,IAAmB;IACvC,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,WAAW,EAAE,IAAI,CAAC,WAAW;KAC9B,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,MAAqB;IAC3C,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,GAAG,CAAC,MAAM,CAAC,eAAe;YACxB,CAAC,CAAC;gBACE,SAAS,EAAE,MAAM,CAAC,eAAe,CAAC,SAAS;gBAC3C,aAAa,EAAE,MAAM,CAAC,eAAe,CAAC,aAAa;aACpD;YACH,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,OAAgB,EAAE,cAA2B,IAAI,GAAG,EAAE;IAC7E,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7C,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAEhC,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC;QACpC,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACjE,QAAQ,EAAE,OAAO,CAAC,QAAQ;aACvB,MAAM,CAAC,SAAS,CAAC;aACjB,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;aAC7D,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,eAAe,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;QACtE,cAAc,EAAE,OAAO,CAAC,cAAc;QACtC,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,OAAgB,EAAE,eAAwB,EAAE,cAA2B,IAAI,GAAG,EAAE;IACrG,IAAI,CAAC,eAAe,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;QAC/C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7C,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAEhC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ;SAC9B,MAAM,CAAC,SAAS,CAAC;SACjB,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;SAC7D,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,eAAe,EAAE,eAAe,CAAC,CAAC;SAClF,MAAM,CAAC,CAAC,YAAY,EAA2B,EAAE,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC;IAE5E,OAAO;QACL,GAAG,OAAO;QACV,QAAQ;KACT,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,QAAgC,EAChC,UAAqC,EAAE;IAEvC,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,KAAK,CAAC;IAEzD,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,OAAO;QACL,GAAG,QAAQ;QACX,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;YACjD,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBACpH,OAAO,CAAC,QAAQ,CAAC,CAAC;YACpB,CAAC;YAED,MAAM,eAAe,GAAG,aAAa,CAAC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;YACzE,IAAI,CAAC,eAAe,EAAE,CAAC;gBACrB,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,OAAO,CAAC;oBACN,GAAG,QAAQ;oBACX,OAAO,EAAE,eAAe;iBACzB,CAAC,CAAC;QACL,CAAC,CAAC;KACH,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAoB;IAC5C,OAAO;QACL,EAAE,EAAE,QAAQ,CAAC,EAAE;QACf,WAAW,EAAE,QAAQ,CAAC,WAAW;QACjC,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC;QACjC,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,GAAG,CAAC,QAAQ,CAAC,aAAa,IAAI,EAAE,aAAa,EAAE,QAAQ,CAAC,aAAa,EAAE,CAAC;QACxE,GAAG,CAAC,QAAQ,CAAC,OAAO,IAAI,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI;YACrD,OAAO,EAAE,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC;SAC3C,CAAC;KACH,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,2BAA2B,CACzC,QAAgC,EAChC,UAAqC,EAAE;IAEvC,MAAM,gBAAgB,GAAG,yBAAyB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACtE,MAAM,UAAU,GAAyB,EAAE,CAAC;IAE5C,mDAAmD;IACnD,KAAK,MAAM,QAAQ,IAAI,gBAAgB,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;QACrD,IAAI,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3B,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC9C,CAAC;QACD,4EAA4E;IAC9E,CAAC;IAED,kEAAkE;IAClE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1E,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,qDAAqD;IACrD,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,EAAE,IAAI,CAAC;IAEnE,wCAAwC;IACxC,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC;IAC/E,MAAM,eAAe,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC;IAE5F,OAAO;QACL,UAAU,EAAE,gBAAgB,CAAC,UAAU,IAAI,IAAI;QAC/C,UAAU;QACV,OAAO,EAAE;YACP,eAAe,EAAE,UAAU,CAAC,MAAM;YAClC,GAAG,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,CAAC;YAC7B,YAAY,EAAE,QAAQ,CAAC,MAAM;YAC7B,eAAe;SAChB;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,QAAgC,EAAE,UAAqC,EAAE;IACzG,MAAM,gBAAgB,GAAG,yBAAyB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACtE,MAAM,gBAAgB,GAAa,EAAE,CAAC;IAEtC,KAAK,MAAM,QAAQ,IAAI,gBAAgB,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;QACrD,gDAAgD;QAChD,IAAI,YAAY,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,WAAW,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YAClF,8CAA8C;YAC9C,IAAI,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBAChC,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;gBACjC,gBAAgB,CAAC,IAAI,CACnB,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,OAAO,OAAO,CAAC,MAAM,EAAE,IAAI,IAAI,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,KAAK,OAAO,CAAC,IAAI,EAAE,CAClH,CAAC;YACJ,CAAC;QACH,CAAC;QACD,4EAA4E;IAC9E,CAAC;IAED,OAAO,gBAAgB,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"pr-comment-mapper.js","sourceRoot":"","sources":["../src/pr-comment-mapper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { BitbucketMutationOutputMode } from './bitbucket-response-mapper.js';
2
+ import { type MergeGateway } from './merge-gateway.js';
3
+ export interface MergePullRequestParams {
4
+ projectKey: string;
5
+ repositorySlug: string;
6
+ pullRequestId: string;
7
+ /** Current PR version, required for optimistic locking. */
8
+ version: number;
9
+ gateway: MergeGateway;
10
+ strategyId?: string;
11
+ message?: string;
12
+ output?: BitbucketMutationOutputMode;
13
+ }
14
+ /** Read-only mergeability check: reports conflicts and merge-check vetoes. */
15
+ export declare function fetchMergeability(projectKey: string, repositorySlug: string, pullRequestId: string): Promise<import("@atlassian-dc-mcp/common").ApiErrorResponse<import("./bitbucket-client/index.js").RestPullRequestMergeability>>;
16
+ /**
17
+ * Merge a pull request under the operator's merge policy. Order matters: the repository
18
+ * (and target branch, when restricted) is checked before any request, and the mergeability
19
+ * check runs before the POST so a conflicted or vetoed pull request is refused without
20
+ * issuing the write.
21
+ */
22
+ export declare function mergePullRequest(params: MergePullRequestParams): Promise<import("@atlassian-dc-mcp/common").ApiErrorResponse<import("./bitbucket-client/index.js").RestPullRequest>>;
23
+ //# sourceMappingURL=pr-merge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr-merge.d.ts","sourceRoot":"","sources":["../src/pr-merge.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,2BAA2B,EAG5B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAuD,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE5G,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,YAAY,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,2BAA2B,CAAC;CACtC;AAED,8EAA8E;AAC9E,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,mIAWxG;AAkCD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,uHAoBpE"}
@@ -0,0 +1,59 @@
1
+ import { handleApiOperation } from '@atlassian-dc-mcp/common';
2
+ import { PullRequestsService } from './bitbucket-client/index.js';
3
+ import { shapeMergeability, shapePullRequestAck, } from './bitbucket-response-mapper.js';
4
+ import { assertRepoMergeAllowed, assertTargetRefMergeAllowed } from './merge-gateway.js';
5
+ /** Read-only mergeability check: reports conflicts and merge-check vetoes. */
6
+ export async function fetchMergeability(projectKey, repositorySlug, pullRequestId) {
7
+ const result = await handleApiOperation(() => PullRequestsService.canMerge(projectKey, pullRequestId, repositorySlug), 'Error checking pull request mergeability');
8
+ if (result.success && result.data) {
9
+ return { ...result, data: shapeMergeability(result.data) };
10
+ }
11
+ return result;
12
+ }
13
+ function describeVetoes(vetoes) {
14
+ return vetoes
15
+ .map(veto => [veto.summary, veto.detail].filter(Boolean).join(' — '))
16
+ .filter(Boolean)
17
+ .join('; ');
18
+ }
19
+ async function assertMergeable(projectKey, repositorySlug, pullRequestId) {
20
+ const mergeability = shapeMergeability(await PullRequestsService.canMerge(projectKey, pullRequestId, repositorySlug));
21
+ if (mergeability.canMerge) {
22
+ return;
23
+ }
24
+ const cause = mergeability.conflicted ? 'it has conflicts' : 'a merge check vetoed the merge';
25
+ const reasons = describeVetoes(mergeability.vetoes);
26
+ throw new Error(`Pull request cannot be merged: ${cause}${reasons ? `. ${reasons}` : ''}`);
27
+ }
28
+ /** Only fetches the pull request when the operator restricts target branches. */
29
+ async function assertTargetRefAllowed(params) {
30
+ if (params.gateway.targetRefs.length === 0) {
31
+ return;
32
+ }
33
+ const pullRequest = await PullRequestsService.get3(params.projectKey, params.pullRequestId, params.repositorySlug);
34
+ assertTargetRefMergeAllowed(params.gateway, pullRequest?.toRef?.id);
35
+ }
36
+ /**
37
+ * Merge a pull request under the operator's merge policy. Order matters: the repository
38
+ * (and target branch, when restricted) is checked before any request, and the mergeability
39
+ * check runs before the POST so a conflicted or vetoed pull request is refused without
40
+ * issuing the write.
41
+ */
42
+ export async function mergePullRequest(params) {
43
+ const { projectKey, repositorySlug, pullRequestId, version, gateway } = params;
44
+ const result = await handleApiOperation(async () => {
45
+ assertRepoMergeAllowed(gateway, projectKey, repositorySlug);
46
+ await assertTargetRefAllowed(params);
47
+ await assertMergeable(projectKey, repositorySlug, pullRequestId);
48
+ return PullRequestsService.merge(projectKey, pullRequestId, repositorySlug, String(version), {
49
+ version,
50
+ ...(params.strategyId ? { strategyId: params.strategyId } : {}),
51
+ ...(params.message ? { message: params.message } : {}),
52
+ });
53
+ }, 'Error merging pull request');
54
+ if (result.success && result.data && params.output !== 'full') {
55
+ return { ...result, data: shapePullRequestAck(result.data) };
56
+ }
57
+ return result;
58
+ }
59
+ //# sourceMappingURL=pr-merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr-merge.js","sourceRoot":"","sources":["../src/pr-merge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAEL,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,sBAAsB,EAAE,2BAA2B,EAAqB,MAAM,oBAAoB,CAAC;AAc5G,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,UAAkB,EAAE,cAAsB,EAAE,aAAqB;IACvG,MAAM,MAAM,GAAG,MAAM,kBAAkB,CACrC,GAAG,EAAE,CAAC,mBAAmB,CAAC,QAAQ,CAAC,UAAU,EAAE,aAAa,EAAE,cAAc,CAAC,EAC7E,0CAA0C,CAC3C,CAAC;IAEF,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAClC,OAAO,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;IAC7D,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,cAAc,CAAC,MAAoD;IAC1E,OAAO,MAAM;SACV,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SACpE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,UAAkB,EAAE,cAAsB,EAAE,aAAqB;IAC9F,MAAM,YAAY,GAAG,iBAAiB,CACpC,MAAM,mBAAmB,CAAC,QAAQ,CAAC,UAAU,EAAE,aAAa,EAAE,cAAc,CAAC,CAC9E,CAAC;IACF,IAAI,YAAY,CAAC,QAAQ,EAAE,CAAC;QAC1B,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,gCAAgC,CAAC;IAC9F,MAAM,OAAO,GAAG,cAAc,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,IAAI,KAAK,CAAC,kCAAkC,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC7F,CAAC;AAED,iFAAiF;AACjF,KAAK,UAAU,sBAAsB,CAAC,MAA8B;IAClE,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3C,OAAO;IACT,CAAC;IACD,MAAM,WAAW,GAAQ,MAAM,mBAAmB,CAAC,IAAI,CACrD,MAAM,CAAC,UAAU,EACjB,MAAM,CAAC,aAAa,EACpB,MAAM,CAAC,cAAc,CACtB,CAAC;IACF,2BAA2B,CAAC,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;AACtE,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAA8B;IACnE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAE/E,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,KAAK,IAAI,EAAE;QACjD,sBAAsB,CAAC,OAAO,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC;QAC5D,MAAM,sBAAsB,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,eAAe,CAAC,UAAU,EAAE,cAAc,EAAE,aAAa,CAAC,CAAC;QAEjE,OAAO,mBAAmB,CAAC,KAAK,CAAC,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE;YAC3F,OAAO;YACP,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/D,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACvD,CAAC,CAAC;IACL,CAAC,EAAE,4BAA4B,CAAC,CAAC;IAEjC,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC9D,OAAO,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;IAC/D,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlassian-dc-mcp/bitbucket",
3
- "version": "0.28.0",
3
+ "version": "0.30.0",
4
4
  "main": "build/index.js",
5
5
  "type": "module",
6
6
  "bin": "./bin/run.js",
@@ -31,7 +31,7 @@
31
31
  "test": "jest"
32
32
  },
33
33
  "dependencies": {
34
- "@atlassian-dc-mcp/common": "^0.28.0",
34
+ "@atlassian-dc-mcp/common": "^0.30.0",
35
35
  "@modelcontextprotocol/sdk": "^1.27.1",
36
36
  "dotenv": "^16.4.7",
37
37
  "zod": "^3.24.2"
@@ -48,5 +48,5 @@
48
48
  "publishConfig": {
49
49
  "access": "public"
50
50
  },
51
- "gitHead": "7f51cd1b0328ecc90785211511415e9609d09a25"
51
+ "gitHead": "92a4fc60548de5ee374489deef4d09271536014f"
52
52
  }
@@ -2166,7 +2166,7 @@ describe('BitbucketService', () => {
2166
2166
  const mockComment = { id: 502, version: 4, text: 'New body', state: 'RESOLVED', severity: 'BLOCKER' };
2167
2167
  (PullRequestsService.updateComment2 as jest.Mock).mockResolvedValue(mockComment);
2168
2168
 
2169
- await bitbucketService.updatePullRequestComment(
2169
+ const result = await bitbucketService.updatePullRequestComment(
2170
2170
  mockProjectKey,
2171
2171
  mockRepositorySlug,
2172
2172
  mockPullRequestId,
@@ -2184,6 +2184,83 @@ describe('BitbucketService', () => {
2184
2184
  mockRepositorySlug,
2185
2185
  { version: 3, text: 'New body', state: 'RESOLVED', severity: 'BLOCKER' }
2186
2186
  );
2187
+ expect(result.data).toMatchObject({ state: 'RESOLVED', severity: 'BLOCKER' });
2188
+ });
2189
+
2190
+ it('should resolve a comment thread by sending threadResolved true', async () => {
2191
+ const mockComment = { id: 504, version: 3, state: 'OPEN', threadResolved: true };
2192
+ (PullRequestsService.updateComment2 as jest.Mock).mockResolvedValue(mockComment);
2193
+
2194
+ const result = await bitbucketService.updatePullRequestComment(
2195
+ mockProjectKey,
2196
+ mockRepositorySlug,
2197
+ mockPullRequestId,
2198
+ '504',
2199
+ 2,
2200
+ undefined, // text
2201
+ undefined, // state
2202
+ undefined, // severity
2203
+ true // threadResolved
2204
+ );
2205
+
2206
+ expect(PullRequestsService.updateComment2).toHaveBeenCalledWith(
2207
+ mockProjectKey,
2208
+ '504',
2209
+ mockPullRequestId,
2210
+ mockRepositorySlug,
2211
+ { version: 2, threadResolved: true }
2212
+ );
2213
+ expect(result.data).toMatchObject({ state: 'OPEN', threadResolved: true });
2214
+ });
2215
+
2216
+ it('should reopen a comment thread by sending threadResolved false', async () => {
2217
+ const mockComment = { id: 505, version: 4, threadResolved: false };
2218
+ (PullRequestsService.updateComment2 as jest.Mock).mockResolvedValue(mockComment);
2219
+
2220
+ await bitbucketService.updatePullRequestComment(
2221
+ mockProjectKey,
2222
+ mockRepositorySlug,
2223
+ mockPullRequestId,
2224
+ '505',
2225
+ 3,
2226
+ undefined,
2227
+ undefined,
2228
+ undefined,
2229
+ false
2230
+ );
2231
+
2232
+ expect(PullRequestsService.updateComment2).toHaveBeenCalledWith(
2233
+ mockProjectKey,
2234
+ '505',
2235
+ mockPullRequestId,
2236
+ mockRepositorySlug,
2237
+ { version: 3, threadResolved: false }
2238
+ );
2239
+ });
2240
+
2241
+ it('should set task state and thread resolution independently in one update', async () => {
2242
+ const mockComment = { id: 506, version: 5, state: 'OPEN', threadResolved: true };
2243
+ (PullRequestsService.updateComment2 as jest.Mock).mockResolvedValue(mockComment);
2244
+
2245
+ await bitbucketService.updatePullRequestComment(
2246
+ mockProjectKey,
2247
+ mockRepositorySlug,
2248
+ mockPullRequestId,
2249
+ '506',
2250
+ 4,
2251
+ undefined,
2252
+ 'OPEN',
2253
+ undefined,
2254
+ true
2255
+ );
2256
+
2257
+ expect(PullRequestsService.updateComment2).toHaveBeenCalledWith(
2258
+ mockProjectKey,
2259
+ '506',
2260
+ mockPullRequestId,
2261
+ mockRepositorySlug,
2262
+ { version: 4, state: 'OPEN', threadResolved: true }
2263
+ );
2187
2264
  });
2188
2265
 
2189
2266
  it('should propagate API errors', async () => {
@@ -143,6 +143,7 @@ describe('BitbucketService token optimization paths', () => {
143
143
  comments: [],
144
144
  threadResolved: false,
145
145
  state: 'OPEN',
146
+ severity: 'NORMAL',
146
147
  },
147
148
  },
148
149
  ],
@@ -151,6 +152,8 @@ describe('BitbucketService token optimization paths', () => {
151
152
  prAuthor: { name: 'author', displayName: 'Author' },
152
153
  commentCount: 1,
153
154
  unresolvedCount: 1,
155
+ blockerCount: 0,
156
+ unresolvedBlockerCount: 0,
154
157
  },
155
158
  });
156
159
  expect(PullRequestsService.getActivities).toHaveBeenCalledWith('TEST', '123', 'repo', undefined, undefined, undefined, 25);
@@ -202,6 +205,8 @@ describe('BitbucketService token optimization paths', () => {
202
205
  prAuthor: { name: 'author', displayName: 'Author' },
203
206
  commentCount: 0,
204
207
  unresolvedCount: 0,
208
+ blockerCount: 0,
209
+ unresolvedBlockerCount: 0,
205
210
  },
206
211
  });
207
212
  expect(includeResolvedResult.success).toBe(true);
@@ -238,10 +243,12 @@ describe('BitbucketService token optimization paths', () => {
238
243
  comments: [],
239
244
  threadResolved: true,
240
245
  state: 'OPEN',
246
+ severity: 'NORMAL',
241
247
  },
242
248
  ],
243
249
  threadResolved: true,
244
250
  state: 'OPEN',
251
+ severity: 'NORMAL',
245
252
  },
246
253
  },
247
254
  ],
@@ -250,6 +257,8 @@ describe('BitbucketService token optimization paths', () => {
250
257
  prAuthor: { name: 'author', displayName: 'Author' },
251
258
  commentCount: 1,
252
259
  unresolvedCount: 0,
260
+ blockerCount: 0,
261
+ unresolvedBlockerCount: 0,
253
262
  },
254
263
  });
255
264
  });
@@ -267,6 +276,8 @@ describe('BitbucketService token optimization paths', () => {
267
276
  prAuthor: { name: 'author', displayName: 'Author' },
268
277
  commentCount: 1,
269
278
  unresolvedCount: 1,
279
+ blockerCount: 0,
280
+ unresolvedBlockerCount: 0,
270
281
  },
271
282
  items: ['Reviewer on src/app.ts:10: Looks good'],
272
283
  });
@@ -0,0 +1,119 @@
1
+ import {
2
+ assertRepoMergeAllowed,
3
+ assertTargetRefMergeAllowed,
4
+ resolveMergeGateway,
5
+ } from '../merge-gateway.js';
6
+
7
+ const silentWarn = () => undefined;
8
+
9
+ describe('resolveMergeGateway', () => {
10
+ it('is disabled by default', () => {
11
+ const gateway = resolveMergeGateway({ env: {}, warn: silentWarn });
12
+ expect(gateway.enabled).toBe(false);
13
+ expect(gateway.repos).toEqual([]);
14
+ });
15
+
16
+ it('stays disabled when enabled without any repository', () => {
17
+ const gateway = resolveMergeGateway({ env: { BITBUCKET_MERGE_ENABLED: 'true' }, warn: silentWarn });
18
+ expect(gateway.enabled).toBe(false);
19
+ });
20
+
21
+ it('stays disabled when every configured repository entry is malformed', () => {
22
+ const gateway = resolveMergeGateway({
23
+ env: { BITBUCKET_MERGE_ENABLED: 'true', BITBUCKET_MERGE_ALLOWED_REPOS: 'demo, PROJ/a/b, */*' },
24
+ warn: silentWarn,
25
+ });
26
+ expect(gateway.enabled).toBe(false);
27
+ });
28
+
29
+ it('normalizes repository entries and de-duplicates them', () => {
30
+ const gateway = resolveMergeGateway({
31
+ env: {
32
+ BITBUCKET_MERGE_ENABLED: 'yes',
33
+ BITBUCKET_MERGE_ALLOWED_REPOS: 'proj/Demo, PROJ/demo; OTHER/*',
34
+ },
35
+ warn: silentWarn,
36
+ });
37
+ expect(gateway.enabled).toBe(true);
38
+ expect(gateway.repos).toEqual(['PROJ/demo', 'OTHER/*']);
39
+ expect(gateway.targetRefs).toEqual([]);
40
+ });
41
+
42
+ it('expands bare branch names into fully-qualified target refs', () => {
43
+ const gateway = resolveMergeGateway({
44
+ env: {
45
+ BITBUCKET_MERGE_ENABLED: '1',
46
+ BITBUCKET_MERGE_ALLOWED_REPOS: 'PROJ/demo',
47
+ BITBUCKET_MERGE_ALLOWED_TARGET_REFS: 'develop, refs/heads/release/*',
48
+ },
49
+ warn: silentWarn,
50
+ });
51
+ expect(gateway.targetRefs).toEqual(['refs/heads/develop', 'refs/heads/release/*']);
52
+ });
53
+
54
+ it('warns about ignored entries and about being enabled with no valid repository', () => {
55
+ const warnings: string[] = [];
56
+ resolveMergeGateway({
57
+ env: { BITBUCKET_MERGE_ENABLED: 'true', BITBUCKET_MERGE_ALLOWED_REPOS: 'demo' },
58
+ warn: message => warnings.push(message),
59
+ });
60
+ expect(warnings).toHaveLength(2);
61
+ expect(warnings[0]).toContain('"demo"');
62
+ expect(warnings[1]).toContain('stay disabled');
63
+ });
64
+ });
65
+
66
+ describe('assertRepoMergeAllowed', () => {
67
+ const gateway = resolveMergeGateway({
68
+ env: { BITBUCKET_MERGE_ENABLED: 'true', BITBUCKET_MERGE_ALLOWED_REPOS: 'PROJ/demo, OTHER/*' },
69
+ warn: silentWarn,
70
+ });
71
+
72
+ it('refuses everything when merging is disabled', () => {
73
+ expect(() => assertRepoMergeAllowed({ enabled: false, repos: [], targetRefs: [] }, 'PROJ', 'demo'))
74
+ .toThrow(/disabled on this server/);
75
+ });
76
+
77
+ it('allows an exact repository regardless of the casing used by the caller', () => {
78
+ expect(() => assertRepoMergeAllowed(gateway, 'proj', 'DEMO')).not.toThrow();
79
+ });
80
+
81
+ it('allows any repository in a wildcard project', () => {
82
+ expect(() => assertRepoMergeAllowed(gateway, 'OTHER', 'anything')).not.toThrow();
83
+ });
84
+
85
+ it('refuses a repository outside the allowed list', () => {
86
+ expect(() => assertRepoMergeAllowed(gateway, 'PROJ', 'other-repo')).toThrow(/not allowed in PROJ\/other-repo/);
87
+ });
88
+
89
+ it('does not treat a wildcard project as a prefix of another project', () => {
90
+ expect(() => assertRepoMergeAllowed(gateway, 'OTHERS', 'demo')).toThrow(/not allowed/);
91
+ });
92
+ });
93
+
94
+ describe('assertTargetRefMergeAllowed', () => {
95
+ const unrestricted = { enabled: true, repos: ['PROJ/demo'], targetRefs: [] };
96
+ const restricted = {
97
+ enabled: true,
98
+ repos: ['PROJ/demo'],
99
+ targetRefs: ['refs/heads/develop', 'refs/heads/release/*'],
100
+ };
101
+
102
+ it('allows any ref when no target-ref restriction is configured', () => {
103
+ expect(() => assertTargetRefMergeAllowed(unrestricted, 'refs/heads/master')).not.toThrow();
104
+ expect(() => assertTargetRefMergeAllowed(unrestricted, undefined)).not.toThrow();
105
+ });
106
+
107
+ it('allows an exact and a wildcard target ref', () => {
108
+ expect(() => assertTargetRefMergeAllowed(restricted, 'refs/heads/develop')).not.toThrow();
109
+ expect(() => assertTargetRefMergeAllowed(restricted, 'refs/heads/release/1.2')).not.toThrow();
110
+ });
111
+
112
+ it('refuses a target ref outside the allowed list', () => {
113
+ expect(() => assertTargetRefMergeAllowed(restricted, 'refs/heads/master')).toThrow(/refs\/heads\/master is not allowed/);
114
+ });
115
+
116
+ it('refuses when the target ref is unknown but restrictions apply', () => {
117
+ expect(() => assertTargetRefMergeAllowed(restricted, undefined)).toThrow(/Could not determine the target branch/);
118
+ });
119
+ });