6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PR ごとにプレビュー環境が立ち上がる CI/CD 構成を作った話

6
Posted at

はじめに

みなさん「タコス」食べていますか?

image.png

こんにちは、tacosDB 開発責任者です。

タコスが好きすぎてタコスに特化したサイト「tacos DB」を開発しています。

食べログなど既存のグルメサイトでよくない?と最初は私も思っていたのですが、場所や値段、評価で絞ることはできてもトルティーヤの種類や具材などで絞ることは既存のサービスでは叶いません。

私はコーントルティーヤで、チキンティンガ、ワカモレトッピングのタコスが好きなのですが、このタコスを提供するお店をピンポイントで探すことって結構難しいんですよね、、、

開発を進める中で、出先でもスマホからレビューできる環境が欲しいと思うようになり、 PR ごとにプレビュー環境が自動で立ち上がる仕組みを作りました!

この記事では、GitHub Actions と Cloudflare を使って構築した CI/CD の配備構成を紹介します。


技術スタック

領域 技術
Backend Rust
Frontend (Web) Astro
Frontend (CMS) Next.js
Infrastructure Cloudflare (Pages / Workers / R2 / D1 / Zero Trust / DNS / etc...) / Terraform / GitHub Actions

Cloudflare の構成

今回扱うのは次の 4 つです。dev / prod それぞれに同じ構成が 1 セットずつあります。

  • Cloudflare Pages — 公開 Web
  • Cloudflare Workers — API サーバー
  • Cloudflare D1 — 店舗・記事などのデータ
  • Cloudflare R2 — 画像

スクリーンショット 2026-05-31 23.06.28.png

実際には公開 Web と CMS のアプリが分かれていたり、API も用途ごとに分けていたりします。ディレクトリ構成は別の記事でまとめます。


dev と prod の出しどころを決める

最初に決めたのは「どのタイミングで、どこに配備するか」です。

  • develop へのマージ → 即時 dev へ配備
  • GitHub Release / tag の作成 → prod へ配備
  • 手動再配備 → workflow_dispatch で対応

本番は develop → main の release PR をマージし、GitHub Release が作られたタイミングで配備されます。バージョンはセマンティックバージョニングで管理し、PR につけたラベルに応じて patch / minor / major を自動インクリメントします。

手動再配備時は、migration はデフォルトで実行しない設計にしています(後述)。

on:
  push:
    branches:
      - develop
  release:
    types:
      - published
  workflow_dispatch:
    inputs:
      release_tag:
        description: "Release tag to deploy to prod (example: v0.1.0)"
        required: true
        type: string
      apply_migrations:
        description: "Apply remote D1 migrations before deploy"
        required: false
        default: false
        type: boolean

スクリーンショット 2026-05-31 23.16.46.png


PR ごとにプレビュー環境を作る

開発中に意外と手間だったのが画面のレビューです。コードを読めば変更内容は把握できますが、店舗一覧や CMS の入力画面は実際に開いて確認したほうが早い。

そこで、Web または CMS に差分がある PR では自動でプレビュー URL を生成し、PR コメントに貼り付けるようにしました。

差分検知

web_changed="false"
cms_changed="false"

while IFS= read -r file_path; do
  case "$file_path" in
    src/ts/tacos-web/*)
      web_changed="true"
      ;;
  esac

  case "$file_path" in
    src/ts/tacos-cms/*)
      cms_changed="true"
      ;;
  esac
done < /tmp/cloudflare-preview-changed.txt

Web のプレビュー(Cloudflare Pages)

- name: Deploy tacos-web preview to Pages
  working-directory: src/ts/tacos-web
  run: >
    npx --yes wrangler@${WRANGLER_VERSION}
    pages deploy dist
    --project-name "${WEB_PROJECT_NAME}"
    --branch "${WEB_BRANCH_ALIAS}"

CMS のプレビュー(Cloudflare Workers)

CMS 側は Workers の preview alias を使っています。

Backend と D1 は PR ごとに複製していません。 プレビューの主な用途は画面確認なので、dev 環境のバックエンドを共有する判断にしました。バックエンドは I/O と DB を検証する CI テストでカバーしています。この判断はアプリの規模や同時開発人数によって変わってくる部分だと思います。


D1 migration をいつ流すか

最も慎重に設計したのが D1 migration です。Web の再配備と違い、DB の変更は気軽に巻き戻せません。

ルール:

  • dev への通常配備 — migration ファイルに差分があれば適用する
  • prod への配備(Release 起点) — 常に適用する
  • 手動再配備(同一 tag) — デフォルトでは実行しない。必要なときだけ明示的にオンにする
if: >-
  ${{
    (
      needs.resolve-target.outputs.deploy_env == 'dev' &&
      needs.detect-changes.outputs.migration_changed == 'true'
    ) ||
    (
      needs.resolve-target.outputs.deploy_env == 'prod' &&
      needs.resolve-target.outputs.apply_migrations == 'true'
    )
  }}

適用は Wrangler の D1 migration コマンドで行います。

- name: Apply remote D1 migrations
  working-directory: src/rs/bo-neko-api-server
  run: >
    npx --yes wrangler@${WRANGLER_VERSION}
    d1 migrations apply ITEM_DB
    --remote
    --config wrangler.client-api.generated.toml

機能開発より先に migration の運用方針を決めておいたことは正解でした。後から「schema が変わるアプリ」として考えるより、最初から設計に組み込んだほうが安心して開発を進められます。


Terraform と GitHub Actions の分担

担当 役割
Terraform Pages project / D1 / R2 / ドメインなど、インフラの土台
GitHub Actions コード変更に伴う build / deploy

「土台はコードで管理、アプリを届ける部分は自動化」という分担です。


おわりに

この CI/CD 構成を整備したことで、開発開始から約 2 週間で dev / prod にデプロイできる状態まで持っていけました。早い段階でパイプラインを固めておくと、その後の開発リズムが格段に上がります。


リリースした tacos DB はまだ掲載店舗数が少ないのが課題です。

  • 店舗情報・写真・紹介文を提供してくれる方
  • タコスが好きで一緒に整えてくれる方

を募集しています!知っているお店があれば、ぜひお問い合わせフォームから投稿してください 🌮

スクリーンショット 2026-05-31 23.17.16.png

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?