Skip to content

Commit a5b8c7e

Browse files
authored
feat(gitlab): add release and branch-compare tools, remove dead types (#5475)
* feat(gitlab): add release and branch-compare tools, remove dead types - Add gitlab_delete_branch, gitlab_compare_branches, gitlab_list_releases, gitlab_create_release tools + block wiring (fills gaps found during a full validate-integration pass against live GitLab API docs) - Remove 12 unexported, zero-consumer types left over from never-implemented tool ideas (labels, users, current-user, branch/notes listing) - Add filePath/branch block outputs that get_file/create_file/update_file already returned but weren't exposed - Broaden state/orderBy param descriptions to list all documented GitLab values * fix(gitlab): expose all tool-returned fields as block outputs - Add total, size, ref, blobId, lastCommitId, mergeRequestIid, changesCount, approvedBy, protected, id, status to the block outputs map — these fields are already returned by their respective tools but weren't declared as outputs - Add missing 'title' value to list_issues orderBy description * fix(gitlab): drop empty entries when splitting release milestones Trailing/extra commas in the milestones input (e.g. "v1, ,v2") would produce an empty string entry, which the GitLab API rejects.
1 parent 0132a04 commit a5b8c7e

11 files changed

Lines changed: 724 additions & 105 deletions

File tree

apps/sim/blocks/blocks/gitlab.ts

Lines changed: 217 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,18 @@ export const GitLabBlock: BlockConfig<GitLabResponse> = {
5454
{ label: 'List Commits', id: 'gitlab_list_commits' },
5555
{ label: 'List Branches', id: 'gitlab_list_branches' },
5656
{ label: 'Create Branch', id: 'gitlab_create_branch' },
57+
{ label: 'Delete Branch', id: 'gitlab_delete_branch' },
58+
{ label: 'Compare Branches', id: 'gitlab_compare_branches' },
5759
// Additional Merge Request Operations
5860
{ label: 'Get MR Changes', id: 'gitlab_get_merge_request_changes' },
5961
{ label: 'Approve Merge Request', id: 'gitlab_approve_merge_request' },
6062
// Job Operations
6163
{ label: 'List Pipeline Jobs', id: 'gitlab_list_pipeline_jobs' },
6264
{ label: 'Get Job Log', id: 'gitlab_get_job_log' },
6365
{ label: 'Play Job', id: 'gitlab_play_job' },
66+
// Release Operations
67+
{ label: 'List Releases', id: 'gitlab_list_releases' },
68+
{ label: 'Create Release', id: 'gitlab_create_release' },
6469
],
6570
value: () => 'gitlab_list_projects',
6671
},
@@ -116,11 +121,15 @@ export const GitLabBlock: BlockConfig<GitLabResponse> = {
116121
'gitlab_list_commits',
117122
'gitlab_list_branches',
118123
'gitlab_create_branch',
124+
'gitlab_delete_branch',
125+
'gitlab_compare_branches',
119126
'gitlab_get_merge_request_changes',
120127
'gitlab_approve_merge_request',
121128
'gitlab_list_pipeline_jobs',
122129
'gitlab_get_job_log',
123130
'gitlab_play_job',
131+
'gitlab_list_releases',
132+
'gitlab_create_release',
124133
],
125134
},
126135
},
@@ -210,16 +219,18 @@ Return ONLY the title - no explanations, no extra text.`,
210219
'gitlab_update_issue',
211220
'gitlab_create_merge_request',
212221
'gitlab_update_merge_request',
222+
'gitlab_create_release',
213223
],
214224
},
215225
wandConfig: {
216226
enabled: true,
217-
prompt: `Generate a comprehensive description for a GitLab issue or merge request based on the user's request.
227+
prompt: `Generate a comprehensive description for a GitLab issue, merge request, or release based on the user's request.
218228
Include relevant sections as appropriate:
219229
- Summary of changes or problem
220230
- Context and motivation
221231
- Testing done (for MRs)
222232
- Steps to reproduce (for bugs)
233+
- Highlights and notable changes (for releases)
223234
224235
Use Markdown formatting for readability.
225236
@@ -278,11 +289,19 @@ Return ONLY the comment text - no explanations, no extra formatting.`,
278289
title: 'Branch/Tag',
279290
type: 'short-input',
280291
placeholder: 'Enter branch or tag name',
281-
required: true,
282-
condition: {
292+
required: {
283293
field: 'operation',
284294
value: ['gitlab_create_pipeline', 'gitlab_get_file', 'gitlab_create_branch'],
285295
},
296+
condition: {
297+
field: 'operation',
298+
value: [
299+
'gitlab_create_pipeline',
300+
'gitlab_get_file',
301+
'gitlab_create_branch',
302+
'gitlab_create_release',
303+
],
304+
},
286305
},
287306
// File Path
288307
{
@@ -305,7 +324,102 @@ Return ONLY the comment text - no explanations, no extra formatting.`,
305324
required: true,
306325
condition: {
307326
field: 'operation',
308-
value: ['gitlab_create_file', 'gitlab_update_file', 'gitlab_create_branch'],
327+
value: [
328+
'gitlab_create_file',
329+
'gitlab_update_file',
330+
'gitlab_create_branch',
331+
'gitlab_delete_branch',
332+
],
333+
},
334+
},
335+
// Compare from ref
336+
{
337+
id: 'compareFrom',
338+
title: 'From',
339+
type: 'short-input',
340+
placeholder: 'Branch, tag, or commit SHA to compare from',
341+
required: true,
342+
condition: {
343+
field: 'operation',
344+
value: ['gitlab_compare_branches'],
345+
},
346+
},
347+
// Compare to ref
348+
{
349+
id: 'compareTo',
350+
title: 'To',
351+
type: 'short-input',
352+
placeholder: 'Branch, tag, or commit SHA to compare to',
353+
required: true,
354+
condition: {
355+
field: 'operation',
356+
value: ['gitlab_compare_branches'],
357+
},
358+
},
359+
// Compare directly instead of using merge base
360+
{
361+
id: 'straight',
362+
title: 'Compare Directly',
363+
type: 'switch',
364+
mode: 'advanced',
365+
condition: {
366+
field: 'operation',
367+
value: ['gitlab_compare_branches'],
368+
},
369+
},
370+
// Release tag name
371+
{
372+
id: 'tagName',
373+
title: 'Tag Name',
374+
type: 'short-input',
375+
placeholder: 'Enter the Git tag for the release (e.g., v1.0.0)',
376+
required: true,
377+
condition: {
378+
field: 'operation',
379+
value: ['gitlab_create_release'],
380+
},
381+
},
382+
// Release name
383+
{
384+
id: 'releaseName',
385+
title: 'Release Name',
386+
type: 'short-input',
387+
placeholder: 'Enter release name (optional)',
388+
condition: {
389+
field: 'operation',
390+
value: ['gitlab_create_release'],
391+
},
392+
},
393+
// Release date
394+
{
395+
id: 'releasedAt',
396+
title: 'Released At',
397+
type: 'short-input',
398+
placeholder: 'ISO 8601 date for an upcoming or historical release (optional)',
399+
mode: 'advanced',
400+
condition: {
401+
field: 'operation',
402+
value: ['gitlab_create_release'],
403+
},
404+
wandConfig: {
405+
enabled: true,
406+
prompt: `Generate an ISO 8601 timestamp based on the user's description of when the release happened or will happen.
407+
408+
Return ONLY the timestamp string - no explanations, no extra text.`,
409+
generationType: 'timestamp',
410+
placeholder: 'Describe when the release happened...',
411+
},
412+
},
413+
// Release milestones
414+
{
415+
id: 'releaseMilestones',
416+
title: 'Milestones',
417+
type: 'short-input',
418+
placeholder: 'Milestone titles (comma-separated, optional)',
419+
mode: 'advanced',
420+
condition: {
421+
field: 'operation',
422+
value: ['gitlab_create_release'],
309423
},
310424
},
311425
// File Content
@@ -593,6 +707,7 @@ Return ONLY the commit message - no explanations, no extra text.`,
593707
'gitlab_list_branches',
594708
'gitlab_list_commits',
595709
'gitlab_list_pipeline_jobs',
710+
'gitlab_list_releases',
596711
],
597712
},
598713
},
@@ -614,6 +729,7 @@ Return ONLY the commit message - no explanations, no extra text.`,
614729
'gitlab_list_branches',
615730
'gitlab_list_commits',
616731
'gitlab_list_pipeline_jobs',
732+
'gitlab_list_releases',
617733
],
618734
},
619735
},
@@ -650,13 +766,17 @@ Return ONLY the commit message - no explanations, no extra text.`,
650766
'gitlab_create_file',
651767
'gitlab_update_file',
652768
'gitlab_create_branch',
769+
'gitlab_delete_branch',
770+
'gitlab_compare_branches',
653771
'gitlab_list_branches',
654772
'gitlab_list_commits',
655773
'gitlab_get_merge_request_changes',
656774
'gitlab_approve_merge_request',
657775
'gitlab_list_pipeline_jobs',
658776
'gitlab_get_job_log',
659777
'gitlab_play_job',
778+
'gitlab_list_releases',
779+
'gitlab_create_release',
660780
],
661781
config: {
662782
tool: (params) => {
@@ -960,6 +1080,32 @@ Return ONLY the commit message - no explanations, no extra text.`,
9601080
page: params.page ? Number(params.page) : undefined,
9611081
}
9621082

1083+
case 'gitlab_delete_branch':
1084+
if (!params.projectId?.trim() || !params.branch?.trim()) {
1085+
throw new Error('Project ID and branch name are required.')
1086+
}
1087+
return {
1088+
...baseParams,
1089+
projectId: params.projectId.trim(),
1090+
branch: params.branch.trim(),
1091+
}
1092+
1093+
case 'gitlab_compare_branches':
1094+
if (
1095+
!params.projectId?.trim() ||
1096+
!params.compareFrom?.trim() ||
1097+
!params.compareTo?.trim()
1098+
) {
1099+
throw new Error('Project ID, from ref, and to ref are required.')
1100+
}
1101+
return {
1102+
...baseParams,
1103+
projectId: params.projectId.trim(),
1104+
from: params.compareFrom.trim(),
1105+
to: params.compareTo.trim(),
1106+
straight: params.straight || undefined,
1107+
}
1108+
9631109
case 'gitlab_list_commits':
9641110
if (!params.projectId?.trim()) {
9651111
throw new Error('Project ID is required.')
@@ -1026,6 +1172,37 @@ Return ONLY the commit message - no explanations, no extra text.`,
10261172
jobId: Number(params.jobId),
10271173
}
10281174

1175+
case 'gitlab_list_releases':
1176+
if (!params.projectId?.trim()) {
1177+
throw new Error('Project ID is required.')
1178+
}
1179+
return {
1180+
...baseParams,
1181+
projectId: params.projectId.trim(),
1182+
perPage: params.perPage ? Number(params.perPage) : undefined,
1183+
page: params.page ? Number(params.page) : undefined,
1184+
}
1185+
1186+
case 'gitlab_create_release':
1187+
if (!params.projectId?.trim() || !params.tagName?.trim()) {
1188+
throw new Error('Project ID and tag name are required.')
1189+
}
1190+
return {
1191+
...baseParams,
1192+
projectId: params.projectId.trim(),
1193+
tagName: params.tagName.trim(),
1194+
name: params.releaseName?.trim() || undefined,
1195+
description: params.description?.trim() || undefined,
1196+
ref: params.ref?.trim() || undefined,
1197+
releasedAt: params.releasedAt?.trim() || undefined,
1198+
milestones: params.releaseMilestones
1199+
? params.releaseMilestones
1200+
.split(',')
1201+
.map((title: string) => title.trim())
1202+
.filter(Boolean)
1203+
: undefined,
1204+
}
1205+
10291206
default:
10301207
return baseParams
10311208
}
@@ -1071,6 +1248,13 @@ Return ONLY the commit message - no explanations, no extra text.`,
10711248
refName: { type: 'string', description: 'Branch or tag name filter' },
10721249
scope: { type: 'string', description: 'Job scope filter' },
10731250
sha: { type: 'string', description: 'Commit SHA' },
1251+
compareFrom: { type: 'string', description: 'Branch, tag, or commit SHA to compare from' },
1252+
compareTo: { type: 'string', description: 'Branch, tag, or commit SHA to compare to' },
1253+
straight: { type: 'boolean', description: 'Compare directly instead of using the merge base' },
1254+
tagName: { type: 'string', description: 'Git tag for the release' },
1255+
releaseName: { type: 'string', description: 'Release name' },
1256+
releasedAt: { type: 'string', description: 'ISO 8601 date for the release' },
1257+
releaseMilestones: { type: 'string', description: 'Milestone titles (comma-separated)' },
10741258
},
10751259
outputs: {
10761260
// Project outputs
@@ -1082,6 +1266,7 @@ Return ONLY the commit message - no explanations, no extra text.`,
10821266
// Merge request outputs
10831267
mergeRequests: { type: 'json', description: 'List of merge requests' },
10841268
mergeRequest: { type: 'json', description: 'Merge request details' },
1269+
mergeRequestIid: { type: 'number', description: 'Merge request internal ID (IID)' },
10851270
// Pipeline outputs
10861271
pipelines: { type: 'json', description: 'List of pipelines' },
10871272
pipeline: { type: 'json', description: 'Pipeline details' },
@@ -1091,17 +1276,38 @@ Return ONLY the commit message - no explanations, no extra text.`,
10911276
tree: { type: 'json', description: 'Repository tree entries' },
10921277
content: { type: 'string', description: 'File contents (decoded)' },
10931278
fileName: { type: 'string', description: 'File name' },
1279+
filePath: { type: 'string', description: 'Path to the file in the repository' },
1280+
branch: { type: 'string', description: 'Branch the file was committed to' },
10941281
branches: { type: 'json', description: 'List of branches' },
10951282
commits: { type: 'json', description: 'List of commits' },
1283+
commit: { type: 'json', description: 'A single commit (e.g. latest commit in a comparison)' },
10961284
name: { type: 'string', description: 'Created branch name' },
1285+
protected: { type: 'boolean', description: 'Whether the branch is protected' },
1286+
size: { type: 'number', description: 'File size in bytes' },
1287+
ref: { type: 'string', description: 'The branch, tag, or commit SHA' },
1288+
blobId: { type: 'string', description: 'The blob ID' },
1289+
lastCommitId: { type: 'string', description: 'The last commit ID that modified the file' },
10971290
webUrl: { type: 'string', description: 'Web URL' },
10981291
// Merge request change outputs
10991292
changes: { type: 'json', description: 'Merge request file changes/diffs' },
1293+
changesCount: { type: 'number', description: 'Number of changed files returned' },
11001294
approvalsRequired: { type: 'number', description: 'Approvals required' },
11011295
approvalsLeft: { type: 'number', description: 'Approvals remaining' },
1296+
approvedBy: { type: 'json', description: 'List of approvers' },
11021297
// Job outputs
11031298
jobs: { type: 'json', description: 'Pipeline jobs' },
11041299
log: { type: 'string', description: 'Job log output' },
1300+
id: { type: 'number', description: 'Job ID' },
1301+
status: { type: 'string', description: 'Job status' },
1302+
// Compare outputs
1303+
diffs: { type: 'json', description: 'File diffs between two compared references' },
1304+
compareTimeout: { type: 'boolean', description: 'Whether the comparison timed out' },
1305+
compareSameRef: { type: 'boolean', description: 'Whether both compared references match' },
1306+
// Release outputs
1307+
releases: { type: 'json', description: 'List of releases' },
1308+
release: { type: 'json', description: 'Release details' },
1309+
// Pagination
1310+
total: { type: 'number', description: 'Total number of items available across all pages' },
11051311
// Success indicator
11061312
success: { type: 'boolean', description: 'Operation success status' },
11071313
},
@@ -1213,5 +1419,12 @@ export const GitLabBlockMeta = {
12131419
content:
12141420
'# Monitor Pipeline Status\n\nUse GitLab to keep an eye on CI pipelines.\n\n## Steps\n1. List pipelines for the project and identify the most recent runs.\n2. Get the pipeline details for any that failed to read the status and reason.\n3. If a failure looks transient, use Retry Pipeline to re-run it.\n\n## Output\nReturn a summary of recent pipeline runs (ref, status, when) and call out any failures. If a retry was triggered, include the retried pipeline ID.',
12151421
},
1422+
{
1423+
name: 'draft-release-notes',
1424+
description:
1425+
'Compare two refs, summarize the merged changes, and publish a GitLab release with generated notes.',
1426+
content:
1427+
"# Draft Release Notes\n\nUse GitLab to publish a release with notes generated from the changes since the last tag.\n\n## Steps\n1. Compare Branches between the previous release tag and the target ref to list the commits and diffs.\n2. Summarize the changes into readable release notes, grouped by feature, fix, or chore.\n3. Use Create Release with the new tag name, the generated description, and the target ref.\n\n## Output\nReturn the created release's tag name and a confirmation that the notes were published, along with the release notes text.",
1428+
},
12161429
],
12171430
} as const satisfies BlockMeta

0 commit comments

Comments
 (0)