本文へ移動
BenriWorks Lab

開発記事公開日

Codex と GitHub と Vercel で、Webアプリを公開するまでの流れ

机の上の2台のモニターにプルリクエストの画面とデプロイの一覧を映し、こちらを向いて座っている女性の開発者

Codex で書き、GitHub でレビューし、Vercel で公開する。BenriWorks のWebアプリ開発の流れを、実際のリポジトリに置いてある運用ルール、CIの門、リリース手順から記録します。動くことと公開してよいことの間に何を置いているかが主題です

プルリクエストをマージすると公開される。BenriWorksのWebアプリは、すべてこの一文で動いています。Codex がコードを書き、GitHub でレビューし、Vercel が本番へ出す。道具は3つで、手順書は要りません。

それなら、AIに「作って」と言えばアプリが公開されるのか。公開はされます。問題はその先で、動いているものと、公開してよいものは同じではありません。この記事は、その2つのあいだに何を置いているかの記録です。

3つの道具の受け持ち

Codex は、OpenAIのコーディングエージェントです。公式ドキュメントによれば、作業を始める前にリポジトリの AGENTS.md を読み、そこに書かれた規約と検査コマンドに従います。ローカルではOSが強制するサンドボックスの中で動き、書き込める範囲と、止まって承認を求める条件を設定で決めます。既定のプリセットでは、作業ディレクトリの中の編集とコマンド実行を自動で行い、それを越える操作で承認を求めます。クラウド版では、タスクごとにコンテナを立ててリポジトリを指定ブランチで取り出し、セットアップスクリプトを走らせてから作業し、終わるとプルリクエストを開けます。

GitHub は、レビューとマージの場所です。Codex のクラウド版をリポジトリに接続すると、プルリクエストのコメントに「@codex review」と書くだけでレビューが走ります。公式ドキュメントは、GitHub上ではP0とP1の問題だけを指摘すること、AGENTS.md にレビュー方針を書けばそれに従うことを説明しています。

Vercel は、公開の場所です。ブランチをプッシュすれば Preview 環境が立ち、main へマージすれば Production へ出ます。プロジェクトごとに環境変数を Preview と Production で分けて持てるので、本番の鍵を Preview に渡さない構成が作れます。BenriWorksでは、アクセス解析のタグを本番デプロイでだけ描画する判定にもこの環境の区別を使っています。

道具の説明はここまでです。ここから先が、道具では決まらない部分です。

Issue から PR までの型

高圧受電設備の単線結線図ジェネレータのリポジトリには、貢献ガイドがあります。書き出しはこうです。「ローカルの Codex から GitHub Issue を起点に実装し、GitHub Pull Request でレビューし、問題がなければリモート側でマージする進め方を標準とする。」

型は単純です。Issue を1つ選ぶ。main を最新にして、codex/issue-番号-短い説明 の形のブランチを切る。ローカルで実装し、テストとビルドを通し、画面を確認する。設計に触れたなら構成ドキュメントを更新する。プッシュしてプルリクエストを作り、CIと Preview とレビューを見て、GitHub上でマージする。

1 Issue に1 PRが原則で、広すぎるなら先に Issue を割ります。AI探偵のリポジトリでは、同じ型を Codex 向けの AGENTS.md に書いています。そこには、検証が実行できなかったときは最終報告とPRにその理由を書くこと、UIの変更があれば影響とレビュー方法を要約することも含まれています。検証できなかったことを、検証したことと区別して書く。この一行が、AIに書かせるときの要になります。

Issueから本番公開までの流れ図。Issueを起点にcodexブランチを切り、ローカルでテストとビルドを通し、プルリクエストでCIとPreview環境とレビューを通り、マージするとVercelのProductionへ出る。CIとレビューの位置に門の印がある
道具は3つ。門はCIとレビューの2か所で、どちらも人が設定を決める

CIという門

門の中身はリポジトリごとに違います。共通しているのは、AIが「通りました」と言うのではなく、機械が判定することです。

wavelaneのCIは、依存関係の再構築、層の境界ルールを含む lint、型検査、受入条件と対応づけたテスト、そして環境変数なしでもビルドが通ることの確認を順に走らせます。最後のひとつは、鍵が未設定のときに販売機能が閉じたままビルドできることを保証するためのものです。そのあとにページごとのメタデータ検査と、実ブラウザでの主要導線の確認が続きます。

AI探偵では、リリース前の検査を1本のコマンドにまとめています。lint、型検査、単体テスト、ビルド、図の描画確認、E2E、性能検査の順です。性能はモバイルの LCP が2,500ミリ秒以下、CLS が0.02未満を3回の中央値で判定し、Issue ごとのQA表に実測値と合否を残します。2026年7月の表では、Playwright が27件、Vitest が128件で、LCP は1,946.9ミリ秒でした。

白地図 Studio には、ドキュメントの検査まで入っています。README と docs 配下の Markdown について、コードフェンスが閉じているか、相対リンク先が実在するかを機械で確認します。遠隔巡視のシミュレータでは、要件書のSHA-256を実装状況ドキュメントに記録し、要件書を書き換えたら指紋も更新しなければテストが落ちます。

どれも派手ではありません。ただ、AIが書いた変更が門を通ったかどうかを、AIの自己申告と切り離して判定できます。

「動く」と「公開してよい」のあいだ

wavelaneの初回有料リリースの計画書は、状態を4つに分けています。ローカル実装、統合検証、外部設定、Production確認です。リポジトリにコードが入った状態と、lint と型検査とテストとビルドとブラウザ確認を同じ変更集合で通した状態と、Stripe や Redis や署名鍵を対象環境へ設定した状態と、公開URLで決済からPro認証まで通した状態は、それぞれ別の状態として扱います。計画書はこう続けます。「ローカル実装の完了だけを『公開済み』と扱わない。」

この区別が効いたのは、リリース検証の場面です。verify:release というコマンドは、ローカルの契約、問題40件すべてのレビュー記録、鍵ペアを検証し、Stripe のAPIでは価格と決済リンクの一覧を読むだけで外部の状態を変えません。これが通ったビルドだけを Production へ出す。通らなければ購入ボタンは表示されず、決済APIも403を返します。運用手順書には「verify:release のエラーを一時的なフラグ変更やダミー値で回避しない」と書いてあります。

2026年7月21日の検証記録には、この段で見つかったものが残っています。問題の全パラメータ組み合わせ762,824組を独立した式で再計算したところ、通常の出題範囲では現れない5択の表示値重複が2件見つかり、出題条件を直しました。動いていたコードです。動いていて、正しくなかった。

リリースまでの4つの状態を並べた図。ローカル実装、統合検証、外部設定、Production確認の順に、それぞれ何をもって完了とするかが添えられている。最後の状態だけが公開済みと呼べる
コードが入っただけでは1段目。公開済みと呼べるのは4段目だけ

状態を仕様書に外部化する

wavelaneのローンチ計画書の原則に、こう書いてあります。「状態は§10に外部化する。決定事項は理由込みで記録。会話やCodexセッションの記憶に依存しない。」

AIのセッションは終わります。次のセッションは前の会話を覚えていません。そこで、決めたことと決めた理由と、いまどこまで終わっているかを、リポジトリのMarkdownに書きます。インフラの手順書には、共用データベースで論理分離を選んだ理由や、環境変数を Vercel の環境スコープで分ける決定が、日付と根拠つきで並んでいます。

同じ手順書には、Codex への委譲もそのまま書いてあります。「リポジトリ内の process.env. 参照を全て grep し、変数名、用途、参照ファイルの表を出せ」という一行です。棚卸しのように、正確さが要って判断が要らない仕事は、こう切り出して渡します。逆に、ドメインの本文や仕様の判断は運営者が持ち、整形と組み込みだけを Codex に回す。ローンチ計画書はその線引きを明記しています。

案内役の女性がクリップボードを持って立っているバナー。「マージすれば公開。それで足りますか」「「動く」と「公開してよい」の間に置いたもの」というコピーが入っている

本番でしか見つからないもの

門を通しても、本番でだけ壊れるものはあります。9月上旬に16サイトへアクセス解析を入れたとき、3サイトで計測が届きませんでした。原因はテンプレート文字列のエスケープ落ちと、本番のHTTPヘッダーだけに付いていたCSPでした。どちらもビルドは通っていました。経緯は「Claude Fable 5.1 で13リポジトリにGA4を入れた記録」にあります。

Vercel 固有の落とし穴も、運用の中で拾ってきました。プロジェクトには *.vercel.app の既定ドメインが残り続けるので、そちらには noindex を返す設定を vercel.json に置いています。ドメイン移転の転送は、ダッシュボードの既定である307ではなく恒久の308を選ばないと検索エンジンの評価が引き継がれません。こうした項目は、どれも「動く」の外側にあります。

マージすれば公開される、の続き

冒頭の一文に戻ると、マージすれば公開されるのは本当です。Codex が書き、CIが判定し、Preview で見て、マージして、Vercel が出す。この流れ自体は、AIに「作って」と言うのと変わりません。

違うのは、流れの途中に置いたものです。Issue を1つに絞る型、AIの自己申告を通さない門、コードが入った状態と公開してよい状態を分ける4段、決めた理由を残す仕様書。どれもAIが要求したものではなく、人が置いたものです。置かなければ流れはもっと速く、たぶんもっと多くのものが本番で見つかります。

Androidアプリでは、この「本番」が電車の中になります。そちらは「Codex の導入から、Android 測定アプリが実乗車で動くまで」に続きます。

参照した公式情報

  • OpenAI「Codex CLI」「Custom instructions with AGENTS.md」「Agent approvals & security」「Sandbox」「Codex cloud」「Cloud environments」「Review GitHub pull requests with Codex」(developers.openai.com/codex、2026年9月時点)
  • BenriWorks 各リポジトリの CONTRIBUTING.md、AGENTS.md、CI設定、リリース計画書、運用手順書、検証記録

関連アプリ

こんな記事も読まれています