refactor: split git provider adapters
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
import { Octokit } from '@octokit/rest'
|
||||
import { readRemoteFolder } from '../content'
|
||||
import { buildLfsPointer, splitLfsFiles, uploadToLfs } from '../lfs'
|
||||
import type { GitProvider, GitRemoteConfig, PushFilesParams } from '../types'
|
||||
|
||||
export function createGitHubProvider(remote: GitRemoteConfig, branch: string): GitProvider {
|
||||
const octokit = new Octokit({
|
||||
auth: remote.token,
|
||||
baseUrl: remote.apiBaseUrl,
|
||||
})
|
||||
|
||||
return {
|
||||
getRemoteFolder(folderPath) {
|
||||
return readRemoteFolder(remote, branch, folderPath)
|
||||
},
|
||||
|
||||
async pushFiles({ files, deletePaths, commitMessage }: PushFilesParams) {
|
||||
const { lfsFiles, regularFiles } = splitLfsFiles(files)
|
||||
|
||||
await uploadToLfs(
|
||||
remote,
|
||||
lfsFiles.map((file) => ({ oid: file.oid, size: file.size, contentBase64: file.contentBase64 })),
|
||||
)
|
||||
|
||||
const { owner, repo } = remote
|
||||
const { data: ref } = await octokit.git.getRef({
|
||||
owner,
|
||||
repo,
|
||||
ref: `heads/${branch}`,
|
||||
})
|
||||
const latestCommitSha = ref.object.sha
|
||||
|
||||
const { data: commit } = await octokit.git.getCommit({
|
||||
owner,
|
||||
repo,
|
||||
commit_sha: latestCommitSha,
|
||||
})
|
||||
|
||||
const allFiles = [...regularFiles, ...lfsFiles]
|
||||
|
||||
const blobResults = await Promise.all(
|
||||
allFiles.map((file) => {
|
||||
const lfs = lfsFiles.find((lfsFile) => lfsFile.path === file.path)
|
||||
if (lfs) {
|
||||
const pointer = buildLfsPointer(lfs.oid, lfs.size)
|
||||
return octokit.git.createBlob({
|
||||
owner,
|
||||
repo,
|
||||
content: Buffer.from(pointer, 'utf-8').toString('base64'),
|
||||
encoding: 'base64',
|
||||
})
|
||||
}
|
||||
|
||||
return octokit.git.createBlob({
|
||||
owner,
|
||||
repo,
|
||||
content: file.contentBase64,
|
||||
encoding: 'base64',
|
||||
})
|
||||
}),
|
||||
)
|
||||
|
||||
const newFilePaths = new Set(files.map((file) => file.path))
|
||||
const deleteEntries = deletePaths
|
||||
.filter((path) => !newFilePaths.has(path))
|
||||
.map((path) => ({
|
||||
path,
|
||||
mode: '100644' as const,
|
||||
type: 'blob' as const,
|
||||
sha: null,
|
||||
}))
|
||||
|
||||
const { data: newTree } = await octokit.git.createTree({
|
||||
owner,
|
||||
repo,
|
||||
base_tree: commit.tree.sha,
|
||||
tree: [
|
||||
...allFiles.map((file, index) => ({
|
||||
path: file.path,
|
||||
mode: '100644' as const,
|
||||
type: 'blob' as const,
|
||||
sha: blobResults[index].data.sha,
|
||||
})),
|
||||
...deleteEntries,
|
||||
],
|
||||
})
|
||||
|
||||
const { data: newCommit } = await octokit.git.createCommit({
|
||||
owner,
|
||||
repo,
|
||||
message: commitMessage,
|
||||
tree: newTree.sha,
|
||||
parents: [latestCommitSha],
|
||||
})
|
||||
|
||||
await octokit.git.updateRef({
|
||||
owner,
|
||||
repo,
|
||||
ref: `heads/${branch}`,
|
||||
sha: newCommit.sha,
|
||||
})
|
||||
|
||||
return { commitUrl: newCommit.html_url || `${remote.webUrl}/commit/${newCommit.sha}` }
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user