DN360 Blog

githubの機能を使いまくってブログ機能をつくってみた

2026/8/1

はじめに

このホームページは、NextJSとStatic Exportをつかって静的ファイルとして出力し、github pagesとして出力しています。今回のリニューアルに関しても同じ仕組みで実装しています。そして、リニューアル前のホームページではブログ機能があったのですが、あれは自分でマークダウンを書きpublic以下に添付ファイルを置き、リンクをいい感じに貼ってブログを書いていました。しかし、これだといちいちエディタを立ち上げないといけないので手間がかかっていたのです。

そこで、Githubにissueとしてmarkdownを書き、blogのラベルが貼られたときにGithub Actionsを起動し、ブログを構成するためのjsonファイルとしてmarkdown情報をpush、それをトリガーとしてNextJS の Static Export + github pagesにデプロイすることで自動化をしてみました。

実装に際して使った技術

  • Github Copilot
    • このホームページの実装自体もCopilotにほぼ任せています。NextJSのセットアップからGithub Actionsのワークフロー作成なども行っています。
  • Octokit
    • 後述する問題に対して使っています。GithubのREST APIを叩きIssueやリポジトリ内のファイルに直接アクセスするためのモジュールです。
  • NextJS
    • これがないとホームページができないですよ。

大問題発生「GithubのIssueにアタッチされたファイルのURLは外から見えない」

Github上で添付したファイルはs3にアップロードされているようです。添付ファイルのレスポンスヘッダに x-amz-replication-status があるのでおそらくs3です。

そしてs3に置かれたファイルへのアクセスはjwt認証で時間制限付きでアクセスができるようになっています。そしてこのjwt認証のトークンはブラウザ上の認証キャッシュからアクセス権があれば付与され、Issue上で見られるようになっています。

そう、ここでお気づきの方もいると思うのですが、なんと認証キャッシュから判定して発行しているのでcURLに認証情報を持たせてもアクセスができないのです。しかもこのホームページのリポジトリ自体はprivateにしているので外からwebでアクセスして取得...みたいな力技も難しいです(最終的にめちゃくちゃ力技になっていますが)

ちなみに他の方も記事で言及されていますが、このファイルへのアクセスをなんとかGithub Tokenでやってほしいという要望はあるようです。この記事を書いている段階ではまだないので早く実装してほしいものです。

どうやったか?REST APIに解決策があった

なんとか抜け道はないものか...と調べに調べたところあるDiscussionにたどり着きました。「Github Appのトークンでprivate なリポジトリにある添付ファイルにアクセスできんの?」という会話でした。まさしく求めていた内容です。そしてうれしいことにここに答えが書いてありました。

まずGitHub REST APIで課題を取得することができます。 この取得するときに、headerのAcceptに "application/vnd.github.html+json" と指定すると結果がmarkdownではなく整形されたHTMLで返ってきます。そしてこのHTML内にある添付ファイルを表示するためのURLはなんとjwtがついたURLになっているのです。しかもmarkdownに添付したときに貼り付けられるURLと紐づけがちゃんとできるような形式で貼られています。このHTML形式で取る方法はoctokitのパラメータのheadersに書く、という方法でできますのでこれを使えば良さそうです。

ということで方針が固まりました。以下に方針をまとめます。

実装方針

以下の方針をGithub Copilotに渡してプランニングし、自分がプランのレビューをしてからそのとおりに実装してもらいました。

  1. Issueにブログ記事を書き、画像ファイルの添付などしてからblogラベルを貼る。
  2. blogラベルが貼られたIssueについて、octokitをつかって取得しリストとして保持する。
  3. 1つ1つのIssueについて、Issue番号を元に整形済みHTMLを取得する。この中にあるjwtが付与されているURLをすべて抜き出しておく。
  4. Issueのmarkdownのほうにある添付ファイルのURLにはUUIDがついているので、このUUIDと3で抜き出したURLリストのうち、URL内に一致するものがあったらそれが対応するURLとして取得しダウンロード、publicフォルダ以下にIssue番号に紐づいたフォルダを作成して配置する。
  5. markdownのimgタグや添付ファイルのURLをpublicフォルダ以下のものを指すように変更する。

できたのか?試しに前のページでつくったブログのものを見てみよう。

前にChatGPTとNovelAIをつかって年賀状をつくった、というブログを書いたのですが、今回のリニューアルでコピーし、今回構築したブログとして書き直してみました。まず出来上がったブログの画像のURLを見てみましょう。

Image

はい、正しくpublicフォルダ以下にあるアセットを参照していますね。ではIssue上にあるブログ記事をみてみましょう。

Image

上図: markdownテキスト

Image

上図: markdownプレビューのインスペクタ

Issue上ではs3上のものを指定していることがわかりました。ということでブログとして発行したときだけ、という処理はちゃんとできていそうですね。

万全な対応なのか?

実をいうと結構抜け道をついているので今後アプデで対応されたら動かなくなります。ただし、それに合わせてちゃんと取得できるようにしてくれたらもっと簡単になるので対応してもらいたいところです。

Issueでいいのか?

最初markdownをリポジトリにpushして、それをトリガーにする...というのを考えていたんですが結局ユーザー添付ファイルの認証問題に引っかかったのでじゃあIssueのほうがわかりやすいしいいなという気持ちがあります(WIPが見やすい) あと名前をトリガーにしてslugにしたところNextJS 16 Turboでどうもうまくいかないことがわかり、ならIssue番号を固有IDとしてブログのルーティングに使えるということもあってIssueベースにしています。 ちなみにWikiページについてですが、なんとGitHub REST APIに該当するAPIが見当たりません。残念...

まとめ

  • ユーザー添付ファイルを取得するのは超大変、というか正攻法だと無理でした。
  • GitHub REST APIで取得したIssueはHTMLに整形でき、整形されたHTMLには認証情報がついているのでそれをつかって取得はできました。
    • 永続はできないのであくまでそのタイミングで取得するだけのほうがいいです。
  • これでコードエディタを立ち上げなくてもブログが書けます。スマホにはGitHubアプリもあるのでそれでブログを書き続けることもできます。
Blogブログ一覧に戻る