Code

// src/createMergeRequest.ts
import simpleGit from "simple-git";
import { readEnvProps } from "./env-parser";

// test: <https://git.koreaats.com/api/v4/version>
const git = simpleGit();
const gitlabUrl = "<https://git.koreaats.com>";
const gitlabPrjectID = "50";
const targetBranch = "develop";

// async function getRemoteUrl(): Promise<string> {
//     const remotes = await git.getRemotes(true);
//     const originRemote = remotes.find(remote => remote.name === "origin");
//     if (!originRemote) {
//         throw new Error("Origin remote not found.");
//     }
//     return originRemote.refs.fetch;
// }

// ========================================================================================
/** 현재 브랜치명 반환
*/// ======================================================================================
async function getCurrentBranch(): Promise<string> {
    const status = await git.status();
    return status.current!;
}

// ========================================================================================
/** 현재 브랜치와 대상 브랜치의 차이가 있는지 확인
*/// ======================================================================================
async function hasChanges(): Promise<boolean> {
    await git.fetch();
    const summary = await git.diffSummary(['HEAD', `origin/${targetBranch}`]);
    return summary.files.length > 0;
}

// ========================================================================================
/** Merge Request 생성
*/// ======================================================================================
async function createMergeRequest(sourceBranch: string, accessToken: string) {
    const apiUrl = `${gitlabUrl}/api/v4/projects/${gitlabPrjectID}/merge_requests`;

    try {
        const response = await fetch(apiUrl, {
            method: "POST",
            headers: {
                "PRIVATE-TOKEN": accessToken,
                "Content-Type": "application/json"
            },
            body: JSON.stringify({
                source_branch: sourceBranch,
                target_branch: targetBranch,
                title: `Auto Generated Merge Request [${sourceBranch}] -> [${targetBranch}]`
            })
        });

        if (!response.ok) {
            throw new Error(`GitLab API responded with ${response.status}`);
        }

        const data = await response.json();
        console.log(`Merge Request 생성 완료: ${data.web_url}`);
    } catch (error) {
        console.error(`Merge Request에 실패하였습니다: ${error.message}`);
    }
}

// Main
(async () => {

    try {
        const envLocal = readEnvProps(".env.local");
        const currentBranch = await getCurrentBranch();
        const accessToken = envLocal.GITLAB_ACCESS_TOKEN;
        const isBranchesHasChanges = await hasChanges();

        if(!isBranchesHasChanges) {
            throw new Error("변경사항이 존재하지 않습니다.");
        }

        if (!accessToken) {
            throw new Error(".env.local 파일에 GITLAB_ACCESS_TOKEN 설정이 필요합니다.");
        }

        await createMergeRequest(currentBranch, accessToken);
    } catch (error) {
        console.error(`Merge Request 생성에 실패하였습니다: ${error.message}`);
    }
})();