opencode-gitlab-plugin 2.7.0 → 2.8.1
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.
- package/CHANGELOG.md +14 -0
- package/README.md +2 -2
- package/dist/index.js +58 -13
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.cjs +59 -14
- package/dist/mcp-server.cjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [2.8.1](https://gitlab.com/vglafirov/opencode-gitlab-plugin/compare/v2.8.0...v2.8.1) (2026-09-06)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### 🐛 Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **merge-requests:** auto-detect merge train strategy in smart merge ([14fb879](https://gitlab.com/vglafirov/opencode-gitlab-plugin/commit/14fb879b167ed7ada03b02ef83b0944fbfc00480))
|
|
11
|
+
|
|
12
|
+
## [2.8.0](https://gitlab.com/vglafirov/opencode-gitlab-plugin/compare/v2.7.0...v2.8.0) (2026-09-06)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### ✨ Features
|
|
16
|
+
|
|
17
|
+
* **merge-requests:** support target_project_id for cross-project MRs ([e03a3b4](https://gitlab.com/vglafirov/opencode-gitlab-plugin/commit/e03a3b436e2ad7ef3540fee1ee380a6ef5b03b09))
|
|
18
|
+
|
|
5
19
|
## [2.7.0](https://gitlab.com/vglafirov/opencode-gitlab-plugin/compare/v2.6.1...v2.7.0) (2026-08-17)
|
|
6
20
|
|
|
7
21
|
|
package/README.md
CHANGED
|
@@ -343,13 +343,13 @@ Or for API tokens:
|
|
|
343
343
|
|
|
344
344
|
The plugin provides **64 tools** organized into the following categories:
|
|
345
345
|
|
|
346
|
-
### Merge Request Tools (
|
|
346
|
+
### Merge Request Tools (9 tools)
|
|
347
347
|
|
|
348
348
|
| Tool | Description |
|
|
349
349
|
| ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
350
350
|
| `gitlab_get_merge_request` | Get details of a specific merge request with title, description, state, author, assignees, reviewers, labels, and diff stats |
|
|
351
351
|
| `gitlab_list_merge_requests` | List merge requests with filtering by state, scope, and labels |
|
|
352
|
-
| `gitlab_create_merge_request` | Create a new merge request
|
|
352
|
+
| `gitlab_create_merge_request` | Create a new merge request (supports target_project_id for fork-to-upstream MRs) |
|
|
353
353
|
| `gitlab_update_merge_request` | Update merge request title, description, state, assignees, reviewers, and labels |
|
|
354
354
|
| `gitlab_get_mr_changes` | Get file changes/diffs for a merge request |
|
|
355
355
|
| `gitlab_get_mr_details` | Get additional MR details (commits or pipelines) with detail_type parameter |
|
package/dist/index.js
CHANGED
|
@@ -705,11 +705,48 @@ var MergeRequestsClient = class _MergeRequestsClient extends GitLabApiClient {
|
|
|
705
705
|
Object.keys(body).length > 0 ? body : void 0
|
|
706
706
|
);
|
|
707
707
|
}
|
|
708
|
+
/**
|
|
709
|
+
* Resolve the auto-merge strategy for a project.
|
|
710
|
+
*
|
|
711
|
+
* When the caller does not specify a strategy, projects with merge trains
|
|
712
|
+
* enabled require ADD_TO_MERGE_TRAIN_WHEN_CHECKS_PASS; otherwise
|
|
713
|
+
* MERGE_WHEN_CHECKS_PASS is correct. Using the wrong one causes auto-merge to
|
|
714
|
+
* fail with an opaque "The merge failed" error. Falls back to
|
|
715
|
+
* MERGE_WHEN_CHECKS_PASS if the project setting cannot be read.
|
|
716
|
+
*
|
|
717
|
+
* Returns both the chosen strategy and how it was arrived at, so the caller
|
|
718
|
+
* can thread a breadcrumb into its result. A bare fallback would collapse a
|
|
719
|
+
* 401, a network timeout, and a genuine 404 all into a silent MWPS default,
|
|
720
|
+
* reintroducing the opaque "The merge failed" this behaviour exists to
|
|
721
|
+
* eliminate; `detection` makes that observable without changing the fallback.
|
|
722
|
+
*/
|
|
723
|
+
async resolveAutoMergeStrategy(projectId) {
|
|
724
|
+
try {
|
|
725
|
+
const encodedProject = this.encodeProjectId(projectId);
|
|
726
|
+
const project = await this.fetch(
|
|
727
|
+
"GET",
|
|
728
|
+
`/projects/${encodedProject}`
|
|
729
|
+
);
|
|
730
|
+
return project.merge_trains_enabled ? {
|
|
731
|
+
strategy: "ADD_TO_MERGE_TRAIN_WHEN_CHECKS_PASS",
|
|
732
|
+
detection: "merge_trains_enabled"
|
|
733
|
+
} : { strategy: "MERGE_WHEN_CHECKS_PASS", detection: "merge_trains_disabled" };
|
|
734
|
+
} catch (error) {
|
|
735
|
+
return {
|
|
736
|
+
strategy: "MERGE_WHEN_CHECKS_PASS",
|
|
737
|
+
detection: "defaulted_after_error",
|
|
738
|
+
reason: error instanceof Error ? error.message : String(error)
|
|
739
|
+
};
|
|
740
|
+
}
|
|
741
|
+
}
|
|
708
742
|
/**
|
|
709
743
|
* Smart merge: merge immediately if checks pass, otherwise set auto-merge
|
|
710
|
-
* Returns detailed context about what happened
|
|
744
|
+
* Returns detailed context about what happened.
|
|
745
|
+
*
|
|
746
|
+
* If `strategy` is omitted, it is auto-detected from the project's merge
|
|
747
|
+
* train settings (merge-train projects need ADD_TO_MERGE_TRAIN_WHEN_CHECKS_PASS).
|
|
711
748
|
*/
|
|
712
|
-
async smartMerge(projectId, mrIid, sha, strategy
|
|
749
|
+
async smartMerge(projectId, mrIid, sha, strategy) {
|
|
713
750
|
let mr = await this.getMergeRequest(projectId, mrIid);
|
|
714
751
|
if (mr.detailed_merge_status === "checking") {
|
|
715
752
|
for (let attempt = 0; attempt < 5 && mr.detailed_merge_status === "checking"; attempt++) {
|
|
@@ -757,15 +794,24 @@ var MergeRequestsClient = class _MergeRequestsClient extends GitLabApiClient {
|
|
|
757
794
|
}
|
|
758
795
|
const autoMergeStatuses = ["ci_still_running", "not_approved"];
|
|
759
796
|
if (autoMergeStatuses.includes(mr.detailed_merge_status)) {
|
|
797
|
+
let resolvedStrategy;
|
|
798
|
+
if (strategy) {
|
|
799
|
+
resolvedStrategy = strategy;
|
|
800
|
+
context.strategyDetection = `explicit: ${strategy}`;
|
|
801
|
+
} else {
|
|
802
|
+
const detected = await this.resolveAutoMergeStrategy(projectId);
|
|
803
|
+
resolvedStrategy = detected.strategy;
|
|
804
|
+
context.strategyDetection = detected.detection === "defaulted_after_error" ? `failed, defaulted to MERGE_WHEN_CHECKS_PASS${detected.reason ? ` (${detected.reason})` : ""}` : `auto-detected (${detected.detection}): ${detected.strategy}`;
|
|
805
|
+
}
|
|
760
806
|
try {
|
|
761
|
-
const result = await this.setAutoMerge(projectId, mrIid, sha,
|
|
807
|
+
const result = await this.setAutoMerge(projectId, mrIid, sha, resolvedStrategy);
|
|
762
808
|
const autoMergeMessages = {
|
|
763
809
|
ci_still_running: "pipeline passes",
|
|
764
810
|
not_approved: "approved"
|
|
765
811
|
};
|
|
766
812
|
return {
|
|
767
813
|
action: "auto_merge_enabled",
|
|
768
|
-
message: `Auto-merge enabled (${
|
|
814
|
+
message: `Auto-merge enabled (${resolvedStrategy}). MR will merge when ${autoMergeMessages[mr.detailed_merge_status]}.`,
|
|
769
815
|
mergeRequest: result,
|
|
770
816
|
context
|
|
771
817
|
};
|
|
@@ -2830,7 +2876,10 @@ Returns the created merge request with all details.`,
|
|
|
2830
2876
|
milestone_id: z.number().optional().describe("The ID of a milestone"),
|
|
2831
2877
|
remove_source_branch: z.boolean().optional().describe("Remove source branch after merge (default: false)"),
|
|
2832
2878
|
squash: z.boolean().optional().describe("Squash commits on merge (default: false)"),
|
|
2833
|
-
allow_collaboration: z.boolean().optional().describe("Allow commits from members who can merge to the target branch")
|
|
2879
|
+
allow_collaboration: z.boolean().optional().describe("Allow commits from members who can merge to the target branch"),
|
|
2880
|
+
target_project_id: z.number().optional().describe(
|
|
2881
|
+
"The ID of the target project for cross-project (fork to upstream) merge requests. Defaults to the source project when omitted."
|
|
2882
|
+
)
|
|
2834
2883
|
},
|
|
2835
2884
|
execute: async (args, _ctx) => {
|
|
2836
2885
|
const client = getGitLabClient();
|
|
@@ -2845,7 +2894,8 @@ Returns the created merge request with all details.`,
|
|
|
2845
2894
|
milestone_id: args.milestone_id,
|
|
2846
2895
|
remove_source_branch: args.remove_source_branch,
|
|
2847
2896
|
squash: args.squash,
|
|
2848
|
-
allow_collaboration: args.allow_collaboration
|
|
2897
|
+
allow_collaboration: args.allow_collaboration,
|
|
2898
|
+
target_project_id: args.target_project_id
|
|
2849
2899
|
});
|
|
2850
2900
|
return JSON.stringify(mr, null, 2);
|
|
2851
2901
|
}
|
|
@@ -3005,17 +3055,12 @@ Note: You must provide the current HEAD SHA of the MR to prevent race conditions
|
|
|
3005
3055
|
"The HEAD SHA of the merge request. Get this from the MR details (diff_refs.head_sha or sha field)."
|
|
3006
3056
|
),
|
|
3007
3057
|
strategy: z.enum(["MERGE_WHEN_CHECKS_PASS", "ADD_TO_MERGE_TRAIN_WHEN_CHECKS_PASS"]).optional().describe(
|
|
3008
|
-
"Auto-merge strategy when immediate merge is not possible.
|
|
3058
|
+
"Auto-merge strategy when immediate merge is not possible. If omitted, it is auto-detected from the project: merge-train projects use ADD_TO_MERGE_TRAIN_WHEN_CHECKS_PASS, otherwise MERGE_WHEN_CHECKS_PASS."
|
|
3009
3059
|
)
|
|
3010
3060
|
},
|
|
3011
3061
|
execute: async (args, _ctx) => {
|
|
3012
3062
|
const client = getGitLabClient();
|
|
3013
|
-
const result = await client.smartMerge(
|
|
3014
|
-
args.project_id,
|
|
3015
|
-
args.mr_iid,
|
|
3016
|
-
args.sha,
|
|
3017
|
-
args.strategy || "MERGE_WHEN_CHECKS_PASS"
|
|
3018
|
-
);
|
|
3063
|
+
const result = await client.smartMerge(args.project_id, args.mr_iid, args.sha, args.strategy);
|
|
3019
3064
|
return JSON.stringify(result, null, 2);
|
|
3020
3065
|
}
|
|
3021
3066
|
}),
|