今最もクールな ブルーグラスサイトとして 注目されているのが Bluemoon だ
新システム構想(#212)に基づき、Astro + Content Collectionsで構築中。
src/
├── pages/
│ ├── index.astro # トップページ
│ └── events/[slug].astro # 年度イベントページ(コンテンツコレクションから生成)
├── content/events/ # 年度ごとのイベント内容(Markdown/MDX)
├── layouts/ # BaseLayout / EventLayout
├── components/ # SiteNav, InfoCard, ScheduleTable 等
├── assets/ # ビルド時最適化される画像
└── styles/global.css
public/ # そのまま配信される静的ファイル(favicon等)
本番はCloudflare Workers Static AssetsのWorker bluemoonから、src/のAstroビルド成果物(dist/)を配信します。
npm install
npm run dev # http://localhost:4321 でプレビュー
npm run check # 型・テンプレートチェック
npm run build # dist/ に静的ビルド
npm run preview # ビルド結果をローカルで確認新しい年度イベントページを追加する場合は src/content/events/ に .mdx ファイルを1つ追加するだけで /events/<slug> に自動生成されます。
https://www.bluemoon.works/admin/ にSveltia CMSを配置しています。events / news / pages コレクションを管理でき、GitHub OAuthでログインして変更をGitHubリポジトリへcommitします。
CMSの書き込み先は cms-drafts ブランチです。公開操作があると .github/workflows/cms-publish.yml が検証(npm run check / npm run build / 変更パスがコンテンツパスのみか検査)後にmainへ自動マージし、main ブランチのデプロイCIが本番へ反映します。このため、編集担当者はブランチやPRを意識せずに公開できます。
cms-drafts への変更は コンテンツパス(src/content/** / src/assets/events/** / public/images/**)のみが公開フローを通ります。それ以外のパス(コード・設定等)の変更が含まれるpushは公開ワークフローが失敗し、本番には反映されません(GitHub Freeではルールセットのパス制限が使えないため、CI層で検査しています。ブランチの削除・force-pushはルールセットで禁止)。コード変更はこれまでどおりPR経由です。
- CMS設定:
public/admin/config.yml - CMS本体:
public/admin/index.html(CDNから読み込み) - OAuth Worker:
workers/sveltia-cms-auth/(GitHubログイン処理用)
編集者のアカウントを追加するには、GitHubでリポジトリ azumag/bluemoon にそのユーザーを collaborator として追加してください。
編集者向けの更新手順は docs/editors-manual.md を参照してください。
cms-publish.yml がmainへマージするには、以下のActions Secretが必要です。mainのルールセット(copilot review)をバイパスできる権限が必要なため、GitHub App(例: bluemoon-cms-bot)を使用します(PATは2025年以降のGitHub仕様でルールセットをバイパスできません)。
- GitHub App作成(Webhook無効、Permissions: Contents → Read and write、対象リポジトリ
azumag/bluemoonのみ)し、リポジトリへインストール - リポジトリのルールセット「copilot review」のバイパスリストにそのAppを追加(設定済み)
- Secretsに登録:
CMS_APP_ID: GitHub AppのApp IDCMS_APP_PRIVATE_KEY: GitHub Appのprivate key(PEMの全文)
- eventsのヒーロー画像:
src/assets/events/にアップロードされ、Astroで最適化されます - news/pages本文の画像:
public/images/にアップロードされ、/images/...として配信されます
public/images/ が存在しない場合は空の .gitkeep を置いてください。
mainブランチにpushすると、.github/workflows/main.ymlが次の順で実行され、Cloudflare Workersのbluemoon(本番)とsveltia-cms-auth(CMS認証)へデプロイします。
npm ci → npm run check → npm run build → wrangler deploy (bluemoon)
→ wrangler deploy (sveltia-cms-auth)
sveltia-cms-auth Workerの初回セットアップ:
- GitHubの
https://github.com/settings/applications/newでOAuthアプリを登録。Authorization callback URLはhttps://sveltia-cms-auth.tsubasa-azumagakito.workers.dev/callback - 発行されたClient ID / SecretをCloudflare Workersダッシュボード(
sveltia-cms-auth→ Settings → Variables)へ設定GITHUB_CLIENT_ID(通常変数)GITHUB_CLIENT_SECRET(Encrypt)ALLOWED_DOMAINS:localhost:4321, www.bluemoon.works(必須。認証エンドポイントの開放ドメインを制限するため。未設定だとCMSの認証が任意サイトから利用できてしまう)
初回だけ、GitHubリポジトリのActions SecretにCLOUDFLARE_API_TOKENを登録してください。Cloudflareダッシュボードで**アカウントレベル(全Workerスクリプト)**のデプロイ権限を許可したAPIトークンを作成します。bluemoonとsveltia-cms-authの両方にデプロイするため、特定スクリプト名限定のトークンではsveltia-cms-authのデプロイが失敗します。値をGitHubのSettings → Secrets and variables → Actionsに保存します。アカウントIDはwrangler.tomlのaccount_idを使用します。
ローカルからデプロイする場合は、Cloudflare OAuthログイン済みの環境で次を実行します。
npm ci
npm run check
npm run build
wrangler deployPull Requestを作成または更新すると、.github/workflows/pr-preview.ymlがPR番号ごとにbluemoon-pr-<番号>というWorkerを作成し、workers.devのプレビューURLをPRへコメントします。PRをクローズすると、そのプレビューWorkerを削除します。