@zereight/mcp-gitlab 2.3.7 β 2.3.8-next.142
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/build/index.js +2 -91
- package/build/utils/merge-request-summary.js +94 -0
- package/package.json +1 -1
package/build/index.js
CHANGED
|
@@ -107,6 +107,7 @@ import { checkForNewVersion } from "./utils/version-check.js";
|
|
|
107
107
|
import { assertGitLabVersionAtLeast } from "./utils/gitlab-version-gate.js";
|
|
108
108
|
import { fetchWithValidatedRedirects } from "./utils/safe-redirect-fetch.js";
|
|
109
109
|
import { fetchStatusBeforeDeadline } from "./utils/poll-deadline.js";
|
|
110
|
+
import { getUniqueApprovalUsers, inferMergeRequestApproved, MERGE_REQUEST_DEPLOYMENT_SUMMARY_LIMIT, parseApprovalsResponse, sortDeploymentsByCreatedAtDesc, toMergeRequestDeploymentSummaryRecord, } from "./utils/merge-request-summary.js";
|
|
110
111
|
import { parseGitLabVersionApiResponse, } from "./utils/gitlab-instance-version.js";
|
|
111
112
|
import { buildBulkPublishDraftNotesBody, needsGitLab19_2BulkPublish, } from "./utils/bulk-publish-options.js";
|
|
112
113
|
import { appendFilterParam, appendFilterParams, cleanMutuallyExclusiveIdUsernameOptions, dropBlankArrayEntries, isBlankFilterValue, LIST_MERGE_REQUESTS_ID_USERNAME_PAIRS, sanitizeToolArguments, } from "./utils/tool-args.js";
|
|
@@ -128,7 +129,7 @@ GitLabDiscussionNoteSchema, // Added
|
|
|
128
129
|
GitLabDiscussionSchema,
|
|
129
130
|
// Draft Notes Schemas
|
|
130
131
|
GitLabDraftNoteSchema, GitLabForkSchema, GitLabBranchSchema, GitLabProtectedBranchSchema, GitLabProtectedTagSchema, GitLabGroupSchema, GitLabIssueLinkSchema, GitLabIssueSchema, GitLabIssueWithLinkDetailsSchema, GitLabMarkdownUploadSchema, GitLabMergeRequestPipelineSchema, GitLabMergeRequestSchema, GitLabMilestonesSchema, GitLabGroupMilestonesSchema, GitLabNamespaceExistsResponseSchema, GitLabNamespaceSchema, GitLabPipelineJobSchema, GitLabDeploymentSchema, GitLabEnvironmentSchema, GitLabPipelineSchema, GitLabPipelineScheduleSchema, GitLabPipelineScheduleVariableSchema, GitLabPipelineSchedulePlayResultSchema, ListPipelineSchedulesSchema, GetPipelineScheduleSchema, ListPipelineSchedulePipelinesSchema, CreatePipelineScheduleSchema, UpdatePipelineScheduleSchema, DeletePipelineScheduleSchema, PlayPipelineScheduleSchema, TakeOwnershipPipelineScheduleSchema, GetPipelineScheduleVariableSchema, CreatePipelineScheduleVariableSchema, UpdatePipelineScheduleVariableSchema, DeletePipelineScheduleVariableSchema, GitLabPipelineTriggerJobSchema, GitLabProjectMemberSchema, GitLabProjectSchema, GitLabTodoSchema, GitLabReferenceSchema, GitLabRepositorySchema, GitLabSearchBlobResultSchema, GitLabSearchResponseSchema, GitLabTreeItemSchema, GitLabUserSchema, GitLabUsersResponseSchema, GitLabWikiPageSchema, GroupIteration, ListCommitStatusesSchema, ListBranchesSchema, ListCommitsSchema, ListDraftNotesSchema, ListGroupIterationsSchema, ListGroupProjectsSchema, GitLabCiVariableSchema, ListProjectVariablesSchema, GetProjectVariableSchema, CreateProjectVariableSchema, UpdateProjectVariableSchema, DeleteProjectVariableSchema, ListGroupVariablesSchema, GetGroupVariableSchema, CreateGroupVariableSchema, UpdateGroupVariableSchema, DeleteGroupVariableSchema, GitLabDependencyProxySchema, GitLabDependencyProxyBlobSchema, GetDependencyProxySettingsSchema, UpdateDependencyProxySettingsSchema, ListDependencyProxyBlobsSchema, PurgeDependencyProxyCacheSchema, ListProjectVulnerabilitiesSchema, GetVulnerabilitySchema, DismissVulnerabilitySchema, ConfirmVulnerabilitySchema, ListIssueDiscussionsSchema, ListIssueLinksSchema, ListIssuesSchema, ListTodosSchema, ListLabelsSchema, ListMergeRequestDiffsSchema, // Added
|
|
131
|
-
GetMergeRequestFileDiffSchema, ListMergeRequestChangedFilesSchema, ListMergeRequestDiscussionsSchema, ListMergeRequestPipelinesSchema, ListMergeRequestsSchema, ListGroupMergeRequestsSchema, ListMergeRequestVersionsSchema, GetMergeRequestVersionSchema, GitLabMergeRequestVersionSchema, GitLabMergeRequestVersionDetailSchema, ListNamespacesSchema, ListPipelineJobsSchema, ListPipelinesSchema, ListDeploymentsSchema, ListEnvironmentsSchema, ListProjectRunnersSchema, GetRunnerSchema, ListPipelineTriggerJobsSchema, ValidateCiLintSchema, ValidateProjectCiLintSchema, ListCiCatalogResourcesSchema, GetCiCatalogResourceSchema, ListProjectMembersSchema, ListGroupMembersSchema, ListProjectMilestonesSchema, ListGroupMilestonesSchema, ListProjectsSchema, ListWikiPagesSchema, GetGroupWikiPageSchema, ListGroupWikiPagesSchema, UpdateGroupWikiPageSchema, MarkdownUploadSchema, MarkdownUploadRemoteSchema, DownloadAttachmentSchema, DownloadJobArtifactsSchema, GetJobArtifactFileSchema, GitLabArtifactEntrySchema, ListJobArtifactsSchema, MergeMergeRequestSchema, ApproveMergeRequestSchema, UnapproveMergeRequestSchema, RebaseMergeRequestSchema, GetMergeRequestApprovalStateSchema, GetMergeRequestConflictsSchema,
|
|
132
|
+
GetMergeRequestFileDiffSchema, ListMergeRequestChangedFilesSchema, ListMergeRequestDiscussionsSchema, ListMergeRequestPipelinesSchema, ListMergeRequestsSchema, ListGroupMergeRequestsSchema, ListMergeRequestVersionsSchema, GetMergeRequestVersionSchema, GitLabMergeRequestVersionSchema, GitLabMergeRequestVersionDetailSchema, ListNamespacesSchema, ListPipelineJobsSchema, ListPipelinesSchema, ListDeploymentsSchema, ListEnvironmentsSchema, ListProjectRunnersSchema, GetRunnerSchema, ListPipelineTriggerJobsSchema, ValidateCiLintSchema, ValidateProjectCiLintSchema, ListCiCatalogResourcesSchema, GetCiCatalogResourceSchema, ListProjectMembersSchema, ListGroupMembersSchema, ListProjectMilestonesSchema, ListGroupMilestonesSchema, ListProjectsSchema, ListWikiPagesSchema, GetGroupWikiPageSchema, ListGroupWikiPagesSchema, UpdateGroupWikiPageSchema, MarkdownUploadSchema, MarkdownUploadRemoteSchema, DownloadAttachmentSchema, DownloadJobArtifactsSchema, GetJobArtifactFileSchema, GitLabArtifactEntrySchema, ListJobArtifactsSchema, MergeMergeRequestSchema, ApproveMergeRequestSchema, UnapproveMergeRequestSchema, RebaseMergeRequestSchema, GetMergeRequestApprovalStateSchema, GetMergeRequestConflictsSchema, GitLabMergeRequestApprovalStateSchema, MyIssuesSchema, OrbitQuerySchema, OrbitSchemaSchema, OrbitStatusSchema, OrbitToolsSchema, MarkAllTodosDoneSchema, MarkTodoDoneSchema, PaginatedDiscussionsResponseSchema, PromoteProjectMilestoneSchema, PublishDraftNoteSchema, PlayPipelineJobSchema, PushFilesSchema, RetryPipelineJobSchema, RetryPipelineSchema, SearchCodeSchema, SearchGroupCodeSchema, SearchProjectCodeSchema, SearchRepositoriesSchema, UpdateDraftNoteSchema, UpdateIssueNoteSchema, UpdateIssueSchema, UpdateIssueDescriptionPatchSchema, UpdateLabelSchema, UpdateProjectSchema, UpdateMergeRequestNoteSchema, UpdateMergeRequestDiscussionNoteSchema, UpdateMergeRequestSchema, UpdateWikiPageSchema, VerifyNamespaceSchema, GitLabEventSchema, ListEventsSchema, GetProjectEventsSchema, ExecuteGraphQLSchema, GitLabReleaseSchema, ListReleasesSchema, GetReleaseSchema, CreateReleaseSchema, UpdateReleaseSchema, DeleteReleaseSchema, CreateReleaseEvidenceSchema, DownloadReleaseAssetSchema, ListTagsSchema, GetTagSchema, CreateTagSchema, DeleteTagSchema, GetTagSignatureSchema, ListProtectedTagsSchema, GetProtectedTagSchema, ProtectTagSchema, UnprotectTagSchema, GitLabTagSchema, GitLabTagSignatureSchema, ListSnippetsSchema, GetSnippetSchema, CreateSnippetSchema, UpdateSnippetSchema, DeleteSnippetSchema, GitLabSnippetSchema, GetMergeRequestNotesSchema, GetMergeRequestNoteSchema, GetMergeRequestDiscussionSchema, DeleteMergeRequestDiscussionNoteSchema, ResolveMergeRequestThreadSchema, GetWorkItemSchema, ListWorkItemsSchema, CreateWorkItemSchema, UpdateWorkItemSchema, ConvertWorkItemTypeSchema, ListWorkItemStatusesSchema, ListWorkItemNotesSchema, CreateWorkItemNoteSchema, CreateWorkItemEmojiReactionSchema, CreateWorkItemNoteEmojiReactionSchema, ListWorkItemEmojiReactionsSchema, ListWorkItemNoteEmojiReactionsSchema, DeleteWorkItemEmojiReactionSchema, DeleteWorkItemNoteEmojiReactionSchema, MoveWorkItemSchema, ListCustomFieldDefinitionsSchema, GetTimelineEventsSchema, CreateTimelineEventSchema, ListWebhooksSchema, CreateWebhookSchema, UpdateWebhookSchema, DeleteWebhookSchema, ListWebhookEventsSchema, GetWebhookEventSchema, HealthCheckSchema, } from "./schemas.js";
|
|
132
133
|
import { createHash, randomUUID, timingSafeEqual } from "node:crypto";
|
|
133
134
|
import { createLogger, flushBufferedLogs, flushStartupLogs } from "./utils/logger.js";
|
|
134
135
|
const logger = createLogger();
|
|
@@ -1265,7 +1266,6 @@ const ignoredExplicitTools = [...individuallyEnabledTools].filter(name => isExpl
|
|
|
1265
1266
|
if (ignoredExplicitTools.length > 0) {
|
|
1266
1267
|
logger.warn(`GITLAB_TOOLS names ${ignoredExplicitTools.join(", ")}, but that tool is enabled only when its toolset is listed in GITLAB_TOOLSETS. The GITLAB_TOOLS entry is ignored.`);
|
|
1267
1268
|
}
|
|
1268
|
-
const MERGE_REQUEST_DEPLOYMENT_SUMMARY_LIMIT = 10;
|
|
1269
1269
|
function toAllowedGitLabApiUrl(value) {
|
|
1270
1270
|
const trimmed = value.trim();
|
|
1271
1271
|
if (!trimmed)
|
|
@@ -4072,58 +4072,6 @@ async function buildMergeRequestApprovalSummary(projectId, mergeRequestIid) {
|
|
|
4072
4072
|
};
|
|
4073
4073
|
}
|
|
4074
4074
|
}
|
|
4075
|
-
function toMergeRequestDeploymentSummaryRecord(deployment) {
|
|
4076
|
-
return {
|
|
4077
|
-
id: deployment.id,
|
|
4078
|
-
status: deployment.status,
|
|
4079
|
-
ref: deployment.ref,
|
|
4080
|
-
sha: deployment.sha,
|
|
4081
|
-
created_at: deployment.created_at,
|
|
4082
|
-
updated_at: deployment.updated_at,
|
|
4083
|
-
finished_at: deployment.finished_at,
|
|
4084
|
-
web_url: deployment.web_url,
|
|
4085
|
-
environment: deployment.environment
|
|
4086
|
-
? {
|
|
4087
|
-
id: deployment.environment.id,
|
|
4088
|
-
name: deployment.environment.name,
|
|
4089
|
-
slug: deployment.environment.slug,
|
|
4090
|
-
external_url: deployment.environment.external_url,
|
|
4091
|
-
state: deployment.environment.state,
|
|
4092
|
-
tier: deployment.environment.tier,
|
|
4093
|
-
}
|
|
4094
|
-
: undefined,
|
|
4095
|
-
deployable: deployment.deployable === null
|
|
4096
|
-
? null
|
|
4097
|
-
: deployment.deployable
|
|
4098
|
-
? {
|
|
4099
|
-
id: deployment.deployable.id,
|
|
4100
|
-
name: deployment.deployable.name,
|
|
4101
|
-
status: deployment.deployable.status,
|
|
4102
|
-
stage: deployment.deployable.stage,
|
|
4103
|
-
web_url: deployment.deployable.web_url,
|
|
4104
|
-
pipeline: deployment.deployable.pipeline
|
|
4105
|
-
? {
|
|
4106
|
-
id: deployment.deployable.pipeline.id,
|
|
4107
|
-
status: deployment.deployable.pipeline.status,
|
|
4108
|
-
ref: deployment.deployable.pipeline.ref,
|
|
4109
|
-
sha: deployment.deployable.pipeline.sha,
|
|
4110
|
-
web_url: deployment.deployable.pipeline.web_url,
|
|
4111
|
-
}
|
|
4112
|
-
: undefined,
|
|
4113
|
-
}
|
|
4114
|
-
: undefined,
|
|
4115
|
-
};
|
|
4116
|
-
}
|
|
4117
|
-
function sortDeploymentsByCreatedAtDesc(deployments) {
|
|
4118
|
-
return [...deployments].sort((a, b) => {
|
|
4119
|
-
const aTime = Date.parse(a.created_at);
|
|
4120
|
-
const bTime = Date.parse(b.created_at);
|
|
4121
|
-
if (Number.isNaN(aTime) || Number.isNaN(bTime)) {
|
|
4122
|
-
return b.created_at.localeCompare(a.created_at);
|
|
4123
|
-
}
|
|
4124
|
-
return bTime - aTime;
|
|
4125
|
-
});
|
|
4126
|
-
}
|
|
4127
4075
|
async function buildMergeRequestDeploymentSummary(projectId, mergeRequest) {
|
|
4128
4076
|
const lookupSha = mergeRequest.merge_commit_sha ?? mergeRequest.diff_refs?.head_sha ?? null;
|
|
4129
4077
|
if (!lookupSha) {
|
|
@@ -4566,43 +4514,6 @@ async function getMergeRequestApprovalsFallback(projectId, mergeRequestIid) {
|
|
|
4566
4514
|
await handleGitLabError(approvalsResponse);
|
|
4567
4515
|
return parseApprovalsResponse(await approvalsResponse.json());
|
|
4568
4516
|
}
|
|
4569
|
-
/**
|
|
4570
|
-
* Parse the response from POST /approve and POST /unapprove endpoints.
|
|
4571
|
-
* These endpoints return the approvals format (approved_by contains nested
|
|
4572
|
-
* { user: {...} } objects), which must be converted to the flat format
|
|
4573
|
-
* used by GitLabMergeRequestApprovalStateSchema.
|
|
4574
|
-
*/
|
|
4575
|
-
function parseApprovalsResponse(responseJson) {
|
|
4576
|
-
const parsedApprovals = GitLabMergeRequestApprovalsResponseSchema.parse(responseJson);
|
|
4577
|
-
const approvedByUsers = getUniqueApprovalUsers((parsedApprovals.approved_by || []).map(approvedByEntry => approvedByEntry.user));
|
|
4578
|
-
const approvedByUsernames = approvedByUsers.map(user => user.username);
|
|
4579
|
-
return GitLabMergeRequestApprovalStateSchema.parse({
|
|
4580
|
-
approved: parsedApprovals.approved,
|
|
4581
|
-
user_has_approved: parsedApprovals.user_has_approved,
|
|
4582
|
-
user_can_approve: parsedApprovals.user_can_approve,
|
|
4583
|
-
approved_by: approvedByUsers,
|
|
4584
|
-
approved_by_usernames: approvedByUsernames,
|
|
4585
|
-
source_endpoint: "approvals",
|
|
4586
|
-
});
|
|
4587
|
-
}
|
|
4588
|
-
function getUniqueApprovalUsers(users) {
|
|
4589
|
-
const uniqueUsers = new Map();
|
|
4590
|
-
for (const user of users) {
|
|
4591
|
-
if (!uniqueUsers.has(user.id)) {
|
|
4592
|
-
uniqueUsers.set(user.id, user);
|
|
4593
|
-
}
|
|
4594
|
-
}
|
|
4595
|
-
return [...uniqueUsers.values()];
|
|
4596
|
-
}
|
|
4597
|
-
function inferMergeRequestApproved(rules) {
|
|
4598
|
-
if (!rules || rules.length === 0) {
|
|
4599
|
-
return null;
|
|
4600
|
-
}
|
|
4601
|
-
if (rules.some(rule => typeof rule.approved !== "boolean")) {
|
|
4602
|
-
return null;
|
|
4603
|
-
}
|
|
4604
|
-
return rules.every(rule => rule.approved === true);
|
|
4605
|
-
}
|
|
4606
4517
|
/**
|
|
4607
4518
|
* Create a new note (comment) on an issue or merge request
|
|
4608
4519
|
* π¦ μλ‘μ΄ ν¨μ: createNote - μ΄μ λλ λ³ν© μμ²μ λ
ΈνΈ(λκΈ)λ₯Ό μΆκ°νλ ν¨μ
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// Pure helpers for the get_merge_request summaries (include_summaries) and the
|
|
2
|
+
// approve/unapprove/approval state results. The functions that call GitLab
|
|
3
|
+
// stay in index.ts.
|
|
4
|
+
import { GitLabMergeRequestApprovalsResponseSchema, GitLabMergeRequestApprovalStateSchema, } from "../schemas.js";
|
|
5
|
+
export const MERGE_REQUEST_DEPLOYMENT_SUMMARY_LIMIT = 10;
|
|
6
|
+
export function toMergeRequestDeploymentSummaryRecord(deployment) {
|
|
7
|
+
return {
|
|
8
|
+
id: deployment.id,
|
|
9
|
+
status: deployment.status,
|
|
10
|
+
ref: deployment.ref,
|
|
11
|
+
sha: deployment.sha,
|
|
12
|
+
created_at: deployment.created_at,
|
|
13
|
+
updated_at: deployment.updated_at,
|
|
14
|
+
finished_at: deployment.finished_at,
|
|
15
|
+
web_url: deployment.web_url,
|
|
16
|
+
environment: deployment.environment
|
|
17
|
+
? {
|
|
18
|
+
id: deployment.environment.id,
|
|
19
|
+
name: deployment.environment.name,
|
|
20
|
+
slug: deployment.environment.slug,
|
|
21
|
+
external_url: deployment.environment.external_url,
|
|
22
|
+
state: deployment.environment.state,
|
|
23
|
+
tier: deployment.environment.tier,
|
|
24
|
+
}
|
|
25
|
+
: undefined,
|
|
26
|
+
deployable: deployment.deployable === null
|
|
27
|
+
? null
|
|
28
|
+
: deployment.deployable
|
|
29
|
+
? {
|
|
30
|
+
id: deployment.deployable.id,
|
|
31
|
+
name: deployment.deployable.name,
|
|
32
|
+
status: deployment.deployable.status,
|
|
33
|
+
stage: deployment.deployable.stage,
|
|
34
|
+
web_url: deployment.deployable.web_url,
|
|
35
|
+
pipeline: deployment.deployable.pipeline
|
|
36
|
+
? {
|
|
37
|
+
id: deployment.deployable.pipeline.id,
|
|
38
|
+
status: deployment.deployable.pipeline.status,
|
|
39
|
+
ref: deployment.deployable.pipeline.ref,
|
|
40
|
+
sha: deployment.deployable.pipeline.sha,
|
|
41
|
+
web_url: deployment.deployable.pipeline.web_url,
|
|
42
|
+
}
|
|
43
|
+
: undefined,
|
|
44
|
+
}
|
|
45
|
+
: undefined,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export function sortDeploymentsByCreatedAtDesc(deployments) {
|
|
49
|
+
return [...deployments].sort((a, b) => {
|
|
50
|
+
const aTime = Date.parse(a.created_at);
|
|
51
|
+
const bTime = Date.parse(b.created_at);
|
|
52
|
+
if (Number.isNaN(aTime) || Number.isNaN(bTime)) {
|
|
53
|
+
return b.created_at.localeCompare(a.created_at);
|
|
54
|
+
}
|
|
55
|
+
return bTime - aTime;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Parse the response from POST /approve and POST /unapprove endpoints.
|
|
60
|
+
* These endpoints return the approvals format (approved_by contains nested
|
|
61
|
+
* { user: {...} } objects), which must be converted to the flat format
|
|
62
|
+
* used by GitLabMergeRequestApprovalStateSchema.
|
|
63
|
+
*/
|
|
64
|
+
export function parseApprovalsResponse(responseJson) {
|
|
65
|
+
const parsedApprovals = GitLabMergeRequestApprovalsResponseSchema.parse(responseJson);
|
|
66
|
+
const approvedByUsers = getUniqueApprovalUsers((parsedApprovals.approved_by || []).map(approvedByEntry => approvedByEntry.user));
|
|
67
|
+
const approvedByUsernames = approvedByUsers.map(user => user.username);
|
|
68
|
+
return GitLabMergeRequestApprovalStateSchema.parse({
|
|
69
|
+
approved: parsedApprovals.approved,
|
|
70
|
+
user_has_approved: parsedApprovals.user_has_approved,
|
|
71
|
+
user_can_approve: parsedApprovals.user_can_approve,
|
|
72
|
+
approved_by: approvedByUsers,
|
|
73
|
+
approved_by_usernames: approvedByUsernames,
|
|
74
|
+
source_endpoint: "approvals",
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
export function getUniqueApprovalUsers(users) {
|
|
78
|
+
const uniqueUsers = new Map();
|
|
79
|
+
for (const user of users) {
|
|
80
|
+
if (!uniqueUsers.has(user.id)) {
|
|
81
|
+
uniqueUsers.set(user.id, user);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return [...uniqueUsers.values()];
|
|
85
|
+
}
|
|
86
|
+
export function inferMergeRequestApproved(rules) {
|
|
87
|
+
if (!rules || rules.length === 0) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
if (rules.some(rule => typeof rule.approved !== "boolean")) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
return rules.every(rule => rule.approved === true);
|
|
94
|
+
}
|
package/package.json
CHANGED