最近GitHub Actionsを便利に使うためのCustom Actionを作っていました。
このActionに設定をリポジトリ内のファイルから取得する機能を追加したくなったんですが、この機能のためだけにcheckoutするのもなぁ、と悩んでいました。
具体的には、このPRの実装に必要でした。リリース用Issueの先頭に固定のテキスト(リリースフローなどを想定しています)を追加する機能です。
Custom Actionからリポジトリ内のファイルを参照する
GitHub ActionsではそのActionが発火するリポジトリに関する操作ができるGitHubのトークンが簡単に取得できます。APIから固定のファイルを取得することができれば、リポジトリ全体をcheckoutしてくる必要がありません。
GitHubはAPIが豊富なので、もちろんこのAPIも用意されていました。
パスを指定してファイルを取得できます。パスがファイルの場合は*1 content
フィールドにエンコードされたファイルの内容が入っています。また、encoding
フィールドにエンコード方式が入っています。
サンプルレスポンスには、エンコード方式にbase64とあり、実際にAPIを叩いてみてもBase64でエンコードされた内容が入っているようなのですが、ドキュメントにはエンコーディングについての説明が見当たりませんでした。
Stackoverflowに Base64 encoded content
と昔は書かれていたような記録を見つけたので、これを信じてBase64固定で実装しました。
このAPIでは指定したパスにあるファイル形式により挙動が変わるので少しややこしいのですが、ファイルを取得したいだけなら
const content = await octokit.rest.repos.getContent({ owner: owner, repo: repo, path: path, }); if ("content" in content.data) { const file_content = Buffer.from(content.data["content"]).toString("base64"); console.log(file_content) }
簡単ですね
ということでPRができました。PRではファイル以外のパターンでのエラー処理なども追加しています。
*1:ファイル以外にもディレクトリやサブモジュールの場合もあり、それぞれ返ってくるレスポンスが違います。