🚃

Railsにマージされた最新PRを毎日自動要約するサイトを作った

に公開

GA technologiesでソフトウェアエンジニアをしている中坂です。

先日、業務の傍らで個人的にRails PR Digestというサイトを作りました。これはRuby on Railsにマージされた最新のPull Requestを自動収集してLLMで日本語要約した結果をまとめるサイトです。リリースしてから大体一ヶ月弱くらい運用していますが特に問題なく安定して稼働しています。

https://yuheinakasaka.github.io/rails-pr-digest/

主な機能は以下の通りです。

  • 毎日自動でrails/railsのmainブランチにマージされたPRをチェック
  • LLM(OpenAI GPT-5.1)を用いた詳細な日本語要約(概要・変更内容・影響範囲・参考情報)
  • 月別に整理されたアーカイブ

なぜ作ったか

普段業務でRailsを使って開発しているのでRailsの日々の動向を追うのは重要です。しかし、rails/railsのリポジトリには毎日割と多くのPRがマージされており、GitHub公式サイトを地道に追うのはやや面倒です。

また、PRのタイトルだけでは具体的に何が変わったのか、自分のプロジェクトにどう影響するのかがわかりにくいことも多いです。特に英語のPR本文を読むのも、毎日となると負担が大きくなります。今はLLMがあるので翻訳をかければ一発ではあるのですが、通勤中にスマホで読みたい場合などはPCで読む場合より一手間か二手間くらいかかるのでなかなか面倒です。

そこで「マージされたPRを自動収集して、AIで日本語要約し、整理してサクッと閲覧できるサイト」を作ることにしました。

構成

今回のサイトの全体の構成は以下のようになっています。

普段使いのClaude Codeと対話を行ない、要求や基本設計などの方針を示して伝えることで、良い感じにモジュール分割されたTypeScriptのコードや、テストコード、GitHub Actionsの設定ファイルなどを作りました。

今回の主要な実装は大きく分けて以下の4つのコンポーネントで構成されています。

1. PR収集(GitHub API)

GitHub APIを使用して、過去24時間にmainブランチにマージされたPRを検索します。PR番号、タイトル、説明、変更ファイル数などの情報を取得します。

2. AI要約(OpenAI GPT-5.1)

収集したPR情報をOpenAI GPT-5.1に送信し、日本語で以下の構造で要約を生成します。

  • 概要(1-2文)
  • 変更内容の詳細(サンプルコード含む)
  • 影響範囲・注意点
  • 参考情報
const prompt = `以下のRuby on Rails PRを日本語で要約・解説してください。

PR情報:
- タイトル: ${pr.title}
- 番号: #${pr.number}
- 作成者: ${pr.user?.login}
- マージ日時: ${pr.merged_at}
- 説明: ${pr.body}

変更されたファイル (最大20件):
${fileChanges}

以下の形式で出力してください:
1. 概要 (1-2文で)
2. 変更内容の詳細(あればサンプルコードも含めて)
3. 影響範囲・注意点
4. 参考情報 (あれば)

技術的に正確で、開発者にとって有益な情報を含めてください。`;

ちなみにGPT-5.1を使ったのはコストの安さと程々な精度が出るという理由です。尚、今の最新だとGPT-5.2ですがこちらは5.1より料金が高いのとパフォーマンスがやや悪い印象がありGPT-5.1を使っています。

https://platform.openai.com/docs/pricing

3. ファイル生成・更新

年月に基づいてMarkdownファイルを生成します。月の途中の実行では既存ファイルに追記(最新の情報が上に表示)され、新しい月の最初の実行では新しいファイルが作成されます。重複チェック機能も実装されており、既に処理済みのPRは再度追加されません。

4. デプロイ(GitHub Actions + VitePress)

GitHub Actionsで毎日定時に自動実行され、変更をコミット・プッシュした後、VitePressでビルドしてGitHub Pagesにデプロイします。

VitePressは静的サイトジェネレーターで、Markdownファイルを元に静的HTMLを生成できます。デザインもデフォルトで良い感じになっているそのまま使っています。VitePressを使っている他のサイトはたくさんあるので似たような見た目のサイトになってしまうのは難点かもしれませんが、変に色気を出して見辛いデザインにするよりはマシです。

設計と運用のこだわり

このサイトを構築する上で最もこだわったのは、開発後に極力手をかけずに動かし続ける仕組みを作ることです。

LLMの時代におけるエンジニアリング

LLMの登場で実装する工程は確かに楽になりましたが、エンジニアリングはただ作るだけではなく、その先の安定した運用保守まで作り込んでこそです。

  • いつか変更や更新を手動で行う際にデグレを防ぐためのテストやドキュメントを残しておく
  • 自動化できる部分は徹底的に自動化する
  • コストがかからない構成を選ぶ
  • 障害が起きにくい設計にする
  • メンテナンスの手間を最小化する

などなど、品質と持続的に維持するための視点でシステムを設計することで、長期的に安定して動き続けるサービスにつながります。

誰でもすぐに動くものが作れるようになったLLM時代こそ、エンジニアリングの本質を理解している人が求められていると思います。

コストを抑える設計

運用コストはOpenAIのAPI利用料のみです(実は1年前くらいに勉強代に数万円ぶっ込んでいたのですが使いきれなくなっておりその余りを使っています)。

GitHub ActionsもGitHub Pagesも無料枠で十分に収まります。API利用料はおそらく3年分ほどはあるはずですが、残高がなくなるとメールで通知が来るように設定はしてあります。

自動化された運用フロー

下記のすべてがGitHub Actions上で完結し、人間の介入なしに動き続けるので一度動き出せば基本的には手を入れる必要がありません(依存のmajor version upはマニュアルで対応が必要)。

  • 毎日自動収集
    • GitHub Actionsが毎日定時に実行され、新しいPRを自動収集
  • AI要約
    • 収集したPRをOpenAI GPT-5.1で自動要約
  • 重複チェック
    • 既に処理済みのPRは自動でスキップ
  • 静的サイト生成
    • VitePressでMarkdownから静的HTMLを生成
  • 自動デプロイ
    • GitHub Pagesへ自動デプロイ

依存関係の自動更新

Renovate Botを導入し、依存パッケージを毎週決まった曜日に自動更新するようにしています。セキュリティアラートがあれば即座にPRが作成されます。これにより、メンテナンスの手間も最小限に抑えられるはずです。

実際に使ってみて

実際にサイトを作ってから日々RailsにマージされているPRをチェックしていましたが様々な気づきが得られました。以下にいくつか興味深かったPRを挙げてみます。

#56350 Use a modern approach for cross-site request forgery protection

CSRF保護の実装が大きく変わる変更です。従来のauthenticity tokenを使う方式から、Sec-Fetch-Siteヘッダを使ったモダンな方式がRails 8.2のデフォルトになります。

具体的には、protect_from_forgery using: :header_onlyのように指定すると、ブラウザが送信するSec-Fetch-SiteヘッダだけでCSRF判定が行われます。レガシーブラウザ対応が必要な場合はusing: :header_or_legacy_tokenとすることで、ヘッダがない場合のみトークン方式にフォールバックできます。

さらに、OAuthコールバックのような正当なクロスサイトリクエストを許可するtrusted_originsオプションも追加されました。authenticity tokenを使わない方法が一般的になっていくのは知らなかったので、なるほど〜となりました。

#56345 Add SVG renderer

format.svg { render svg: @page }という形でSVGを第一級のレスポンス形式として扱えるようになりました。QRコードやダイナミックに生成する図表などを、JSONやXMLと同じように自然に扱えます。

class PagesController < ActionController::Base
  def show
    @page = Page.find(params[:id])
    respond_to do |format|
      format.html
      format.svg { render svg: @page }
    end
  end
end

レスポンス形式周りの機能が充実していくのは純粋に嬉しい変更です。あとはformat.pdfみたいな感じでPDF生成できるようになってくれたりしないかなとか思ったりしてました。現状だとsend_dataを使ってバイナリをレスポンスする必要がありちょっと自然じゃない感じがするので。

#56327 Active Storage: eager analysis and local file processing

Active Storageでprocess: :immediatelyを指定したバリアント付き添付ファイルについて、バリデーション時にメタデータ解析が即時実行されるようになりました。これにより、画像の幅や高さをバリデーションで使いたい場合に、明示的にanalyzeを呼ばなくても自動で解析されるようになります。

さらに、アップロード直後のローカルファイルを直接使って解析・変換を行うため、わざわざストレージからダウンロードし直す無駄がなくなりました。Active Storageのメタデータ取得周りの改善は地味ですが実務で嬉しい変更です。

#56332 Fix typo in comments: exisiting → existing

Active Recordのコメント内の「exisiting」を「existing」に修正しただけのPRです。コードの挙動には一切影響しませんが、codespellというツールで見つけたスペルミスを丁寧に直しています。

地味で初歩的なPRですが歴史あるRailsのようなメジャーなフレームワークでも、まだ誰でも貢献できそうな余地があることがわかります。

#56288 Add SecureRandom.base32

SecureRandom.base32が追加され、Crockford方式のBase32文字列を生成できるようになりました(ちなみにCrockford氏はJSONを作った人であり、かの有名な『JavaScript: The Good Parts』の著者です)。

SecureRandom.base32
SecureRandom.base32(10) # 桁数を指定できるっぽい

Crockford Base32は、大文字小文字を区別せず、人間が混同しやすい文字(I, L, O, U)を避けた設計になっています。2FAコードやマジックリンク用トークンなど、人が読んで打ち込む前提のコード生成に最適です。

そもそも恥ずかしながら自分はBASE32という符号化方式を初めて知りました。こういうRails以外の学びもあったりして便利です。

まとめ

Rails PR Digestは、Railsの最新動向を効率的にキャッチアップするために作ったサイトです。TypeScript + GitHub Actions + OpenAI GPT-5.1 + VitePressという構成で、毎日自動でPRを収集・要約し、整理して公開しています。

実際に運用してみて、Railsの変更内容を追いやすくなっただけでなく、関連する技術知識も学べる良いサイトになったと感じています。

また、このサイトはruby-jpRailsアップグレードガイドにも掲載していただきました(ありがとうございます!!)。

もしRailsを使っている方で最新動向が気になる方は、ぜひRails PR Digestを活用してみてください。

https://yuheinakasaka.github.io/rails-pr-digest/

最後に

GA technologiesではこうした簡単なWebサイトを作成する場合でもエンジニアリングの観点を持って構築できるソフトウェアエンジニアを求めています。もし興味があれば下記のリンク、もしくは私のXのアカウントまでご連絡ください。

https://ga-technologies-engineering.notion.site/GA-technologies-9794c78bc56c4011a03f7f3dcf91a18f

リンク

株式会社GA technologies

Discussion