はじめに
Node 環境から GitHub へのコミットを行ったので、備忘録的にその方法を記事にします
今回の実装を行ったレポジトリはこちらです
https://github.com/kanakanho/esa-frontmatter-rewrite-push-github
環境
コミットする手順
0. 宣言とライブラリの準備
環境変数
GITHUB_ACCESS_TOKEN=<GitHubのトークン>GITHUB_OWNER=<GitHubのオーナー>GITHUB_REPO=<GitHubのレポジトリ>GITHUB_BRANCH=<コミット先のブランチ名>GITHUB_PATH=<コミットするGitHubのディレクトリのパス>
octokit と ファイル関係の宣言
import { Octokit } from "@octokit/rest";
const content:string = "# コミットするファイルの中身";const fileName:string = "README.md";const filePath:string = `${GITHUB_PATH}/${fileName}`;
const octokit = new Octokit({ auth: GITHUB_ACCESS_TOKEN,});
1. base ブランチの情報をfetch する
const baseBranchRef = await octokit.git .getRef({ owner: GITHUB_OWNER, repo: GITHUB_REPO, ref: `heads/${GITHUB_BRANCH}`, }) .catch((e) => { console.error(e); return false; });
if (typeof baseBranchRef === "boolean") { return false;}
2. コミットを行うブランチの最新のコミットの tree を fetch する
const currentCommit = await octokit.git .getCommit({ owner: GITHUB_OWNER, repo: GITHUB_REPO, commit_sha: baseBranchRef.data.object.sha, }) .catch((e) => { console.error(e); return false; });
if (typeof currentCommit === "boolean") { return false;}
3. fetch した tree を元にファイルを追加する tree を作成する
const newTree = await octokit.git.createTree({ owner: GITHUB_OWNER, repo: GITHUB_REPO, base_tree: currentCommit.data.tree.sha, tree: [ { path: filePath, mode: "100644", content: content, }, ],});
4. 作成した tree を用いて commit を作成する
const newCommit = await octokit.git.createCommit({ owner: GITHUB_OWNER, repo: GITHUB_REPO, message: `[esa-hono] commit`, tree: newTree.data.sha, parents: [baseBranchRef.data.object.sha],});
5. 作成したコミットをブランチに反映する
await octokit.git.updateRef({ owner: GITHUB_OWNER, repo: GITHUB_REPO, ref: `heads/${GITHUB_BRANCH}`, sha: newCommit.data.sha,});
これが全てエラーなく実行されたら GitHub にデータコミットされると思います
全体のコード
const { GITHUB_ACCESS_TOKEN, GITHUB_OWNER, GITHUB_REPO, GITHUB_BRANCH, GITHUB_PATH } = env<{ GITHUB_ACCESS_TOKEN: string; GITHUB_OWNER: string; GITHUB_REPO: string; GITHUB_BRANCH: string; GITHUB_PATH: string;}>(c);
const content:string = "# コミットするファイルの中身";const fileName:string = "README.md";const filePath:string = `${GITHUB_PATH}/${fileName}`;
const octokit = new Octokit({ auth: GITHUB_ACCESS_TOKEN,});
const currentCommit = await octokit.git .getCommit({ owner: GITHUB_OWNER, repo: GITHUB_REPO, commit_sha: baseBranchRef.data.object.sha, }) .catch((e) => { console.error(e); return false; });
if (typeof currentCommit === "boolean") { return false;}
const newCommit = await octokit.git.createCommit({ owner: GITHUB_OWNER, repo: GITHUB_REPO, message: `[esa-hono] commit`, tree: newTree.data.sha, parents: [baseBranchRef.data.object.sha],});
const newCommit = await octokit.git.createCommit({ owner: GITHUB_OWNER, repo: GITHUB_REPO, message: `[esa-hono] commit`, tree: newTree.data.sha, parents: [baseBranchRef.data.object.sha],});
await octokit.git.updateRef({ owner: GITHUB_OWNER, repo: GITHUB_REPO, ref: `heads/${GITHUB_BRANCH}`, sha: newCommit.data.sha,});
終わりに
普段 Git の深いところまで触れていないので、コミットって思ったよりも複雑な仕組みでできているんだと感じました。 あんまり情報がまとまっていないように感じたので、誰かの参考になれば幸いです!