File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1818 steps :
1919 - uses : actions/checkout@v4
2020
21+ # 管理画面に表示するビルド番号(JSTの日時 + 短縮コミットハッシュ)。
22+ # 本番で動いているイメージがいつのどのコミットのものかを画面から確認できるようにする
23+ - id : build_number
24+ run : |
25+ echo "value=$(TZ=Asia/Tokyo date +'%Y%m%d-%H%M')-$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
26+
2127 # arm64イメージをamd64ランナー上でビルドするためのQEMUエミュレーション
2228 - uses : docker/setup-qemu-action@v3
2329
4753 # 本番ホスト(arm64)とローカル検証用(amd64)のマルチアーキビルド。
4854 # arm64側はQEMUエミュレーションのためビルド時間が長い
4955 platforms : linux/amd64,linux/arm64
56+ build-args : |
57+ BUILD_NUMBER=${{ steps.build_number.outputs.value }}
5058 tags : ${{ steps.meta.outputs.tags }}
5159 labels : ${{ steps.meta.outputs.labels }}
5260 cache-from : type=gha
Original file line number Diff line number Diff line change @@ -44,6 +44,10 @@ NextAuthではなく自前実装。`lib/auth/session.ts`がHMAC-SHA256で署名
4444
4545manifest(` app/manifest.ts ` 、Next.jsのMetadata Files規約で` /manifest.webmanifest ` として配信)+アイコン(` public/icons/ ` のmanifest用3枚と、` app/icon.png ` ・` app/apple-icon.png ` のファビコン/apple-touch-icon)による最小構成のPWA対応で、Service Worker・オフライン対応は意図的に持たない(「デプロイしたのに古い画面が出る」系の問題を避けるため、必要になるまで導入しない方針)。インストール後も中身は同じWebアプリで、認証Cookieもそのまま使われる。iOSはmanifestの` display ` /` icons ` を見ないため、` app/layout.tsx ` の` metadata.appleWebApp ` と` app/apple-icon.png ` で別途同等の設定をしている。` /manifest.webmanifest ` は` middleware.ts ` のガード対象から除外が必要(上記「認証」参照)。アイコンPNGは` scripts/generate-icons.mjs ` (sharp使用、依存には含めない)で生成したものをコミットしてあり、デザイン変更時のみ再生成する。
4646
47+ ### ビルド番号
48+
49+ GitHub Actions(` .github/workflows/docker-publish.yml ` )がビルド時に` <JST日時>-<短縮コミットハッシュ> ` 形式のビルド番号を生成し、` --build-arg BUILD_NUMBER ` でDockerfileのprodステージに渡して` ENV BUILD_NUMBER ` として焼き込む。` app/[type]/admin/page.tsx ` (サーバーコンポーネント)が` process.env.BUILD_NUMBER ` を読んで` AdminView ` の` buildNumber ` propに渡し、管理画面の見出し横に表示する(未設定時は「開発ビルド」)。` NEXT_PUBLIC_ ` で` next build ` 時に埋め込むのではなくリクエスト時に環境変数を読む方式にしてあるため、ビルド番号が毎回変わってもNext.jsのビルドキャッシュには影響しない(prodステージは` next build ` の後段のため、Dockerレイヤキャッシュも実質壊さない)。
50+
4751### スポット種別(` spot_types ` )の設計
4852
4953単一の`spots`テーブルを`spot_types`により複数の「種別」で使い回す設計。`tourist`(観光地)がアプリ初期化時(`db/init/01_schema.sql`)に必ず作成される唯一の既定種別で、それ以外の種別は管理者が`/[type]/admin`から追加する(空の種別ではデータが入らないだけで、削除しない限り存在し続ける)。既定種別といっても自動で作られるのは`spot_types`の行だけで、スポットデータ自体は他の種別と同様シードデータを`db/init/`に直接コミットせず外部リポジトリ[travel-log-data](../travel-log-data)にCSVとして置き、`/[type]/admin`のCSVインポートから取り込む(下記「外部データソース」の段落参照)。観光地データの`description`はWikipedia記事冒頭文の引用でCC BY-SA 4.0、`name`/`lat`/`lng`の一部はOpenStreetMap(ODbL)由来のため、travel-logリポジトリ本体には同梱せずtravel-log-data側でのみ管理・出典表示する。
Original file line number Diff line number Diff line change @@ -19,6 +19,11 @@ RUN npm run build
1919FROM node:22-alpine AS prod
2020WORKDIR /app
2121ENV NODE_ENV=production
22+ # GitHub Actionsが --build-arg BUILD_NUMBER=<JST日時>-<短縮コミットハッシュ> で渡すビルド番号。
23+ # 管理画面(app/[type]/admin)がリクエスト時にこの環境変数を読んで表示する。
24+ # ビルド時に埋め込まず実行時に読むためnext buildのキャッシュには影響しない(未指定なら空=開発ビルド扱い)
25+ ARG BUILD_NUMBER=""
26+ ENV BUILD_NUMBER=$BUILD_NUMBER
2227COPY --from=builder /app/.next/standalone ./
2328COPY --from=builder /app/.next/static ./.next/static
2429EXPOSE 3000
Original file line number Diff line number Diff line change @@ -109,6 +109,10 @@ docker compose pull app && docker compose up -d
109109 ホストに合う方が自動選択される
110110- 特定時点に戻したいときは` docker-compose.yml ` のイメージタグを` latest ` から
111111 ` sha-xxxxxxx ` (Actionsが付けるコミットSHAタグ)に一時的に変えてpullし直す
112+ - Actionsはビルド番号(` 20260722-1035-9162ba9 ` のようなJST日時+短縮コミットハッシュ)を
113+ イメージに埋め込み、管理画面` /[種別キー]/admin ` の見出し横に表示する。今動いている
114+ イメージがいつのどのコミットのものか、pull後の反映確認に使える(ローカル開発時など
115+ 埋め込みが無い場合は「開発ビルド」と表示される)
112116
113117## 画面
114118
Original file line number Diff line number Diff line change @@ -13,5 +13,7 @@ export default async function TypedAdminPage({
1313 const { rows } = await query ( "select 1 from spot_types where key = $1" , [ type ] ) ;
1414 if ( ! rows [ 0 ] ) notFound ( ) ;
1515
16- return < AdminView typeKey = { type } /> ;
16+ // ビルド番号(Dockerfileのprodステージが --build-arg BUILD_NUMBER で受け取る)。
17+ // 開発時など未設定の場合はnullを渡し、管理画面側で「開発ビルド」と表示する
18+ return < AdminView typeKey = { type } buildNumber = { process . env . BUILD_NUMBER || null } /> ;
1719}
Original file line number Diff line number Diff line change @@ -48,7 +48,13 @@ const CSV_COLUMNS = [
4848 "description" ,
4949] as const ;
5050
51- export default function AdminView ( { typeKey } : { typeKey : string } ) {
51+ export default function AdminView ( {
52+ typeKey,
53+ buildNumber,
54+ } : {
55+ typeKey : string ;
56+ buildNumber ?: string | null ;
57+ } ) {
5258 const router = useRouter ( ) ;
5359 const [ checkingRole , setCheckingRole ] = useState ( true ) ;
5460 const [ hasPageAccess , setHasPageAccess ] = useState ( false ) ;
@@ -662,7 +668,13 @@ export default function AdminView({ typeKey }: { typeKey: string }) {
662668
663669 return (
664670 < main className = "mx-auto max-w-6xl p-4" >
665- < h1 className = "mb-4 text-lg font-bold" > 管理画面</ h1 >
671+ < div className = "mb-4 flex flex-wrap items-baseline gap-x-3 gap-y-1" >
672+ < h1 className = "text-lg font-bold" > 管理画面</ h1 >
673+ { /* 本番で動いているイメージの識別用。GitHub Actionsのビルド時に埋め込まれる */ }
674+ < span className = "font-mono text-xs text-gray-500" >
675+ ビルド: { buildNumber ?? "開発ビルド" }
676+ </ span >
677+ </ div >
666678
667679 { /* スポット種別(ログイン後の既定・種別マスタ) */ }
668680 < div className = "grid grid-cols-1 gap-6 lg:grid-cols-[360px_1fr]" >
You can’t perform that action at this time.
0 commit comments