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

最后

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

相关推荐
Best_Liu~2 小时前
el-table实现固定列,及解决固定列导致部分滚动条无法拖动的问题
前端·javascript·vue.js
给阿姨倒1杯卡布奇诺4 小时前
Git在多人开发中的常见用例
git
苏十八4 小时前
前端进阶:Vue.js
前端·javascript·vue.js·前端框架·npm·node.js·ecmascript
小超嵌入式笔记5 小时前
[教程]Gitee保姆级图文使用教程
git·gitee
乐容5 小时前
vue3使用pinia中的actions,需要调用接口的话
前端·javascript·vue.js
似水明俊德5 小时前
ASP.NET Core Blazor 5:Blazor表单和数据
java·前端·javascript·html·asp.net
friklogff7 小时前
【JavaScript脚本宇宙】美化网格布局:Isotope和Masonry让你的网页焕然一新
开发语言·前端·javascript
程楠楠&M8 小时前
vue3.0(十六)axios详解以及完整封装方法
前端·javascript·vue.js·axios·anti-design-vue
突然暴富的我9 小时前
Git 的基本概念和使用方式。
前端·git·json·github
朝思暮柒11 小时前
顶顶通呼叫中心中间件-外呼通道变量同步到坐席通道变量(mod_cti基于Freeswitch)
开发语言·javascript·ecmascript