Skip to content

Built for people who want to own their automations. Join the waitlist for an invite.

Package listing

@kody/gitlab

src/merge-requests/merge.ts

66 lines · 2.0 KB · TypeScript
import { isConfirmed, isDryRun, normalizeMergeRequestLocator, pickAuthInput, request } from '../core.ts'
import { asRecord, readOptionalBoolean, readOptionalString, slimMergeRequest } from '../shape.ts'

/**
 * Merge a GitLab merge request.
 *
 * Pass `dryRun: true` to preview the merge. Live merges require `confirm: true`.
 *
 * @example
 * import mergeGitlabMergeRequest from 'kody:@kody/gitlab/merge-requests/merge'
 * const preview = await mergeGitlabMergeRequest({
 *   project: 'example-group/example-project',
 *   mergeRequestIid: 4,
 *   squash: true,
 *   dryRun: true,
 * })
 */
export default async function mergeGitlabMergeRequest(params: Record<string, unknown> = {}) {
	const auth = pickAuthInput(params)
	const { projectId, projectPath, mergeRequestIid } = normalizeMergeRequestLocator(params)
	const body: Record<string, unknown> = {}
	const sha = readOptionalString(params.sha)
	if (sha) body.sha = sha
	const squash = readOptionalBoolean(params.squash)
	if (squash !== undefined) body.squash = squash
	const removeSourceBranch = readOptionalBoolean(
		params.should_remove_source_branch ?? params.removeSourceBranch,
	)
	if (removeSourceBranch !== undefined) body.should_remove_source_branch = removeSourceBranch
	const mergeCommitMessage = readOptionalString(
		params.merge_commit_message ?? params.mergeCommitMessage,
	)
	if (mergeCommitMessage) body.merge_commit_message = mergeCommitMessage

	if (isDryRun(params)) {
		return {
			dryRun: true,
			wouldMerge: true,
			projectPath,
			mergeRequestIid,
			body,
			auth,
		}
	}

	if (!isConfirmed(params)) {
		throw new Error(
			`Merging ${projectPath}!${mergeRequestIid} requires dryRun: true (preview) or confirm: true (live merge).`,
		)
	}

	const response = await request<Record<string, unknown>>({
		...auth,
		method: 'PUT',
		path: `/projects/${projectId}/merge_requests/${mergeRequestIid}/merge`,
		body,
		throwOnError: true,
		confirm: true,
	})

	return {
		...slimMergeRequest(asRecord(response.data)),
		projectPath,
		auth: response.auth,
	}
}