@zereight/mcp-gitlab 2.3.2 → 2.3.3
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 +70 -2
- package/package.json +1 -1
package/README.ko.md
CHANGED
|
@@ -138,7 +138,7 @@ command = lib.getExe inputs.gitlab-mcp.packages.${system}.default;
|
|
|
138
138
|
|
|
139
139
|
예시는 기존 `mcp-gitlab`보다 충돌 가능성이 낮은 `zereight-mcp-gitlab` 별칭을 사용합니다. MCP 클라이언트가 찾지 못하면 `which zereight-mcp-gitlab`의 절대 경로를 사용하세요.
|
|
140
140
|
|
|
141
|
-
전역 설치를 쓰지 않으려면 `npx -y @zereight/mcp-gitlab@2.3.
|
|
141
|
+
전역 설치를 쓰지 않으려면 `npx -y @zereight/mcp-gitlab@2.3.2`처럼 직전 안정 버전(문서가 권장하는 버전)으로 고정하세요. 항상 최신 버전을 원하면 `npx -y @zereight/mcp-gitlab@latest`를 사용하세요. 새 버전이 나오면 서버가 시작 시 stderr로 알려줍니다(`GITLAB_DISABLE_VERSION_CHECK=true`로 비활성화 가능).
|
|
142
142
|
|
|
143
143
|
#### Claude Desktop 원클릭 설치(MCP Bundle)
|
|
144
144
|
|
package/README.md
CHANGED
|
@@ -143,7 +143,7 @@ The store path is pinned by your lock file; update it with `nix flake update git
|
|
|
143
143
|
|
|
144
144
|
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`.
|
|
145
145
|
|
|
146
|
-
No global install? Pin `npx` to the previous stable release (the version these docs recommend), for example `npx -y @zereight/mcp-gitlab@2.3.
|
|
146
|
+
No global install? Pin `npx` to the previous stable release (the version these docs recommend), for example `npx -y @zereight/mcp-gitlab@2.3.2`. If you always want the newest release, use `npx -y @zereight/mcp-gitlab@latest` instead. The server prints a notice to stderr on startup when a newer version is available (disable with `GITLAB_DISABLE_VERSION_CHECK=true`).
|
|
147
147
|
|
|
148
148
|
#### Claude Desktop one-click install (MCP Bundle)
|
|
149
149
|
|
package/README.pt-BR.md
CHANGED
|
@@ -138,7 +138,7 @@ O caminho no store é fixado pelo seu lock file; atualize-o com `nix flake updat
|
|
|
138
138
|
|
|
139
139
|
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`.
|
|
140
140
|
|
|
141
|
-
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.
|
|
141
|
+
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.2`. Se quiser sempre a versão mais recente, use `npx -y @zereight/mcp-gitlab@latest`. 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`).
|
|
142
142
|
|
|
143
143
|
#### Instalação com um clique no Claude Desktop (MCP Bundle)
|
|
144
144
|
|
package/README.zh-CN.md
CHANGED
|
@@ -138,7 +138,7 @@ command = lib.getExe inputs.gitlab-mcp.packages.${system}.default;
|
|
|
138
138
|
|
|
139
139
|
示例使用 `zereight-mcp-gitlab`,这是比旧的 `mcp-gitlab` 更不容易冲突的别名。如果 MCP 客户端找不到它,请使用 `which zereight-mcp-gitlab` 输出的绝对路径。
|
|
140
140
|
|
|
141
|
-
如果不想全局安装,请将 `npx` 固定到上一个稳定版本(即文档推荐的版本),例如 `npx -y @zereight/mcp-gitlab@2.3.
|
|
141
|
+
如果不想全局安装,请将 `npx` 固定到上一个稳定版本(即文档推荐的版本),例如 `npx -y @zereight/mcp-gitlab@2.3.2`。如果始终想使用最新版本,请改用 `npx -y @zereight/mcp-gitlab@latest`。有新版本发布时,服务器会在启动时通过 stderr 提示(可用 `GITLAB_DISABLE_VERSION_CHECK=true` 关闭)。
|
|
142
142
|
|
|
143
143
|
#### Claude Desktop 一键安装(MCP Bundle)
|
|
144
144
|
|
package/build/index.js
CHANGED
|
@@ -6363,6 +6363,74 @@ async function erasePipelineJob(projectId, jobId) {
|
|
|
6363
6363
|
const TERMINAL_PIPELINE_STATUSES = new Set(["success", "failed", "canceled", "skipped", "manual"]);
|
|
6364
6364
|
const TERMINAL_JOB_STATUSES = new Set(["success", "failed", "canceled", "skipped", "manual"]);
|
|
6365
6365
|
const TERMINAL_REBASE_STATUSES = new Set(["finished"]);
|
|
6366
|
+
// GitLab accepts PUT .../rebase before Sidekiq starts the job. Until then, GET
|
|
6367
|
+
// with include_rebase_in_progress can still say rebase_in_progress=false and return
|
|
6368
|
+
// the pre-rebase sha (gitlab-org/gitlab-foss#57481). Recheck that snapshot a few
|
|
6369
|
+
// times, capped so the default 5s poll interval cannot stretch this into 15s.
|
|
6370
|
+
const REBASE_UNCHANGED_HEAD_RECHECK_LIMIT = 3;
|
|
6371
|
+
const REBASE_UNCHANGED_HEAD_RECHECK_INTERVAL_CAP_MS = 1000;
|
|
6372
|
+
function rebaseHeadMoved(previous, current) {
|
|
6373
|
+
return current.sha !== previous.sha;
|
|
6374
|
+
}
|
|
6375
|
+
function rebaseFailureExplained(previous, current) {
|
|
6376
|
+
const mergeError = current.merge_error;
|
|
6377
|
+
if (typeof mergeError !== "string" || mergeError.length === 0) {
|
|
6378
|
+
return false;
|
|
6379
|
+
}
|
|
6380
|
+
return mergeError !== previous.merge_error;
|
|
6381
|
+
}
|
|
6382
|
+
function delayForRebasePoll(delayMs) {
|
|
6383
|
+
return new Promise(resolve => {
|
|
6384
|
+
setTimeout(resolve, delayMs);
|
|
6385
|
+
});
|
|
6386
|
+
}
|
|
6387
|
+
async function getMergeRequestRebaseStatusBeforeDeadline(projectId, mergeRequestIid, deadline) {
|
|
6388
|
+
const remaining = deadline - Date.now();
|
|
6389
|
+
if (remaining <= 0) {
|
|
6390
|
+
throw new Error("Timed out waiting for terminal status");
|
|
6391
|
+
}
|
|
6392
|
+
return getMergeRequestRebaseStatus(projectId, mergeRequestIid, AbortSignal.timeout(remaining));
|
|
6393
|
+
}
|
|
6394
|
+
/**
|
|
6395
|
+
* Poll until a rebase finishes, without trusting a finished snapshot that still
|
|
6396
|
+
* has the pre-rebase sha and no new merge_error. A later rebase_in_progress true
|
|
6397
|
+
* means the job did start, so wait for that terminal status as usual. Rechecks
|
|
6398
|
+
* share the caller's timeout and never add time beyond it.
|
|
6399
|
+
*/
|
|
6400
|
+
async function waitForMergeRequestRebase(projectId, mergeRequestIid, previous, timeoutSeconds = 300, pollIntervalSeconds = 5) {
|
|
6401
|
+
const deadline = Date.now() + timeoutSeconds * 1000;
|
|
6402
|
+
let snapshot = await getMergeRequestRebaseStatusBeforeDeadline(projectId, mergeRequestIid, deadline);
|
|
6403
|
+
let rechecksRemaining = REBASE_UNCHANGED_HEAD_RECHECK_LIMIT;
|
|
6404
|
+
while (true) {
|
|
6405
|
+
if (!TERMINAL_REBASE_STATUSES.has(snapshot.status)) {
|
|
6406
|
+
rechecksRemaining = 0;
|
|
6407
|
+
const remaining = deadline - Date.now();
|
|
6408
|
+
if (remaining <= 0) {
|
|
6409
|
+
break;
|
|
6410
|
+
}
|
|
6411
|
+
await delayForRebasePoll(Math.min(pollIntervalSeconds * 1000, remaining));
|
|
6412
|
+
snapshot = await getMergeRequestRebaseStatusBeforeDeadline(projectId, mergeRequestIid, deadline);
|
|
6413
|
+
continue;
|
|
6414
|
+
}
|
|
6415
|
+
const mergeRequest = snapshot.mergeRequest;
|
|
6416
|
+
if (rebaseHeadMoved(previous, mergeRequest) || rebaseFailureExplained(previous, mergeRequest)) {
|
|
6417
|
+
return mergeRequest;
|
|
6418
|
+
}
|
|
6419
|
+
if (rechecksRemaining <= 0) {
|
|
6420
|
+
return mergeRequest;
|
|
6421
|
+
}
|
|
6422
|
+
const remaining = deadline - Date.now();
|
|
6423
|
+
const delay = Math.min(pollIntervalSeconds * 1000, REBASE_UNCHANGED_HEAD_RECHECK_INTERVAL_CAP_MS, remaining);
|
|
6424
|
+
// The next poll has to land inside the timeout. If one full backoff does not fit, stop.
|
|
6425
|
+
if (remaining <= 0 || delay >= remaining) {
|
|
6426
|
+
return mergeRequest;
|
|
6427
|
+
}
|
|
6428
|
+
rechecksRemaining -= 1;
|
|
6429
|
+
await delayForRebasePoll(delay);
|
|
6430
|
+
snapshot = await getMergeRequestRebaseStatusBeforeDeadline(projectId, mergeRequestIid, deadline);
|
|
6431
|
+
}
|
|
6432
|
+
throw new Error(`Timed out waiting for terminal status; last status: ${snapshot.status}`);
|
|
6433
|
+
}
|
|
6366
6434
|
async function waitForStatus(fetchStatus, terminalStatuses, timeoutSeconds = 300, pollIntervalSeconds = 5) {
|
|
6367
6435
|
const deadline = Date.now() + timeoutSeconds * 1000;
|
|
6368
6436
|
const fetchBeforeDeadline = async () => {
|
|
@@ -8771,11 +8839,11 @@ async function handleToolCall(params) {
|
|
|
8771
8839
|
}
|
|
8772
8840
|
const { mergeRequest: previous } = await getMergeRequestRebaseStatus(project_id, merge_request_iid);
|
|
8773
8841
|
await rebaseMergeRequest(project_id, merge_request_iid, skip_ci);
|
|
8774
|
-
const
|
|
8842
|
+
const mergeRequest = await waitForMergeRequestRebase(project_id, merge_request_iid, previous, timeout_seconds, poll_interval_seconds);
|
|
8775
8843
|
const rebaseResult = {
|
|
8776
8844
|
...mergeRequest,
|
|
8777
8845
|
previous_sha: previous.sha,
|
|
8778
|
-
head_changed:
|
|
8846
|
+
head_changed: rebaseHeadMoved(previous, mergeRequest),
|
|
8779
8847
|
};
|
|
8780
8848
|
return { content: [{ type: "text", text: JSON.stringify(rebaseResult) }] };
|
|
8781
8849
|
}
|
package/package.json
CHANGED