通过这篇文章你可以掌握如何将github action 环境下临时生成的文件推送至指定分支,并且可以打开利用github开放的api做各种强大或有趣的事情的视野和思路。
如果你对github-action感兴趣,还可以看这篇文章, 这篇文章教会你如何开发Github Action,并且让你明白它是什么,怎么用,如何做到的。如何开发一个action
先抛出全部代码,然后在后续把这段代码的实现讲清楚。
try { // 1. 获取特定分支的最后一次提交 SHA const branchResponse = await Axios.get(`/branches/${branch}`); const lastCommitSHA = branchResponse.data.commit.sha; console.log("lastCommitSHA", lastCommitSHA); // 2. 创建 Blobs(base64 编码) const createBlob = async (content, encoding) => { const blobResponse = await Axios.post("/git/blobs", { content: content, encoding: encoding }); return blobResponse.data.sha; }; const jsonSHA = await createBlob( Buffer.from(JSON.stringify(contributors)).toString("base64"), "base64" ); const pngSHA = await createBlob(imageContent.toString("base64"), "base64"); // 3. 创建一个定义了文件夹结构的树 const createTree = async (baseTreeSHA, blobs) => { const tree = blobs.map(blob => { return { path: blob.path, mode: "100644", type: "blob", sha: blob.sha }; }); const treeResponse = await Axios.post("/git/trees", { base_tree: baseTreeSHA, tree: tree }); return treeResponse.data.sha; }; const treeSHA = await createTree(lastCommitSHA, [ { path: pngPath, sha: pngSHA }, { path: jsonPath, sha: jsonSHA } ]); console.log("treeSHA", treeSHA); // 4. 创建提交 const createCommit = async treeSHA => { const commitResponse = await Axios.post("/git/commits", { message: commitMessage, author: { name: committerName, email: committerEmail }, parents: [lastCommitSHA], tree: treeSHA }); return commitResponse.data.sha; }; const newCommitSHA = await createCommit(treeSHA); // 5. 更新分支引用 await Axios.patch(`/git/refs/heads/${branch}`, { sha: newCommitSHA }); } catch (error) { console.log("遇到错误", error); }
历史信息地址
每一个接口都可以翻阅文档来查看参数配置。
https://docs.github.com/en/rest/git/refs?apiVersion=2022-11-28以下两种接口的写法是等价的。
await octokit.request('PATCH /repos/{owner}/{repo}/git/refs/{ref}', { owner: 'OWNER', repo: 'REPO', ref: 'REF', sha: 'aa218f56b14c9653891f9e74264a383fa43fefbd', force: true, headers: { 'X-GitHub-Api-Version': '2022-11-28' } })
await Axios.patch(`/git/refs/heads/${branch}`, { sha: newCommitSHA });
console.log("lastCommitSHA", lastCommitSHA);
封装了一个createBlob 函数,用于将图片文件和json文件生成blob
const createBlob = async (content, encoding) => { return sha; }; const jsonSHA = await createBlob( Buffer.from(JSON.stringify(contributors)).toString("base64"), "base64" ); const pngSHA = await createBlob(imageContent.toString("base64"), "base64");
创建我们需要提交的commit,指定这个commit需要提交的文件变更。
treeSHA里面包含了两个文件,以数组的形式配置sha和path。
const createTree = async (baseTreeSHA, blobs) => { return sha; }; const treeSHA = await createTree(lastCommitSHA, [ { path: pngPath, sha: pngSHA }, { path: jsonPath, sha: jsonSHA } ]); console.log("treeSHA", treeSHA);
这边就是配置几个参数,就跟我们平常的git提交习惯差不多,需要有账号邮箱,message信息。只是我们不需要关心变更的文件tree以及parentCommitSha,通过第一步的lastCommitSHA,拿来直接用就好了。
console.log("lastCommitSHA", lastCommitSHA);
const createCommit = async treeSHA => { const commitResponse = await Axios.post("/git/commits", { message: commitMessage, author: { name: committerName, email: committerEmail }, parents: [lastCommitSHA], tree: treeSHA }); return commitResponse.data.sha; }; const newCommitSHA = await createCommit(treeSHA);
这边的branch可以暴露可配置的变量,
await Axios.patch(`/git/refs/heads/${branch}`, { sha: newCommitSHA });
写的够详细了吧,绝对有用吧,写了也是花了不少精力的,文章和你看了这么久的仓库总该点赞吧。