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,
}
}