feat(pr): add GitLab support
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
export type Platform = "github" | "gitea";
|
||||
export type Platform = "github" | "gitea" | "gitlab";
|
||||
|
||||
export async function getDefaultBranch(): Promise<string> {
|
||||
try {
|
||||
@@ -93,16 +93,23 @@ function parseRemoteHostname(url: string): string | null {
|
||||
return hostname || null;
|
||||
}
|
||||
|
||||
export function detectPlatformFromHostname(hostname: string | null): Platform | null {
|
||||
if (!hostname) return null;
|
||||
|
||||
if (hostname === "github.com") return "github";
|
||||
if (hostname === "gitlab.com" || hostname.includes("gitlab")) {
|
||||
return "gitlab";
|
||||
}
|
||||
if (hostname.includes("gitea")) return "gitea";
|
||||
return null;
|
||||
}
|
||||
|
||||
export async function detectPlatform(): Promise<Platform | null> {
|
||||
try {
|
||||
const url = await Bun.$`git remote get-url origin`.quiet().text();
|
||||
const hostname = parseRemoteHostname(url);
|
||||
|
||||
if (!hostname) return null;
|
||||
|
||||
if (hostname === "github.com") return "github";
|
||||
if (hostname.includes("gitea")) return "gitea";
|
||||
return null;
|
||||
return detectPlatformFromHostname(hostname);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
@@ -118,12 +125,16 @@ export async function getRemoteHostname(): Promise<string | null> {
|
||||
}
|
||||
|
||||
export function checkCLI(platform: Platform): string | null {
|
||||
const bin = platform === "github" ? "gh" : "tea";
|
||||
const bin =
|
||||
platform === "github" ? "gh" : platform === "gitlab" ? "glab" : "tea";
|
||||
const path = Bun.which(bin);
|
||||
if (!path) {
|
||||
if (platform === "github") {
|
||||
return "GitHub CLI (gh) not found. Install: brew install gh";
|
||||
}
|
||||
if (platform === "gitlab") {
|
||||
return "GitLab CLI (glab) not found. Install: brew install glab";
|
||||
}
|
||||
return "Gitea CLI (tea) not found. Install from: https://gitea.com/gitea/tea";
|
||||
}
|
||||
return null;
|
||||
@@ -139,6 +150,15 @@ export async function checkAuth(platform: Platform): Promise<string | null> {
|
||||
}
|
||||
}
|
||||
|
||||
if (platform === "gitlab") {
|
||||
try {
|
||||
await Bun.$`glab auth status`.quiet();
|
||||
return null;
|
||||
} catch {
|
||||
return "Not authenticated with GitLab CLI. Run: glab auth login";
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await Bun.$`tea logins list`.quiet().text();
|
||||
if (result.trim()) return null;
|
||||
@@ -186,6 +206,37 @@ export async function createPR(
|
||||
return match?.[1] ?? stdout.trim();
|
||||
}
|
||||
|
||||
if (platform === "gitlab") {
|
||||
const args = [
|
||||
"mr",
|
||||
"create",
|
||||
"--title",
|
||||
title,
|
||||
"--description",
|
||||
body,
|
||||
"--target-branch",
|
||||
base,
|
||||
];
|
||||
if (draft) args.push("--draft");
|
||||
|
||||
const proc = Bun.spawn(["glab", ...args], {
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
const exitCode = await proc.exited;
|
||||
const stdout = await new Response(proc.stdout).text();
|
||||
const stderr = await new Response(proc.stderr).text();
|
||||
|
||||
if (exitCode !== 0) {
|
||||
throw new Error(
|
||||
stderr.trim() || `glab mr create failed (exit code ${exitCode})`,
|
||||
);
|
||||
}
|
||||
|
||||
const match = stdout.match(/(https?:\/\/[^\s]+)/);
|
||||
return match?.[1] ?? stdout.trim();
|
||||
}
|
||||
|
||||
const args = [
|
||||
"pulls",
|
||||
"create",
|
||||
|
||||
Reference in New Issue
Block a user