【Github-Action】GithubAction 环境下,如何将临时生成的文件推送至指定分支。

通过这篇文章你可以掌握如何将github action 环境下临时生成的文件推送至指定分支,并且可以打开利用github开放的api做各种强大或有趣的事情的视野和思路。
如果你对github-action感兴趣,还可以看这篇文章, 这篇文章教会你如何开发Github Action,并且让你明白它是什么,怎么用,如何做到的。如何开发一个action

如何将临时生成的文件推送至指定分支

  • 场景分析
  • 核心代码
  • [检查action 运行的历史](#检查action 运行的历史)
  • 前置知识
  • 开发步骤详解
    • [1. 获取特定分支的最后一次提交 SHA](#1. 获取特定分支的最后一次提交 SHA)
    • [2. 创建 Blobs(base64 编码)](#2. 创建 Blobs(base64 编码))
    • [3. 创建一个定义了文件夹结构的树](#3. 创建一个定义了文件夹结构的树)
    • [4. 创建提交](#4. 创建提交)
    • [5. 更新分支引用](#5. 更新分支引用)
  • 最后

场景分析

  • 问题:什么时候需要这样子的功能?
  • 解答:当时我开发社区贡献统计Action的时候,会生成一个svg图片,但是为了让更多人能够复用这个工具,又节约一笔服务器的运营成本。

核心代码

先抛出全部代码,然后在后续把这段代码的实现讲清楚。

 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);
  }

检查action 运行的历史

历史信息地址

前置知识

每一个接口都可以翻阅文档来查看参数配置。

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
    });

开发步骤详解

1. 获取特定分支的最后一次提交 SHA

console.log("lastCommitSHA", lastCommitSHA);

2. 创建 Blobs(base64 编码)

封装了一个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");

3. 创建一个定义了文件夹结构的树

创建我们需要提交的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);

4. 创建提交

这边就是配置几个参数,就跟我们平常的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);

5. 更新分支引用

这边的branch可以暴露可配置的变量,

  await Axios.patch(`/git/refs/heads/${branch}`, {
    sha: newCommitSHA
  });

最后

写的够详细了吧,绝对有用吧,写了也是花了不少精力的,文章和你看了这么久的仓库总该点赞吧。

相关推荐
ggdpzhk43 分钟前
VUE:基于MVVN的前端js框架
前端·javascript·vue.js
小曲曲2 小时前
接口上传视频和oss直传视频到阿里云组件
javascript·阿里云·音视频
学不会•3 小时前
css数据不固定情况下,循环加不同背景颜色
前端·javascript·html
EasyNTS4 小时前
H.264/H.265播放器EasyPlayer.js视频流媒体播放器关于websocket1006的异常断连
javascript·h.265·h.264
yyycqupt5 小时前
git使用(一)
git
活宝小娜5 小时前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点5 小时前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow5 小时前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js
我开心就好o5 小时前
uniapp点左上角返回键, 重复来回跳转的问题 解决方案
前端·javascript·uni-app
刚刚好ā6 小时前
js作用域超全介绍--全局作用域、局部作用、块级作用域
前端·javascript·vue.js·vue