Last active
April 22, 2024 05:42
-
-
Save mikaelvesavuori/82fb8aeb4a9408fdadafe429c98e6f46 to your computer and use it in GitHub Desktop.
Helpful GitHub API functionality for Node.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { getBlobShaFromGithub } from './getBlobShaFromGithub'; | |
export async function createFileInGithub(input: string, fileName: string, type: string) { | |
const owner = process.env.OWNER; | |
const repo = process.env.REPO; | |
const workflowId = process.env.WORKFLOW_ID; | |
const token = process.env.GITHUB_TOKEN; | |
if (!owner || !repo || !workflowId || !token) | |
throw new Error('Missing required environment variables!'); | |
const folder = 'latest'; | |
const sha = await getBlobShaFromGithub(`${folder}/${fileName}`); | |
const url = `https://api.github.com/repos/${owner}/${repo}/contents/${folder}/${fileName}`; | |
const body = JSON.stringify({ | |
message: type, | |
committer: { | |
name: 'Something', | |
email: '[email protected]' | |
}, | |
content: encode(input), | |
sha | |
}); | |
return await fetch(url, { | |
method: 'PUT', | |
headers: { | |
Authorization: `Bearer ${token}` | |
}, | |
body | |
}); | |
} | |
function encode(content: string) { | |
return Buffer.from(content, 'utf8').toString('base64'); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export async function getBlobShaFromGithub(path: string) { | |
const owner = process.env.OWNER; | |
const repo = process.env.REPO; | |
const workflowId = process.env.WORKFLOW_ID; | |
const token = process.env.GITHUB_TOKEN; | |
if (!owner || !repo || !workflowId || !token) | |
throw new Error('Missing required environment variables!'); | |
const GITHUB_URL = `https://api.github.com/repos/${owner}/${repo}/contents/${path}`; | |
return await fetch(GITHUB_URL, { | |
method: 'GET', | |
headers: { | |
Authorization: `Bearer ${token}` | |
} | |
}) | |
.then((res: any) => res.json()) | |
.then((res: Record<string, any>) => res.sha); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export async function startGitHubWorkflow( | |
type: string, | |
timestamp: string, | |
customerId: string, | |
systemId: string // Used for App ID or Flow ID | |
) { | |
const owner = process.env.OWNER || ''; | |
const repo = process.env.REPO || ''; | |
const token = process.env.GITHUB_TOKEN || ''; | |
if (!owner || !repo || !token) | |
throw new Error( | |
'Missing required environment variables when getting blob SHA from GitHub!' | |
); | |
const basePath = `https://api.github.com/repos/${owner}/${repo}`; | |
const workflowFile = 'main.yml'; | |
return await fetch(`${basePath}/actions/workflows/${workflowFile}/dispatches`, { | |
method: 'POST', | |
body: JSON.stringify({ | |
ref: 'main', | |
inputs: { type, timestamp, customer_id: customerId, flow_id: systemId } | |
}), | |
headers: headers(token) | |
}) | |
} | |
const headers = (token: string, hasBody = true) => ({ | |
Accept: 'application/vnd.github.v3+json', | |
Authorization: `Bearer ${token}`, | |
'Content-Type': hasBody ? 'application/json' : 'text/plain' | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @description Uploading several files to GitHub is a complicated affair. | |
* This utility takes care of that orchestration. | |
*/ | |
export async function uploadFilesToGitHub(files: { name: string; content: string }[]) { | |
const owner = process.env.OWNER || ''; | |
const repo = process.env.REPO || ''; | |
const token = process.env.GITHUB_TOKEN || ''; | |
if (!owner || !repo || !token) | |
throw new Error('Missing required environment variables when generating CFN template!'); | |
const basePath = `https://api.github.com/repos/${owner}/${repo}`; | |
const branch = 'main'; | |
const blobs = await Promise.all( | |
files.map(async (file) => { | |
const response = fetch(`${basePath}/git/blobs`, { | |
method: 'POST', | |
body: JSON.stringify({ | |
content: file.content, | |
encoding: 'utf-8' | |
}), | |
headers: headers(token) | |
}) as any; | |
return { path: file.name, mode: '100644', type: 'blob', sha: response.sha }; | |
}) | |
); | |
const { baseTreeSha, refData } = await getBaseTreeSha( | |
`${basePath}/git/ref/heads/${branch}`, | |
token | |
); | |
const treeData = await createNewTree(`${basePath}/git/trees`, token, baseTreeSha, blobs); | |
const commitData = await createCommit(`${basePath}/git/commits`, token, refData, treeData); | |
await updateRef(`${basePath}/git/refs/heads/${branch}`, token, commitData); | |
} | |
async function getBaseTreeSha(url: string, token: string) { | |
const response = await fetch(url, { | |
method: 'GET', | |
headers: headers(token, false) | |
}) as any; | |
return { refData: response, baseTreeSha: response.object.sha }; | |
} | |
async function createNewTree(url: string, token: string, baseTreeSha: string, blobs: any) { | |
return await fetch(url, { | |
method: 'POST', | |
body: JSON.stringify({ | |
base_tree: baseTreeSha, | |
tree: blobs | |
}), | |
headers: headers(token) | |
}); | |
} | |
async function createCommit(url: string, token: string, refData: any, treeData: any) { | |
return await fetch(url, { | |
method: 'POST', | |
body: JSON.stringify({ | |
committer: { | |
name: 'Popcorn Cloud builder', | |
email: '[email protected]' | |
}, | |
message: 'flow', | |
parents: [refData.object.sha], | |
tree: treeData.sha | |
}), | |
headers: headers(token) | |
}) | |
} | |
async function updateRef(url: string, token: string, commitData: any) { | |
return await fetch(url, { | |
method: 'PATCH', | |
body: JSON.stringify({ sha: commitData.sha }), | |
headers: headers(token, true) | |
}) | |
} | |
const headers = (token: string, hasBody = true) => ({ | |
Accept: 'application/vnd.github.v3+json', | |
Authorization: `Bearer ${token}`, | |
'Content-Type': hasBody ? 'application/json' : 'text/plain' | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment