terada_life

rpn 自動デプロイ — 実装タスク一覧

設計書: 自動デプロイの仕組み.md


事前確認タスク(リードタイムあり)

相手の返答待ちや環境準備で待ちが発生するタスク。Phase 1 の作業と並行して早めに着手する。

#タスク確認先想定リードタイム状態
P-1CLサーバーFTP情報のヒアリングセーズ様数日〜1週間[ ]
P-2CLサーバーのFTP接続方式・制限の確認セーズ様P-1と同時[ ]
P-3CLサーバーのディレクトリ構成確認セーズ様P-1と同時[ ]
P-4GitHub リポジトリの権限確認自社即日〜1日[ ]
P-5GHA利用プラン・制限の確認自社即日[ ]

タスク一覧

Phase 1: 自社サーバーで検証

#タスク依存状態
1リポジトリ構成の整備P-4[ ]
2GitHub Secrets の設定P-4[ ]
3FTPS疎通確認2[ ]
4deploy-schedule.json 初期ファイル作成1[ ]
5Workflow 1: schedule-deploy.yml 実装1, 4[ ]
6Workflow 1 動作テスト5[ ]
7deploy-config.json サンプル作成1[ ]
8テスト用ビルド成果物の配置7[ ]
9Workflow 2: deploy-cron.yml 実装5, 7[ ]
10Workflow 2 動作テスト3, 8, 9[ ]
11E2Eテスト10[ ]
12リダイレクトファイルの作成・配置確認10[ ]

Phase 2: クライアント実サーバーへの適用

#タスク依存状態
14GitHub Secrets の切り替えP-1, P-2[ ]
15クライアントサーバーFTPS疎通確認14[ ]
16実案件でのE2Eテスト15, P-3[ ]
17本番運用リハーサル16[ ]
18運用引き渡し17[ ]

事前確認タスク 詳細


P-1. CLサーバーFTP情報のヒアリング

目的: Phase 2 で必要なFTP接続情報を早めに入手する。

セーズ様に依頼する内容

  • FTPホスト名
  • FTPアカウント
  • FTPパスワード
  • テスト用に使ってよいディレクトリパス(本番パスとは別)

ポイント

  • パスワードは平文メール・チャットで送らない。パスワード管理ツール等で共有してもらう
  • 「まずテスト用パスだけでOK、本番パスは後で」と伝えると先方の対応が早い

完了条件: FTPホスト名・アカウント・パスワードが揃っている


P-2. CLサーバーのFTP接続方式・制限の確認

目的: Workflowの接続設定を事前に確定させる。

セーズ様に確認する内容

  • FTP接続方式(FTP / FTPS / SFTP)
  • IP制限の有無(GHAのIPレンジを許可する必要があるか)
  • パッシブモードの対応状況
  • 同時接続数の制限

ポイント

  • IP制限がある場合、GHAはIPが不定のため対応が複雑になる。その場合は別のアプローチ(セルフホストランナー等)の検討が必要
  • P-1と同じタイミングでまとめて聞くのが効率的

完了条件: 接続方式とネットワーク制限が明確になっている


P-3. CLサーバーのディレクトリ構成確認

目的: deploy-config.json の remote_path を正確に設定するための情報を得る。

セーズ様に確認する内容

  • FTPログイン時のルートディレクトリ(ドキュメントルートとの対応関係)
  • 既存のディレクトリ構成(/202604/21_FB/ 等が既に存在するか、GHAで作成してよいか)
  • rpnファイル以外に同ディレクトリに存在するファイル(mirror --delete で消してはいけないファイルの有無)

ポイント

  • mirror --delete はリモート側の余分なファイルを削除する。rpn以外のファイルが同階層にある場合、削除してしまう危険がある
  • 必要に応じて --delete を外すか、アップロード先をrpn専用ディレクトリに限定する

完了条件: リモートパスの構成と、削除可否の方針が決まっている


P-4. GitHub リポジトリの権限確認

目的: Secrets設定やGHA実行に必要な権限があることを確認する。

確認内容

  • リポジトリの Admin 権限を持っているか(Secrets設定に必要)
  • GitHub Actions が有効になっているか
  • デフォルトの Workflow permissions が Read and write になっているか
    • Settings → Actions → General → Workflow permissions

完了条件: Admin権限あり、GHA有効、Workflow permissionsがRead and write


P-5. GHA利用プラン・制限の確認

目的: GHAの実行制限を事前に把握する。

確認内容

  • リポジトリがPublic / Privateか(Privateの場合、月2,000分の無料枠制限あり)
  • Publicリポジトリならコードが公開されるため、Private前提か確認

ポイント

  • リリースは月1回のため、常時cronを回す必要はない
  • 運用方式の選択肢:
    • 方式A(推奨): リリース日の前日〜当日だけcronを有効化(Workflowファイルのcron行をコメントアウト/解除で切替)
    • 方式B: cronは使わず、リリース時刻に手動でworkflow_dispatch実行(最もシンプル)
    • 方式C: cronを常時有効にするが間隔を長め(1時間等)にする
  • 方式A or Bなら無料枠への影響はほぼゼロ

完了条件: リポジトリの公開設定と、cron運用方式が確定している


Phase 1: 自社サーバーで検証

自社サーバー(snowy-saga-5200.pigboat.jp / ftp.lolipop.jp)で仕組み全体を検証する。


1. リポジトリ構成の整備

目的: GHA Workflowとビルド成果物を格納するディレクトリ構造を作る。

やること

  • 以下のディレクトリ・ファイルを作成してコミット
builds/.gitkeep
.github/workflows/       # Workflow配置先(この時点では空)
deploy-schedule.json     # タスク4で作成

ポイント

  • builds/.gitignore に入れない(ビルド成果物をコミットで管理するため)
  • node_modules/, .next/, out/.gitignore に入っていることを確認

完了条件: builds/.github/workflows/ がリポジトリに存在する


2. GitHub Secrets の設定

目的: FTP接続情報をリポジトリのSecretsに登録する。

やること

  • リポジトリの Settings → Secrets and variables → Actions で以下を登録
Secret名値(自社テスト用)
FTP_SERVERftp.lolipop.jp
FTP_USERNAME自社FTPアカウント
FTP_PASSWORD自社FTPパスワード

注意点

  • クレデンシャルは絶対にコードにハードコードしない
  • Phase 2でクライアント情報に差し替えるか、GitHub Environments で分離する

完了条件: Secrets 3つが登録済み


3. FTPS疎通確認

目的: GHAからFTPSでアップロードできることを、まずローカルで確認する。

やること

  • ローカルに lftp をインストールして接続テスト
# macOS
brew install lftp

# 接続テスト
lftp -c "
  set ftp:ssl-allow yes
  set ftp:ssl-force yes
  set ssl:verify-certificate no
  open -u <FTPアカウント>,<FTPパスワード> ftp.lolipop.jp
  ls
  bye
"

ポイント

  • ロリポップはFTPS対応。ssl:verify-certificate no が必要な場合がある
  • ファイル一覧が取得できればOK
  • テスト用ディレクトリへの書き込みも試す(mkdir test-deploy && rmdir test-deploy

完了条件: lftpでFTPS接続・ファイル一覧取得・書き込みが成功


4. deploy-schedule.json 初期ファイル作成

目的: デプロイ予約管理ファイルの初期状態を作成する。

やること

  • ルートに deploy-schedule.json を作成
[]

完了条件: 空配列の deploy-schedule.json がコミットされている


5. Workflow 1: schedule-deploy.yml 実装

目的: workflow_dispatchでデプロイ予約を登録するWorkflowを作る。

やること

  • .github/workflows/schedule-deploy.yml を作成
  • 設計書「5. アーキテクチャ > Workflow 1」のサンプルコードをベースに実装

入力パラメータ

  • project_name: 案件名(builds/ 配下のフォルダ名)
  • deploy_datetime: デプロイ日時(JST、YYYY-MM-DD HH:MM 形式)

処理内容

  1. 入力バリデーション(フォルダ存在、deploy-config.json 存在、日時フォーマット)
  2. deploy-schedule.json にエントリ追加(jq使用)
  3. コミット&プッシュ

注意点

  • jq はubuntu-latestにプリインストール済み
  • git push のために contents: write パーミッションが必要(デフォルトで付与)
  • ISO 8601形式への変換: YYYY-MM-DD HH:MMYYYY-MM-DDTHH:MM:00+09:00

完了条件: Workflowファイルがコミットされている


6. Workflow 1 動作テスト

目的: 予約登録Workflowが正しく動作することを確認する。

やること

  1. テスト用のビルド成果物フォルダ + deploy-config.json を先に配置(タスク7, 8を先行してもOK)
  2. GitHub → Actions → "デプロイ予約登録" → "Run workflow"
  3. 以下を入力して実行:
    • project_name: テスト用案件名
    • deploy_datetime: 適当な未来日時
  4. 実行ログを確認

確認項目

  • Workflowが正常終了する
  • deploy-schedule.jsonpending エントリが追加されている
  • バリデーション失敗のケースでエラーになる(存在しないフォルダ名を入力)

完了条件: 正常系・異常系の両方が期待通り動作


7. deploy-config.json サンプル作成

目的: テスト用の案件デプロイ設定ファイルを作成する。

やること

  • builds/test-project/deploy-config.json を作成
{
  "project_name": "test-project",
  "deployments": [
    {
      "description": "テストページ",
      "local_dir": "rpn",
      "remote_path": "/test-deploy/rpn/"
    }
  ]
}

ポイント

  • まずは1パスだけで最小限のテスト
  • remote_path は自社サーバー上のテスト用ディレクトリを指定
  • 本番のパス(/202604/21_FB/...)は後のE2Eテストで使う

完了条件: builds/test-project/deploy-config.json がコミットされている


8. テスト用ビルド成果物の配置

目的: FTPアップロードテスト用のファイルを配置する。

やること

  • テスト用のビルドを実行するか、簡易的なHTMLファイルを配置
# 簡易テスト(ビルドせずにダミーファイルで確認する場合)
mkdir -p builds/test-project/rpn
echo '<html><body><h1>deploy test</h1></body></html>' > builds/test-project/rpn/index.html
# 実際のビルドで確認する場合
export BASE_PATH=/test-deploy/rpn
export NEXT_PUBLIC_BASE_PATH=/test-deploy/rpn
npm run build
cp -r out/ builds/test-project/rpn/

ポイント

  • 最初はダミーHTMLで仕組みの検証に集中する
  • 実際のNext.jsビルドのテストは後回しでOK

完了条件: builds/test-project/rpn/ にアップロード対象ファイルが存在


9. Workflow 2: deploy.yml 実装

目的: 予約時刻に達した案件をFTPアップロードするWorkflowを作る。

やること

  • .github/workflows/deploy.yml を作成
  • 設計書「5. アーキテクチャ > Workflow 2」のサンプルコードをベースに実装

トリガー方式(月1回リリースに最適化)

  • workflow_dispatch(手動実行)を主トリガーとする
  • cron(schedule)はオプション。リリース日前後だけ有効化する運用でもOK
  • 普段はリリース時刻に手動dispatchで十分

処理内容

  1. deploy-schedule.json から pending かつ時刻到達のエントリを検出
  2. 該当案件の deploy-config.json を読み取り
  3. lftp でFTPS経由アップロード(各デプロイ先をループ)
  4. ステータスを deployed / failed に更新
  5. コミット&プッシュ

注意点

  • lftpsudo apt-get install -y lftp でインストール(ubuntu-latestにはない)
  • cronを使う場合、*/15 * * * * はUTC基準。GHAのcronは遅延あり(最大15〜30分)
  • mirror --reverse はローカル→リモートへのアップロード。--delete でリモート側の不要ファイル削除

完了条件: Workflowファイルがコミットされている


10. Workflow 2 動作テスト

目的: FTPアップロードが正しく動作することを確認する。

やること

  1. deploy-schedule.json に過去日時の pending エントリを手動で追加してコミット
  2. GitHub → Actions → "デプロイ実行" → "Run workflow"(手動実行)
  3. 実行ログを確認
  4. FTPサーバー上にファイルがアップロードされているか確認

確認項目

  • Workflowが正常終了する
  • FTPサーバーにファイルが配置されている
  • deploy-schedule.json のステータスが deployed に更新されている
  • ブラウザで http://snowy-saga-5200.pigboat.jp/test-deploy/rpn/ にアクセスして表示確認
  • 対象なしの場合はスキップされる

完了条件: FTPアップロード+ステータス更新+ブラウザ確認が成功


11. E2Eテスト

目的: 予約登録 → デプロイ実行 → FTP確認の一連の流れを通しで確認する。

やること

  1. deploy-config.json に複数パスのデプロイ先を設定(本番に近い構成)
{
  "project_name": "test-multi",
  "deployments": [
    {
      "description": "パターン0",
      "local_dir": "pattern_0",
      "remote_path": "/test-deploy/0/rpn/"
    },
    {
      "description": "パターン4",
      "local_dir": "pattern_4",
      "remote_path": "/test-deploy/4/rpn/"
    },
    {
      "description": "共通",
      "local_dir": "rpn",
      "remote_path": "/test-deploy/rpn/"
    }
  ]
}
  1. 各パスにビルド成果物(またはダミーHTML)を配置
  2. Workflow 1 でデプロイ予約
  3. Workflow 2 を手動dispatch → デプロイ実行
  4. 全パスにファイルが配置されたか確認

確認項目

  • 複数パスへのデプロイが全て成功
  • 各URLでページが表示される
  • ステータスが正しく更新される

完了条件: 複数パスの予約デプロイが一連の流れで成功


12. リダイレクトファイルの作成・配置確認

目的: リダイレクト用HTMLの作成方法を確立し、正しくリダイレクトされることを確認する。

やること

  • リダイレクト用HTMLテンプレートを作成
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="refresh" content="0; url=/202604/21_FB/0/rpn/">
  <link rel="canonical" href="/202604/21_FB/0/rpn/">
</head>
<body>
  <p>リダイレクト中... <a href="/202604/21_FB/0/rpn/">こちら</a></p>
</body>
</html>
  • deploy-config.json にリダイレクト先も含めて設定
  • デプロイ後、リダイレクト元URLにアクセスしてリダイレクトされるか確認

注意点

  • meta refresh はサーバー設定不要で確実に動く
  • .htaccess が使えるならサーバーサイドリダイレクト(301)の方がSEO的に良い
  • ロリポップは .htaccess 対応しているので、要件に応じて選択

完了条件: リダイレクト元URLにアクセスすると、rpnページにリダイレクトされる


Phase 2: クライアント実サーバーへの適用

Phase 1完了後、セーズ様の本番サーバーへ切り替える。 事前確認タスク(P-1〜P-3)が完了していることが前提。


14. GitHub Secrets の切り替え

目的: FTP接続先をクライアントサーバーに切り替える。

やること

  • 方式を選択:
    • 方式A(簡易): 既存のSecretsを上書き
    • 方式B(推奨): GitHub Environments で staging(自社)と production(CL)を分離
  • 方式Bの場合: Workflowで environment を指定するよう修正

完了条件: Secrets がクライアントサーバー情報に切り替わっている


15. クライアントサーバーFTPS疎通確認

目的: クライアントサーバーへのFTPS接続を確認する。

やること

  • タスク3と同じ手順で、クライアントサーバーに対して疎通確認
  • テスト用ディレクトリへの書き込みテスト
  • GHAからの接続テスト(Workflow 2を手動dispatch)

注意点

  • FTP接続方式がFTPSでない可能性もある。接続方式に応じてWorkflowの lftp 設定を調整
  • ファイアウォールやIP制限がある場合、GHAのIP範囲を許可する必要がある

完了条件: GHAからクライアントサーバーへのFTPアップロードが成功


16. 実案件でのE2Eテスト

目的: 実際のrpn案件のビルド成果物を使ってE2Eテストを行う。

やること

  1. 実際のNext.jsプロジェクトで BASE_PATH を切り替えてビルド
  2. builds/{案件名}/ に各パスのビルド成果物を配置
  3. deploy-config.json に本番のパス構成を設定
  4. テスト用の日時でデプロイ予約
  5. デプロイ結果を確認

確認項目

  • 全パスにビルド成果物が正しくアップロードされている
  • 各URLでLPが正しく表示される(画像・CSS・JSが読み込まれる)
  • リダイレクトが正しく動作する
  • BASE_PATH が正しく反映されている(アセットのパスが正しい)

完了条件: 実案件のビルド成果物が本番パスで正しく表示される


17. 本番運用リハーサル

目的: 実際の運用フローを本番同様にリハーサルする。

やること

  1. 新規案件を想定し、以下の一連の流れを実施:
    • ビルド(全パス)
    • 成果物配置+deploy-config.json作成
    • コミット&プッシュ
    • 予約登録(翌日の指定時刻等)
    • cron実行を待って自動デプロイ確認
  2. 予約キャンセルのテスト
  3. デプロイ失敗時の対応手順確認

完了条件: 運用フロー全体が問題なく完了。想定外の事象がなければ本番運用開始


18. 運用引き渡し

目的: 運用担当者(自分含む)が迷わず使えるようにする。

やること

  • 設計書(自動デプロイの仕組み.md)の最終更新(Phase 2で変わった内容の反映)
  • 運用手順のチェックリスト化(ビルド→配置→予約の流れ)
  • トラブルシューティングの記載(よくある失敗パターンと対処法)

完了条件: ドキュメントが最新状態で、第三者が読んで運用できるレベル


作成日時: 2026/03/26