import { repoDb } from "./scoped-db";
import { badRequest, conflict, forbidden } from "./errors";
import { branchSha, listRefs } from "./git/refs";
import { kickBranch } from "./merge-automation";
import { dequeuePull, enqueuePull } from "./merge-queue";
import { afterPullChange } from "./pull-events";
import { stackParent } from "./stacks";
import { addIssueEvent, MergeError } from "./pulls";
import type { MergeMethod, Viewer } from "~/lib/types";
import type { PullAccess } from "./reviews-write";
function rethrowMerge(error: unknown): never {
if (error instanceof MergeError) throw conflict(error.message);
throw error;
}
/** Requires write access. Enabling pins the current head; a missing or stale `expectedHead` is a 409. */
export async function setAutoMerge(
access: PullAccess,
viewer: Viewer,
input: { enabled: boolean; method: MergeMethod; message: string; expectedHead?: string },
): Promise<void> {
const { pull } = access;
if (!input.enabled) {
await repoDb(pull.repo_id).run("DELETE FROM pull_auto_merges WHERE issue_id = ?", pull.issue_id);
await addIssueEvent(pull, viewer.id, "auto_merge_disabled", {});
return;
}
if (pull.state !== "open") throw badRequest("Pull request is not open");
if (pull.head_sha !== input.expectedHead) throw conflict("The head branch changed; reload and try again");
await repoDb(pull.repo_id).run(
`INSERT INTO pull_auto_merges (issue_id, repo_id, method, message, enabled_by, created_at, head_sha)
VALUES (?, ?, ?, ?, ?, ?, ?)
ON CONFLICT (issue_id) DO UPDATE SET method = excluded.method, message = excluded.message,
enabled_by = excluded.enabled_by, head_sha = excluded.head_sha`,
pull.issue_id,
pull.repo_id,
input.method,
input.message,
viewer.id,