kanakanho / しばいぬ

About me

Works

Posts

Contact / Links

Node環境からGitHub にコミットを行う方法

2024/09/30

はじめに

Node 環境から GitHub へのコミットを行ったので、備忘録的にその方法を記事にします

今回の実装を行ったレポジトリはこちらです

https://github.com/kanakanho/esa-frontmatter-rewrite-push-github

環境

コミットする手順

0. 宣言とライブラリの準備

環境変数

.dev.vars
GITHUB_ACCESS_TOKEN=<GitHubのトークン>
GITHUB_OWNER=<GitHubのオーナー>
GITHUB_REPO=<GitHubのレポジトリ>
GITHUB_BRANCH=<コミット先のブランチ名>
GITHUB_PATH=<コミットするGitHubのディレクトリのパス>

octokit と ファイル関係の宣言

.ts
title=".ts"
title=".ts"
title=".ts"
title=".ts"
title=".ts"
title=".ts"
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 の深いところまで触れていないので、コミットって思ったよりも複雑な仕組みでできているんだと感じました。 あんまり情報がまとまっていないように感じたので、誰かの参考になれば幸いです!

参考にしたサイト

https://queq1890.info/blog/octokit

Postsに戻る