@zereight/mcp-gitlab 2.3.7-next.139 → 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/README.ko.md +1 -1
- package/README.md +1 -1
- package/README.pt-BR.md +1 -1
- package/README.zh-CN.md +1 -1
- package/build/index.js +2 -91
- package/build/utils/merge-request-summary.js +94 -0
- package/package.json +1 -1
package/README.ko.md
CHANGED
|
@@ -140,7 +140,7 @@ command = lib.getExe inputs.gitlab-mcp.packages.${system}.default;
|
|
|
140
140
|
|
|
141
141
|
예시는 기존 `mcp-gitlab`보다 충돌 가능성이 낮은 `zereight-mcp-gitlab` 별칭을 사용합니다. MCP 클라이언트가 찾지 못하면 `which zereight-mcp-gitlab`의 절대 경로를 사용하세요.
|
|
142
142
|
|
|
143
|
-
전역 설치를 쓰지 않으려면 `npx -y @zereight/mcp-gitlab@2.3.
|
|
143
|
+
전역 설치를 쓰지 않으려면 `npx -y @zereight/mcp-gitlab@2.3.6`처럼 직전 안정 버전(문서가 권장하는 버전)으로 고정하세요. 항상 최신 버전을 원하면 `npx -y @zereight/mcp-gitlab@latest`를 사용하세요. `main`에 머지된 수정을 다음 안정 버전 전에 확인하려면 프리릴리스 빌드인 `npx -y @zereight/mcp-gitlab@next`를 사용하세요(운영 환경용이 아닙니다). 새 버전이 나오면 서버가 시작 시 stderr로 알려줍니다(`GITLAB_DISABLE_VERSION_CHECK=true`로 비활성화 가능).
|
|
144
144
|
|
|
145
145
|
#### Claude Desktop 원클릭 설치(MCP Bundle)
|
|
146
146
|
|
package/README.md
CHANGED
|
@@ -145,7 +145,7 @@ The store path is pinned by your lock file; update it with `nix flake update git
|
|
|
145
145
|
|
|
146
146
|
The examples use `zereight-mcp-gitlab`, a less collision-prone alias for the legacy `mcp-gitlab` binary. If your MCP client cannot find it, use the absolute path from `which zereight-mcp-gitlab`.
|
|
147
147
|
|
|
148
|
-
No global install? Pin `npx` to the previous stable release (the version these docs recommend), for example `npx -y @zereight/mcp-gitlab@2.3.
|
|
148
|
+
No global install? Pin `npx` to the previous stable release (the version these docs recommend), for example `npx -y @zereight/mcp-gitlab@2.3.6`. If you always want the newest release, use `npx -y @zereight/mcp-gitlab@latest` instead. To try a fix merged to `main` before the next stable release, use `npx -y @zereight/mcp-gitlab@next`, a pre-release build that is not meant for production. The server prints a notice to stderr on startup when a newer version is available (disable with `GITLAB_DISABLE_VERSION_CHECK=true`).
|
|
149
149
|
|
|
150
150
|
#### Claude Desktop one-click install (MCP Bundle)
|
|
151
151
|
|
package/README.pt-BR.md
CHANGED
|
@@ -140,7 +140,7 @@ O caminho no store é fixado pelo seu lock file; atualize-o com `nix flake updat
|
|
|
140
140
|
|
|
141
141
|
Os exemplos usam `zereight-mcp-gitlab`, um alias com menor chance de conflito que o binário legado `mcp-gitlab`. Se o seu cliente MCP não o encontrar, use o caminho absoluto retornado por `which zereight-mcp-gitlab`.
|
|
142
142
|
|
|
143
|
-
Não quer instalar globalmente? Fixe o `npx` na versão estável anterior (a versão recomendada por esta documentação), por exemplo `npx -y @zereight/mcp-gitlab@2.3.
|
|
143
|
+
Não quer instalar globalmente? Fixe o `npx` na versão estável anterior (a versão recomendada por esta documentação), por exemplo `npx -y @zereight/mcp-gitlab@2.3.6`. Se quiser sempre a versão mais recente, use `npx -y @zereight/mcp-gitlab@latest`. Para testar uma correção já mesclada na `main` antes da próxima versão estável, use `npx -y @zereight/mcp-gitlab@next`, um build de pré-lançamento que não é indicado para produção. O servidor exibe um aviso no stderr durante a inicialização quando existe uma versão mais nova disponível (desative com `GITLAB_DISABLE_VERSION_CHECK=true`).
|
|
144
144
|
|
|
145
145
|
#### Instalação com um clique no Claude Desktop (MCP Bundle)
|
|
146
146
|
|
package/README.zh-CN.md
CHANGED
|
@@ -140,7 +140,7 @@ command = lib.getExe inputs.gitlab-mcp.packages.${system}.default;
|
|
|
140
140
|
|
|
141
141
|
示例使用 `zereight-mcp-gitlab`,这是比旧的 `mcp-gitlab` 更不容易冲突的别名。如果 MCP 客户端找不到它,请使用 `which zereight-mcp-gitlab` 输出的绝对路径。
|
|
142
142
|
|
|
143
|
-
如果不想全局安装,请将 `npx` 固定到上一个稳定版本(即文档推荐的版本),例如 `npx -y @zereight/mcp-gitlab@2.3.
|
|
143
|
+
如果不想全局安装,请将 `npx` 固定到上一个稳定版本(即文档推荐的版本),例如 `npx -y @zereight/mcp-gitlab@2.3.6`。如果始终想使用最新版本,请改用 `npx -y @zereight/mcp-gitlab@latest`。如需在下一个稳定版本发布前试用已合并到 `main` 的修复,请使用 `npx -y @zereight/mcp-gitlab@next`(预发布版本,不适用于生产环境)。有新版本发布时,服务器会在启动时通过 stderr 提示(可用 `GITLAB_DISABLE_VERSION_CHECK=true` 关闭)。
|
|
144
144
|
|
|
145
145
|
#### Claude Desktop 一键安装(MCP Bundle)
|
|
146
146
|
|
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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zereight/mcp-gitlab",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.8-next.142",
|
|
4
4
|
"mcpName": "io.github.zereight/gitlab-mcp",
|
|
5
5
|
"description": "GitLab MCP server for projects, merge requests, issues, pipelines, wiki, releases, and more",
|
|
6
6
|
"keywords": [
|