有名テック企業の技術ブログを、ひとつのフィードで。
フィード
33件
はじめに こんにちは。freee請求書チームでエンジニアをやっているnuresenです。 この記事では、Rails 7系から8.1へのアップデートを Claude Code の Skills を使って実施した記録を紹介します。 みなさん、Railsのアップデートはできていますか? Railsは定期的に新しいバージョンがリリースされますが、大規模なプロダクトになるとキャッチアップするのもなかなか大変ですよね。 freee請求書では、現在のバージョンがEOLを迎える前にアップデートしていく方針をとっており、だいたい年に1、2回くらいの頻度でバージョンアップを実施しています。 今回は7系から8.0へのバージョンアップを予定していましたが、8.0のEOLが2026年11月に迫っていることを踏まえ、8.1まで一気に上げてしまうことにしました。 ただし、Railsガイドにも書いてあるように、アップデートはジャンプアップせずに1つずつ段階的に上げていくのが鉄則です。そのため、今回は 7系 → 8.0 → 8.1 と2段階に分けてアップデートすることにしました。 2回同じ作業を繰り返すこと、そして今後も定期的にアップデートが必要になることを考えると、この作業自体を仕組み化しておきたいところです。そこで Claude Code の Skills を活用して、できるだけ楽にアップデートできないかを試してみました。 今回はClaude Skillsについての詳細は説明していません。詳細が知りたい方はぜひ公式Docを参照してください。 アプローチ いきなり Skills を作るのではなく、まずは Claude Code で素朴に8.0へのアップグレードを一通りやってみることにしました。実際の作業ステップを体験しておかないと、どこを自動化すべきか判断できないためです。 手動で行った手順は以下のとおりです。 アップグレードガイド・リリースノートの確認 ナレッジページにある過去のアップグレードレポートを読む Gemfile の Rails バージョンを更新して bundle update rails を実行 依存関係で対応が必要な gem のリストアップと更新 ローカルで起動して動作することを確認 PoC の PR を作成して CI を回し、Claude Code にログを渡して失敗を解析 bin/rails app:update の実行と設定ファイルの差分確認 この一連の作業を Claude Code に任せてみたところ、1つの会話で最初から最後まで完了させるのは難しいことがわかりました。理由は大きく2つあります。 コンテキストの肥大化による精度低下 調査結果、bundle update のログ、CI の失敗ログなど大量の情報が積み重なると、LLM の注意力が分散して的確な判断ができなくなる 人間のレビューポイントが必要 gem の更新方針や設定ファイルの取捨選択など、プロダクト固有の判断が求められる場面では、AI に丸投げするのではなく各チェックポイントで人間が確認して責任を持つ必要がある そこで、上記の手順を5つのステップに分割し、それぞれを独立した Skill として定義することにしました。 また、各ステップでは成果物をマークダウン形式のドキュメントとして出力し、それが次のステップの入力になるパイプライン構造を採用しました。これにより、途中で作業を中断してやり直したり、セッションをリセットして別の会話から再開することも可能です。前のステップの成果物さえあればコンテキストを圧迫せずに次のステップを実行でき、LLM の精度を保ったまま作業を進めることができました。 実践編 ── 各ステップの概要 以下が今回作成した5つの Skill の概要です。各 Skill はターゲットバージョンを引数に取り、成果物としてマークダウンを出力します。 Skill実行例 /rails-upgrade-step1-research 8.0 Step 1: Research(調査) Skill定義イメージ --- name: rails-upgrade-step1-research description: 'Railsアップグレード調査フェーズ: リリースノート確認、既知の問題調査、ナレッジ収集' argument-hint: <target_version (例: 8.1)> allowed-tools: [Read, Write, Grep, Glob, WebFetch, WebSearch, AskUserQuestion] --- # rails-upgrade-step1-research ## ワークフロー ### Phase 1: 現在のバージョン確認 - `bundle show rails` で現在のRailsバージョンを確認 - `config/application.rb` の `config.load_defaults` を確認 ### Phase 2: リリースノート調査 WebSearch/WebFetchで以下を調査: - Rails公式リリースノート - Breaking Changes / Deprecations / Removals / New Features をカテゴリ別に整理 ### Phase 3: コミュニティナレッジ調査 - ruby-jpのナレッジページ - GitHubのissue/discussion ### Phase 4: 調査結果ドキュメント作成 リリースノートサマリー、依存gem対応状況、リスク評価をまとめる ## 成果物 出力先: `./ai_tasks/rails_upgrade/v{target_version}/01_research.md` ## 禁止事項 - ファイルの編集(調査ドキュメント作成以外) - コードの変更 - 依存関係の変更 アップグレードに必要な情報を収集し、影響範囲を把握するフェーズです。 主な処理内容 現在の Rails バージョンと config.load_defaults の確認 Rails 公式リリースノートの調査 Breaking Changes・Deprecations・Removals・New Features のカテゴリ別整理 コミュニティの既知の問題を調査(ruby-jp、GitHub Issues など) 依存 gem の Rails 対応状況の確認 リスク評価と推奨対応順序の策定 このステップではコードの変更は行わず、調査とドキュメント作成のみに制限しています。許可ツールを Read / WebSearch / WebFetch 等に絞り、Edit や Bash での変更操作を禁止することで、調査フェーズで誤ってコードを書き換えてしまうリスクをなくしています。 成果物: 01_research.md(リリースノートサマリー、依存 gem 対応状況、リスク評価) Step 2: Gemfile(依存関係解決) Skill定義イメージ --- name: rails-upgrade-step2-gemfile description: 'Railsアップグレード Gemfile更新フェーズ: 依存関係の解決とbundle update' argument-hint: <target_version (例: 8.1)> allowed-tools: [Read, Edit, Write, Grep, Glob, Bash(bundle *), Bash(git *), AskUserQuestion] --- # rails-upgrade-step2-gemfile ## 前提条件 - step1(調査フェーズ)が完了していること ## ワークフロー ### Phase 1: 前ステップの確認 - step1の調査ドキュメントを読み込む ### Phase 2: Gemfile の Rails バージョン更新 - Gemfile を編集: `gem 'rails', '~> {target_version}.0'` - `bundle install` を試行 ### Phase 3: 依存関係エラーの解決 1. エラーメッセージを解析 2. gemのGitHub/RubyGemsで対応バージョンを確認 3. Gemfileを更新 4. 再度 `bundle install` を試行 5. エラーが解消されるまで繰り返し ### Phase 4: bundle update 実行 - `bundle update rails` ### Phase 5: 変更内容の記録 - `git diff Gemfile.lock` で更新されたgemを確認・記録 ## 成果物 出力先: `./ai_tasks/rails_upgrade/v{target_version}/02_gemfile.md` ## 禁止事項 - step1の調査なしでの実行 - bundle installのエラーを無視した強制更新 - 依存関係解決の経緯を記録しないこと Gemfile の Rails バージョンを更新し、依存関係を解決するフェーズです。 主な処理内容 Step 1 の調査ドキュメントを読み込み Gemfile の Rails バージョン指定を更新 bundle install → エラー解析 → Gemfile 修正 → 再試行のループ 依存関係が解決したら bundle update rails を実行 git diff Gemfile.lock で更新された gem を記録 依存関係解決の経緯(どのエラーに対してどう対応したか)をすべて記録するようにしています。 bundle install のエラーを無視した強制更新も禁止しており、1つずつ原因を解消していくようにしています。 成果物: 02_gemfile.md(変更した gem の一覧、依存関係解決の経緯) Step 3: CI Analysis(CI 結果分析) Skill定義イメージ --- name: rails-upgrade-step3-ci description: 'Railsアップグレード CI結果分析フェーズ: CI結果を受け取り、失敗を分類・ドキュメント化' argument-hint: <target_version (例: 8.1)> allowed-tools: [Read, Edit, Write, Grep, Glob, AskUserQuestion] --- # rails-upgrade-step3-ci ## 前提条件 - step2(Gemfile更新)が完了していること - PR が作成済みで CI が実行されていること ## ワークフロー ### Phase 1: CI 結果の受け取り ユーザーに CI 結果の提供を依頼(PR番号、失敗ログ等) ### Phase 2: CI 結果の分析 失敗を以下のカテゴリに分類: 1. Rails変更による破壊的変更 2. 依存gemの変更 3. Deprecation警告 4. RuboCop違反 ### Phase 3: 修正方法の検討 - テストコードの修正が必要か - アプリケーションコードの修正が必要か - 設定変更で対応可能か ### Phase 4: 分析結果のドキュメント化 失敗分類レポートと修正タスク一覧を優先度別に整理 ## 成果物 出力先: `./ai_tasks/rails_upgrade/v{target_version}/03_ci_analysis.md` ## 禁止事項 - このステップで修正を実施すること(分析のみ) - 失敗の原因を調査せずに分類すること PR を作成して CI を回し、失敗を分類・ドキュメント化するフェーズです。 主な処理内容 ユーザーから CI 結果(失敗ログ)を受け取る 失敗を4つのカテゴリに分類 Rails 変更による破壊的変更(API変更、デフォルト値の変更など) 依存 gem の変更による挙動変更 Deprecation 警告(Rails / RSpec / 外部 gem 由来) RuboCop 違反(新しい cop、設定変更) 各失敗に対して関連コードを調査し、修正方法を検討 修正タスクを優先度別に整理 このステップではステップ1と同様に分析のみを行い、コードの修正は行いません。許可ツールから Bash や Edit を除外し、分析に専念させる設計です。「分析」と「修正」をあえて分離することで、修正方針について人間がレビューするポイントを自然に挟むことができます。 成果物: 03_ci_analysis.md(失敗分類レポート、修正タスク一覧) Step 4: Fix(修