-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathcommitFileToRepo.ts
More file actions
91 lines (80 loc) · 2.46 KB
/
commitFileToRepo.ts
File metadata and controls
91 lines (80 loc) · 2.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import { parseGitHubRepoUrl } from "./parseGitHubRepoUrl";
export interface CommitFileResult {
path: string;
success: boolean;
error?: string;
}
/**
* Commits a single file to a GitHub repository using the Contents API.
* Creates the file if it doesn't exist, or updates it if it does.
*
* @param params - The parameters object
* @param params.githubRepo - The full GitHub repository URL (e.g. "https://github.com/owner/repo")
* @param params.path - The file path within the repository (e.g. "src/index.ts")
* @param params.content - The file content as a Buffer or string
* @param params.message - The commit message
* @returns The result indicating success or failure
*/
export async function commitFileToRepo({
githubRepo,
path,
content,
message,
}: {
githubRepo: string;
path: string;
content: Buffer | string;
message: string;
}): Promise<CommitFileResult> {
const token = process.env.GITHUB_TOKEN;
if (!token) {
return { path, success: false, error: "GITHUB_TOKEN is not configured" };
}
const repoInfo = parseGitHubRepoUrl(githubRepo);
if (!repoInfo) {
return { path, success: false, error: "Invalid GitHub repository URL" };
}
const { owner, repo } = repoInfo;
const base64Content =
typeof content === "string"
? Buffer.from(content).toString("base64")
: content.toString("base64");
const headers = {
Authorization: `Bearer ${token}`,
Accept: "application/vnd.github.v3+json",
"User-Agent": "Recoup-API",
"Content-Type": "application/json",
};
const apiUrl = `https://api.github.com/repos/${owner}/${repo}/contents/${path}`;
// Check if file already exists to get its SHA (required for updates)
let existingSha: string | undefined;
const existingResponse = await fetch(apiUrl, { headers });
if (existingResponse.ok) {
const existingData = (await existingResponse.json()) as { sha?: string };
existingSha = existingData.sha;
}
const body: Record<string, string> = {
message,
content: base64Content,
branch: "main",
};
if (existingSha) {
body.sha = existingSha;
}
const response = await fetch(apiUrl, {
method: "PUT",
headers,
body: JSON.stringify(body),
});
if (!response.ok) {
const errorData = (await response.json().catch(() => ({}))) as {
message?: string;
};
return {
path,
success: false,
error: errorData.message ?? `GitHub API error: ${response.status}`,
};
}
return { path, success: true };
}