Color mode

GitHub Actions

Riebeckite では、GitHub Actions を使って GitHub への Push から Cloudflare Workers への Deployment を自動化できます。

Diagram source
text
flowchart LR
    Push["git push"]
    Actions["GitHub Actions"]
    Check["riebeckite check"]
    Build["riebeckite build"]
    Dist["dist/"]
    CF["Cloudflare Workers"]
 
    Push --> Actions
    Actions --> Check
    Check --> Build
    Build --> Dist
    Dist --> CF

Site と Content が同じ Repository にある一般的な構成なら、main へ Push するだけで Build と Deploy を実行できます。

GitHub Actions を有効にして Site を作る

対話式の CLI では、最後にデプロイ設定を尋ねたところで GitHub Actions を選びます。手元からの初回公開(Local-first)は Cloudflare Workers を選びます。コマンドラインから GitHub Actions を指定する場合は次のとおりです。

bash
npx create-riebeckite my-site --github-actions

これによって、Cloudflare Workers への Deployment に必要な、

text
my-site/
├─ .github/
│  └─ workflows/
│     └─ deploy.yml
│
├─ wrangler.jsonc
└─ ...

が生成されます。

File 役割
wrangler.jsonc Cloudflare Workers の Deployment 設定
.github/workflows/deploy.yml GitHub Actions の Build / Deploy Workflow

通常は、生成された Workflow を出発点として利用します。

既存の Site に追加する

すでに Local-first で公開している場合は、Site を作り直さずに継続デプロイを追加できます。Site の Directory で次を実行します。

sh
npm exec riebeckite deploy setup

このコマンドは次の順で進みます。

  1. Git Repository と GitHub Remote を検出する
  2. GitHub CLI(gh)が install 済みでログイン済みか確認する
  3. .github/workflows/deploy.yml が無ければ、同じテンプレートから作成する。Riebeckite 以外の既存 workflow は上書きせず、検出したことを報告し、secret の登録には進まずに停止する
  4. Wrangler のログイン状態から Cloudflare Account を取得する。複数ある場合は選択する
  5. CLOUDFLARE_ACCOUNT_ID と CLOUDFLARE_API_TOKEN を Repository Secret として登録する。Token は hidden prompt、または non-interactive 用の環境変数 CLOUDFLARE_API_TOKEN から読み取る

GitHub Repository の作成と push は行いません。完了後、次で Deploy します。

sh
git push

再実行も可能です。一致する workflow と登録済みの secret は検出され、残りの手順だけを実行します。別の deployment workflow が既にある場合は、置き換えるか削除してから再実行してください。

必要なもの

GitHub Actions から Deployment するには、次の設定が必要です。

  • package-lock.json
  • CLOUDFLARE_API_TOKEN
  • CLOUDFLARE_ACCOUNT_ID
  • deploy setup を使う場合は GitHub CLI(gh)の install とログイン、および Wrangler の依存(Local-first の Site には含まれています)

package-lock.json

生成される Workflow は、

sh
npm ci

を使って依存 Package をインストールします。

そのため、

text
package-lock.json

を Repository に Commit してください。

text
package.json
package-lock.json
      ↓
npm ci
      ↓
同じ依存関係をCIでinstall

package-lock.json がない状態では、生成 Workflow の npm ci をそのまま利用できません。

Repository を GitHub に置く

GitHub Actions は GitHub 上の Repository を読みます。Site Repository がまだなければ、作ります。

Git で初期化する

Site の Directory で、次を実行します。

sh
git init
git add .
git commit -m "First commit"

.gitignore は生成済みなので node_modules/ や dist/ は commit されません。一方で package-lock.json は commit されます。このファイルが無いと、この後説明する npm ci が動かないので必ず残してください。

Git を初めて使う場合、git commit が Author identity unknown で失敗することがあります。そのときは次を設定してからやり直します。

sh
git config --global user.name "あなたの名前"
git config --global user.email "you@example.com"

GitHub に Repository を作って push する

  1. GitHub で New repository を開きます。Repository 名を決めて作成します。Add a README file と Add .gitignore は付けません。ローカルに既に履歴があるため、両方を入れると push が拒否されます。
  2. 作成直後の画面に表示される「…or push an existing repository from the command line」のコマンドを、そのまま実行します。main を使う構成の例は次のとおりです。
sh
git remote add origin https://github.com/<you>/my-site.git
git branch -M main
git push -u origin main

git push -u origin main が成功したら、GitHub の Repository ページにファイルが表示されます。これで main への次回 push から Workflow を動かせます。

Cloudflare の Secrets

Site Repository に、次の GitHub Actions Secrets を設定します。

text
CLOUDFLARE_API_TOKEN
CLOUDFLARE_ACCOUNT_ID

どちらも Cloudflare 側で用意します。

CLOUDFLARE_API_TOKEN を作る

  1. Cloudflare ダッシュボード にログインし、右上のアカウントメニューから My Profile を開きます。直接 API Tokens でも開けます。
  2. Create Token → Create Custom Token を選びます。
  3. Permissions に Account / Workers Scripts / Edit を追加します。
  4. Account Resources に自分の Account を含めます。
  5. Continue to review → Create Token を押します。
  6. 表示されたトークンの値をコピーします。この画面を閉じると、この値は二度と表示されません。

権限の詳しい考え方は Cloudflare の公式手順 を参照してください。トークンが事故で漏れたときは、同じ画面からローテーションできます。

CLOUDFLARE_ACCOUNT_ID を探す

ダッシュボードで Workers & Pages を開くと、ブラウザのアドレスバーが次の形式になります。

text
https://dash.cloudflare.com/<ACCOUNT_ID>/workers-and-pages

<ACCOUNT_ID> が CLOUDFLARE_ACCOUNT_ID の値です。Worker の詳細ページに表示される Account ID と同じ値でも構いません。

GitHub に登録する

GitHub の Site Repository → Settings → Secrets and variables → Actions → New repository secret を開き、名前と値をそれぞれ登録します。

text
名前: CLOUDFLARE_API_TOKEN   値: 上でコピーしたトークン
名前: CLOUDFLARE_ACCOUNT_ID  値: 上の ACCOUNT_ID

riebeckite deploy setup は、すでに Git Repository になっている Site に対してこの2つの登録を自動化します。Wrangler のログインから Account を取得し、Token は hidden prompt に貼り付けます。手元で secret を登録したい場合や、CLI を使えない場合は、上記の手動手順をそのまま利用してください。

GitHub Repository の Actions から、Workflow がこれらを参照します。

Diagram source
text
flowchart LR
    Secrets["GitHub Secrets<br/>CLOUDFLARE_API_TOKEN<br/>CLOUDFLARE_ACCOUNT_ID"]
    Actions["GitHub Actions"]
    Cloudflare["Cloudflare Workers"]
 
    Secrets --> Actions
    Actions --> Cloudflare

これらは Source Code や riebeckite.config.ts に直接書かず、Repository Secret として管理します。

Workflow が動くタイミング

生成される Workflow は、次の3つの Trigger に対応します。

Trigger 用途
main への push Site の変更を自動 Deploy
workflow_dispatch GitHub から手動実行
repository_dispatch: content-updated 別 Repository の Content 更新から実行

通常の Site Repository では、

text
mainへpush
    ↓
GitHub Actions
    ↓
Deploy

という流れになります。

Site と Content が同じ Repository の場合

最も単純な構成です。

text
my-site/
├─ content/
├─ app/
├─ riebeckite.config.ts
└─ .github/
   └─ workflows/
      └─ deploy.yml

記事も Site も同じ Repository にあるため、

Diagram source
text
flowchart LR
    Push["mainへpush"]
    Workflow["deploy.yml"]
    Build["Build"]
    Deploy["Cloudflare"]
 
    Push --> Workflow
    Workflow --> Build
    Build --> Deploy

となります。

記事を変更して main に Push すれば、その Push 自体が Workflow を起動します。

Site と Content が別 Repository の場合

Content Repository を分離している場合は少し流れが変わります。

text
Content Repository
  → Markdown / Obsidian Vault
 
Site Repository
  → Riebeckite / Config / Theme / Plugin

Content Repository に Push しても、それだけでは Site Repository の Workflow は起動しません。

GitHub Actions の Workflow は、それぞれの Repository に属しているためです。

Diagram source
text
flowchart LR
    Content["Content Repository"]
    Site["Site Repository"]
    Workflow["Site deploy.yml"]
 
    Content -.->|"pushだけでは起動しない"| Workflow
    Site -->|"push"| Workflow

Content の更新から Site を自動 Deploy するには、Content Repository から Site Repository へ通知します。

repository_dispatch

別 Repository から Site Workflow を起動するために、

text
repository_dispatch

を利用します。

Riebeckite の生成 Workflow は、

text
content-updated

という Event を受け取れる構成です。

全体の流れは、

Diagram source
text
flowchart LR
    Push["Content<br/>mainへpush"]
    Notify["notify-site.yml"]
    Dispatch["repository_dispatch<br/>content-updated"]
    Site["Site Repository"]
    Workflow["deploy.yml"]
    Build["Build"]
    Deploy["Cloudflare"]
 
    Push --> Notify
    Notify --> Dispatch
    Dispatch --> Site
    Site --> Workflow
    Workflow --> Build
    Build --> Deploy

となります。

notify-site.yml

Content Repository 側には、

text
.github/workflows/notify-site.yml

を置きます。

この Workflow の役割は Site を Build することではありません。

text
Content Repository
      ↓
Site Repositoryへ
「Contentが更新された」と通知

することです。

その通知を受けた Site Repository の deploy.yml が Build と Deploy を実行します。

SITE_DISPATCH_TOKEN

Content Repository から Site Repository へ repository_dispatch を送るには、

text
SITE_DISPATCH_TOKEN

を Content Repository 側の Secret として設定します。

Diagram source
text
flowchart LR
    Content["Content Repository"]
    Token["SITE_DISPATCH_TOKEN"]
    Site["Site Repository"]
 
    Content --> Token
    Token -->|"content-updated"| Site

この Token は、

Content Repository から Site Repository の Workflow を起動するためのもの

です。

Workflow の流れ

生成された Deployment Workflow は、概ね次の順番で処理します。

Diagram source
text
flowchart TD
    Start["Workflow開始"]
    CheckoutSite["1. SiteをCheckout"]
    CheckoutContent["2. 外部ContentをCheckout<br/>必要な場合のみ"]
    Node["3. Node.js 22"]
    Install["4. npm ci"]
    Cache["5. Riebeckite cacheを復元"]
    Check["6. riebeckite check"]
    Build["7. riebeckite build"]
    Deploy["8. CloudflareへDeploy"]
 
    Start --> CheckoutSite
    CheckoutSite --> CheckoutContent
    CheckoutContent --> Node
    Node --> Install
    Install --> Cache
    Cache --> Check
    Check --> Build
    Build --> Deploy

1. Site Repository を Checkout

最初に Site Repository を取得します。

text
GitHub Runner
    ↓
Site Repository

ここには、

  • Riebeckite Config
  • Application
  • Plugin / Theme の設定
  • package.json
  • package-lock.json

などが含まれます。

2. 外部 Content を Checkout

Content が同じ Repository にある場合、この追加処理は必要ありません。

別 Repository を利用している場合は、Content Repository を、

text
content/

へ Checkout します。

text
Runner
 
Site Repository
├─ app/
├─ riebeckite.config.ts
├─ package.json
└─ content/          ← 外部Content Repository

その場合、Riebeckite 側では、

ts
content: {
  directory: "content",
},

として読み込めます。

3. Node.js を設定

生成 Workflow では Node.js 22 を設定します。

text
GitHub Runner
      ↓
Node.js 22

その後の npm ci や Riebeckite CLI はこの環境で実行されます。

4. Package をインストール

sh
npm ci

を実行します。

npm ci は package-lock.json に従って依存 Package をインストールします。

そのため、生成 Workflow を利用する場合は package-lock.json を Commit しておく必要があります。

5. Riebeckite の build state を復元

生成 Workflow は actions/cache で .riebeckite/cache(Markdown と Plugin の処理 cache)と .riebeckite/build/content-state.json(incremental build の state)を復元します。key には runner OS、package-lock.json の hash、run ごとの generation を含めます。各 run は run id と attempt で新しい generation として保存し、restore-keys が最新の互換 generation を取得するため、既存 entry をその場で上書きしません。lockfile の hash は大まかな互換性の境界にすぎず、実際の再利用は Riebeckite の schema version、app/pipeline/content fingerprint、Plugin の cacheVersion が判断します。output cache(.riebeckite/ssg-output-cache.json)は大きく、build 短縮分が転送コストに見合わないため意図的に永続化しません。dist/ は cache しません。

build 後は新しい cache generation が自動保存されます。build log の Persistent content cache 行にある hits、misses、bypasses を見ると、Actions cache の復元後に Riebeckite 内部で実際に再利用されたかを確認できます。cache を削除する、または workflow の cache step を外すと cold processing になりますが、出力の正しさには影響しません。古い cache generation は GitHub が自動的に破棄するため、cache 一覧は肥大しません。

6. Site を検証

次に、

sh
npm exec riebeckite check

を実行します。

Config や Plugin の解決に問題があれば、Deploy 前にここで失敗します。

text
Checkout
   ↓
Install
   ↓
check
   ↓
問題があれば停止

壊れた設定のまま Deployment まで進めないための確認です。

7. Site を Build

check が成功したら、

sh
npm exec riebeckite build

を実行します。

Riebeckite が公開用の、

text
dist/

を生成します。

text
Content
Config
Plugin
Theme
   ↓
riebeckite build
   ↓
dist/

7. Cloudflare Workers へ Deploy

最後に、

text
cloudflare/wrangler-action@v3

を使って Cloudflare Workers へ Deploy します。

Diagram source
text
flowchart LR
    Dist["dist/"]
    Wrangler["wrangler-action"]
    Workers["Cloudflare Workers"]
    Site["Public Site"]
 
    Dist --> Wrangler
    Wrangler --> Workers
    Workers --> Site

ここで、

text
CLOUDFLARE_API_TOKEN
CLOUDFLARE_ACCOUNT_ID

が利用されます。

Private Content Repository を使う

Content Repository が Public の場合と Private の場合では、Checkout の認証が異なります。

Private Content Repository を読む場合は、Site Repository に、

text
RIEBECKITE_CONTENT_READ_TOKEN

を設定します。

Diagram source
text
flowchart LR
    Site["Site Repository"]
    Token["RIEBECKITE_CONTENT_READ_TOKEN"]
    Content["Private Content Repository"]
 
    Site --> Token
    Token -->|"read"| Content

この Token の役割は、

Site の Workflow から Private Content Repository を読み込むこと

です。

2つの Token を混同しない

Repository を分離した構成では、似た名前の Token が2つ登場します。

Secret 保存する場所 役割
RIEBECKITE_CONTENT_READ_TOKEN Site Repository Private Content Repository を読む
SITE_DISPATCH_TOKEN Content Repository Site Repository に更新を通知する

方向で覚えると分かりやすくなります。

text
RIEBECKITE_CONTENT_READ_TOKEN
 
Site ─────read─────> Content
text
SITE_DISPATCH_TOKEN
 
Content ───notify───> Site

つまり、

Diagram source
text
flowchart LR
    Content["Content Repository"]
    Site["Site Repository"]
 
    Content -->|"SITE_DISPATCH_TOKEN<br/>更新を通知"| Site
    Site -->|"RIEBECKITE_CONTENT_READ_TOKEN<br/>Contentを取得"| Content

です。

Site Push と Content Push の違い

Repository を分離した場合は、2つの Deployment 経路があります。

Site を変更した場合

text
Site Repository
      ↓
mainへpush
      ↓
deploy.yml
      ↓
ContentをCheckout
      ↓
Build
      ↓
Deploy

Site の push が直接 Workflow を起動します。

Content を変更した場合

text
Content Repository
      ↓
mainへpush
      ↓
notify-site.yml
      ↓
repository_dispatch
      ↓
Site deploy.yml
      ↓
ContentをCheckout
      ↓
Build
      ↓
Deploy

こちらでは、Content Repository から Site Repository への通知が1段階追加されます。

どちらの場合も、最終的に Site Repository 側で Build する点は同じです。

手動で Deploy Workflow を実行する

生成 Workflow は、

text
workflow_dispatch

にも対応しています。

そのため、GitHub 上から Workflow を手動実行できます。

text
GitHub
  ↓
Actions
  ↓
Deploy Workflow
  ↓
Run workflow

Content や Site に新しい Commit を作らず、現在の状態でもう一度 Deployment したい場合などに利用できます。

Deployment が動かない場合

まず「Workflow が起動していない」のか、「Workflow は起動したが失敗した」のかを分けます。

Diagram source
text
flowchart TD
    Problem["Deployされない"]
 
    Problem --> Started{"Workflowは起動した?"}
 
    Started -->|"No"| Trigger["Triggerを確認"]
    Started -->|"Yes"| Failed{"どこで失敗?"}
 
    Trigger --> Push["main push"]
    Trigger --> Manual["workflow_dispatch"]
    Trigger --> Dispatch["repository_dispatch"]
 
    Failed --> Checkout["Checkout"]
    Failed --> Install["npm ci"]
    Failed --> Check["riebeckite check"]
    Failed --> Build["riebeckite build"]
    Failed --> Deploy["Cloudflare Deploy"]

Workflow が起動しない

Site Repository への Push なら、

text
main

へ Push しているか確認します。

Content Repository への Push なら、

text
notify-site.yml
SITE_DISPATCH_TOKEN
repository_dispatch
content-updated

を確認します。

Content Repository への Push だけでは Site Workflow は起動しません。

npm ci で失敗する

生成 Workflow は、

sh
npm ci

を利用します。

そのため、

text
package-lock.json

が Repository に Commit されているか確認してください。

Content の Checkout で失敗する

Private Content Repository の場合は、

text
RIEBECKITE_CONTENT_READ_TOKEN

を確認します。

Site Repository の Workflow が、その Token を使って Content Repository を読み取れる必要があります。

check で失敗する

sh
npm exec riebeckite check

と同じ Command を手元でも実行します。

Config や Plugin の問題を修正してから Push してください。

build で失敗する

手元で、

sh
npm exec riebeckite build

を実行して再現するか確認します。

Repository を分離している場合は、CI と同じ場所に Content が存在することも確認してください。

Cloudflare Deployment で失敗する

Build までは成功している場合は、

text
CLOUDFLARE_API_TOKEN
CLOUDFLARE_ACCOUNT_ID
wrangler.jsonc

を確認します。

Riebeckite の Build と Cloudflare Deployment は別の段階なので、どちらで失敗したかを分けて調べると原因を特定しやすくなります。

まとめ

通常の Site Repository では、

text
mainへpush
    ↓
GitHub Actions
    ↓
npm ci
    ↓
riebeckite check
    ↓
riebeckite build
    ↓
Cloudflare Workers

という流れになります。

Content Repository を分離している場合は、

text
Contentをpush
    ↓
notify-site.yml
    ↓
repository_dispatch
    ↓
Site Workflow
    ↓
ContentをCheckout
    ↓
Build
    ↓
Deploy

となります。

特に覚えておきたいのは、

text
SITE_DISPATCH_TOKEN
  → ContentからSiteへ通知する
 
RIEBECKITE_CONTENT_READ_TOKEN
  → SiteからContentを読む
 
CLOUDFLARE_API_TOKEN
CLOUDFLARE_ACCOUNT_ID
  → CloudflareへDeployする

という役割の違いです。

関連資料

History

1 changesCollapseExpand
1 + # GitHub Actions
2 +
3 + Riebeckite では、GitHub Actions を使って **GitHub への Push から Cloudflare Workers への Deployment を自動化**できます。
4 +
5 + ```mermaid id="s7gf16"
6 + flowchart LR
7 + Push["git push"]
8 + Actions["GitHub Actions"]
9 + Check["riebeckite check"]
10 + Build["riebeckite build"]
11 + Dist["dist/"]
12 + CF["Cloudflare Workers"]
13 +
14 + Push --> Actions
15 + Actions --> Check
16 + Check --> Build
17 + Build --> Dist
18 + Dist --> CF
19 + ```
20 +
21 + Site と Content が同じ Repository にある一般的な構成なら、`main` へ Push するだけで Build と Deploy を実行できます。
22 +
23 + ## GitHub Actions を有効にして Site を作る
24 +
25 + 対話式の CLI では、最後にデプロイ設定を尋ねたところで `GitHub Actions` を選びます。手元からの初回公開(Local-first)は `Cloudflare Workers` を選びます。コマンドラインから GitHub Actions を指定する場合は次のとおりです。
26 +
27 + ```bash id="f10w6x"
28 + npx create-riebeckite my-site --github-actions
29 + ```
30 +
31 + これによって、Cloudflare Workers への Deployment に必要な、
32 +
33 + ```text id="hw99qe"
34 + my-site/
35 + ├─ .github/
36 + │ └─ workflows/
37 + │ └─ deploy.yml
38 + │
39 + ├─ wrangler.jsonc
40 + └─ ...
41 + ```
42 +
43 + が生成されます。
44 +
45 + | File | 役割 |
46 + | --- | --- |
47 + | `wrangler.jsonc` | Cloudflare Workers の Deployment 設定 |
48 + | `.github/workflows/deploy.yml` | GitHub Actions の Build / Deploy Workflow |
49 +
50 + 通常は、生成された Workflow を出発点として利用します。
51 +
52 + ## 既存の Site に追加する
53 +
54 + すでに Local-first で公開している場合は、Site を作り直さずに継続デプロイを追加できます。Site の Directory で次を実行します。
55 +
56 + ```sh id="d3setupj1"
57 + npm exec riebeckite deploy setup
58 + ```
59 +
60 + このコマンドは次の順で進みます。
61 +
62 + 1. Git Repository と GitHub Remote を検出する
63 + 2. GitHub CLI(`gh`)が install 済みでログイン済みか確認する
64 + 3. `.github/workflows/deploy.yml` が無ければ、同じテンプレートから作成する。Riebeckite 以外の既存 workflow は上書きせず、検出したことを報告し、secret の登録には進まずに停止する
65 + 4. Wrangler のログイン状態から Cloudflare Account を取得する。複数ある場合は選択する
66 + 5. `CLOUDFLARE_ACCOUNT_ID` と `CLOUDFLARE_API_TOKEN` を Repository Secret として登録する。Token は hidden prompt、または non-interactive 用の環境変数 `CLOUDFLARE_API_TOKEN` から読み取る
67 +
68 + GitHub Repository の作成と push は行いません。完了後、次で Deploy します。
69 +
70 + ```sh
71 + git push
72 + ```
73 +
74 + 再実行も可能です。一致する workflow と登録済みの secret は検出され、残りの手順だけを実行します。別の deployment workflow が既にある場合は、置き換えるか削除してから再実行してください。
75 +
76 + ## 必要なもの
77 +
78 + GitHub Actions から Deployment するには、次の設定が必要です。
79 +
80 + - `package-lock.json`
81 + - `CLOUDFLARE_API_TOKEN`
82 + - `CLOUDFLARE_ACCOUNT_ID`
83 + - `deploy setup` を使う場合は GitHub CLI(`gh`)の install とログイン、および Wrangler の依存(Local-first の Site には含まれています)
84 +
85 + ### `package-lock.json`
86 +
87 + 生成される Workflow は、
88 +
89 + ```sh id="8ihzjv"
90 + npm ci
91 + ```
92 +
93 + を使って依存 Package をインストールします。
94 +
95 + そのため、
96 +
97 + ```text id="3oyv7c"
98 + package-lock.json
99 + ```
100 +
101 + を Repository に Commit してください。
102 +
103 + ```text id="s9xb5j"
104 + package.json
105 + package-lock.json
106 + ↓
107 + npm ci
108 + ↓
109 + 同じ依存関係をCIでinstall
110 + ```
111 +
112 + `package-lock.json` がない状態では、生成 Workflow の `npm ci` をそのまま利用できません。
113 +
114 + ## Repository を GitHub に置く
115 +
116 + GitHub Actions は GitHub 上の Repository を読みます。Site Repository がまだなければ、作ります。
117 +
118 + ### Git で初期化する
119 +
120 + Site の Directory で、次を実行します。
121 +
122 + ```sh
123 + git init
124 + git add .
125 + git commit -m "First commit"
126 + ```
127 +
128 + `.gitignore` は生成済みなので `node_modules/` や `dist/` は commit されません。一方で `package-lock.json` は commit されます。このファイルが無いと、この後説明する `npm ci` が動かないので必ず残してください。
129 +
130 + Git を初めて使う場合、`git commit` が `Author identity unknown` で失敗することがあります。そのときは次を設定してからやり直します。
131 +
132 + ```sh
133 + git config --global user.name "あなたの名前"
134 + git config --global user.email "you@example.com"
135 + ```
136 +
137 + ### GitHub に Repository を作って push する
138 +
139 + 1. [GitHub で New repository](https://github.com/new) を開きます。Repository 名を決めて作成します。**Add a README file** と **Add .gitignore** は**付けません**。ローカルに既に履歴があるため、両方を入れると push が拒否されます。
140 + 2. 作成直後の画面に表示される「…or push an existing repository from the command line」のコマンドを、そのまま実行します。`main` を使う構成の例は次のとおりです。
141 +
142 + ```sh
143 + git remote add origin https://github.com/<you>/my-site.git
144 + git branch -M main
145 + git push -u origin main
146 + ```
147 +
148 + `git push -u origin main` が成功したら、GitHub の Repository ページにファイルが表示されます。これで `main` への次回 push から Workflow を動かせます。
149 +
150 + ## Cloudflare の Secrets
151 +
152 + Site Repository に、次の GitHub Actions Secrets を設定します。
153 +
154 + ```text id="79c4ea"
155 + CLOUDFLARE_API_TOKEN
156 + CLOUDFLARE_ACCOUNT_ID
157 + ```
158 +
159 + どちらも Cloudflare 側で用意します。
160 +
161 + ### `CLOUDFLARE_API_TOKEN` を作る
162 +
163 + 1. [Cloudflare ダッシュボード](https://dash.cloudflare.com/) にログインし、右上のアカウントメニューから **My Profile** を開きます。直接 [API Tokens](https://dash.cloudflare.com/profile/api-tokens) でも開けます。
164 + 2. **Create Token** → **Create Custom Token** を選びます。
165 + 3. **Permissions** に **Account** / **Workers Scripts** / **Edit** を追加します。
166 + 4. **Account Resources** に自分の Account を含めます。
167 + 5. **Continue to review** → **Create Token** を押します。
168 + 6. 表示されたトークンの値をコピーします。この画面を閉じると、この値は二度と表示されません。
169 +
170 + 権限の詳しい考え方は [Cloudflare の公式手順](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/) を参照してください。トークンが事故で漏れたときは、同じ画面からローテーションできます。
171 +
172 + ### `CLOUDFLARE_ACCOUNT_ID` を探す
173 +
174 + ダッシュボードで **Workers & Pages** を開くと、ブラウザのアドレスバーが次の形式になります。
175 +
176 + ```text
177 + https://dash.cloudflare.com/<ACCOUNT_ID>/workers-and-pages
178 + ```
179 +
180 + `<ACCOUNT_ID>` が `CLOUDFLARE_ACCOUNT_ID` の値です。Worker の詳細ページに表示される **Account ID** と同じ値でも構いません。
181 +
182 + ### GitHub に登録する
183 +
184 + GitHub の Site Repository → **Settings** → **Secrets and variables** → **Actions** → **New repository secret** を開き、名前と値をそれぞれ登録します。
185 +
186 + ```text
187 + 名前: CLOUDFLARE_API_TOKEN 値: 上でコピーしたトークン
188 + 名前: CLOUDFLARE_ACCOUNT_ID 値: 上の ACCOUNT_ID
189 + ```
190 +
191 + `riebeckite deploy setup` は、すでに Git Repository になっている Site に対してこの2つの登録を自動化します。Wrangler のログインから Account を取得し、Token は hidden prompt に貼り付けます。手元で secret を登録したい場合や、CLI を使えない場合は、上記の手動手順をそのまま利用してください。
192 +
193 + GitHub Repository の Actions から、Workflow がこれらを参照します。
194 +
195 + ```mermaid id="ngbty6"
196 + flowchart LR
197 + Secrets["GitHub Secrets<br/>CLOUDFLARE_API_TOKEN<br/>CLOUDFLARE_ACCOUNT_ID"]
198 + Actions["GitHub Actions"]
199 + Cloudflare["Cloudflare Workers"]
200 +
201 + Secrets --> Actions
202 + Actions --> Cloudflare
203 + ```
204 +
205 + これらは Source Code や `riebeckite.config.ts` に直接書かず、Repository Secret として管理します。
206 +
207 + ## Workflow が動くタイミング
208 +
209 + 生成される Workflow は、次の3つの Trigger に対応します。
210 +
211 + | Trigger | 用途 |
212 + | --- | --- |
213 + | `main` への `push` | Site の変更を自動 Deploy |
214 + | `workflow_dispatch` | GitHub から手動実行 |
215 + | `repository_dispatch: content-updated` | 別 Repository の Content 更新から実行 |
216 +
217 + 通常の Site Repository では、
218 +
219 + ```text id="whvm5u"
220 + mainへpush
221 + ↓
222 + GitHub Actions
223 + ↓
224 + Deploy
225 + ```
226 +
227 + という流れになります。
228 +
229 + ## Site と Content が同じ Repository の場合
230 +
231 + 最も単純な構成です。
232 +
233 + ```text id="8tqoq6"
234 + my-site/
235 + ├─ content/
236 + ├─ app/
237 + ├─ riebeckite.config.ts
238 + └─ .github/
239 + └─ workflows/
240 + └─ deploy.yml
241 + ```
242 +
243 + 記事も Site も同じ Repository にあるため、
244 +
245 + ```mermaid id="j89zya"
246 + flowchart LR
247 + Push["mainへpush"]
248 + Workflow["deploy.yml"]
249 + Build["Build"]
250 + Deploy["Cloudflare"]
251 +
252 + Push --> Workflow
253 + Workflow --> Build
254 + Build --> Deploy
255 + ```
256 +
257 + となります。
258 +
259 + 記事を変更して `main` に Push すれば、その Push 自体が Workflow を起動します。
260 +
261 + ## Site と Content が別 Repository の場合
262 +
263 + Content Repository を分離している場合は少し流れが変わります。
264 +
265 + ```text id="w3jwej"
266 + Content Repository
267 + → Markdown / Obsidian Vault
268 +
269 + Site Repository
270 + → Riebeckite / Config / Theme / Plugin
271 + ```
272 +
273 + Content Repository に Push しても、**それだけでは Site Repository の Workflow は起動しません。**
274 +
275 + GitHub Actions の Workflow は、それぞれの Repository に属しているためです。
276 +
277 + ```mermaid id="v20ejj"
278 + flowchart LR
279 + Content["Content Repository"]
280 + Site["Site Repository"]
281 + Workflow["Site deploy.yml"]
282 +
283 + Content -.->|"pushだけでは起動しない"| Workflow
284 + Site -->|"push"| Workflow
285 + ```
286 +
287 + Content の更新から Site を自動 Deploy するには、Content Repository から Site Repository へ通知します。
288 +
289 + ## `repository_dispatch`
290 +
291 + 別 Repository から Site Workflow を起動するために、
292 +
293 + ```text id="ejx6wo"
294 + repository_dispatch
295 + ```
296 +
297 + を利用します。
298 +
299 + Riebeckite の生成 Workflow は、
300 +
301 + ```text id="5ss0v6"
302 + content-updated
303 + ```
304 +
305 + という Event を受け取れる構成です。
306 +
307 + 全体の流れは、
308 +
309 + ```mermaid id="k5hvll"
310 + flowchart LR
311 + Push["Content<br/>mainへpush"]
312 + Notify["notify-site.yml"]
313 + Dispatch["repository_dispatch<br/>content-updated"]
314 + Site["Site Repository"]
315 + Workflow["deploy.yml"]
316 + Build["Build"]
317 + Deploy["Cloudflare"]
318 +
319 + Push --> Notify
320 + Notify --> Dispatch
321 + Dispatch --> Site
322 + Site --> Workflow
323 + Workflow --> Build
324 + Build --> Deploy
325 + ```
326 +
327 + となります。
328 +
329 + ## `notify-site.yml`
330 +
331 + Content Repository 側には、
332 +
333 + ```text id="7p33l5"
334 + .github/workflows/notify-site.yml
335 + ```
336 +
337 + を置きます。
338 +
339 + この Workflow の役割は Site を Build することではありません。
340 +
341 + ```text id="kw1g8g"
342 + Content Repository
343 + ↓
344 + Site Repositoryへ
345 + 「Contentが更新された」と通知
346 + ```
347 +
348 + することです。
349 +
350 + その通知を受けた Site Repository の `deploy.yml` が Build と Deploy を実行します。
351 +
352 + ## `SITE_DISPATCH_TOKEN`
353 +
354 + Content Repository から Site Repository へ `repository_dispatch` を送るには、
355 +
356 + ```text id="b18f8j"
357 + SITE_DISPATCH_TOKEN
358 + ```
359 +
360 + を Content Repository 側の Secret として設定します。
361 +
362 + ```mermaid id="m04tnw"
363 + flowchart LR
364 + Content["Content Repository"]
365 + Token["SITE_DISPATCH_TOKEN"]
366 + Site["Site Repository"]
367 +
368 + Content --> Token
369 + Token -->|"content-updated"| Site
370 + ```
371 +
372 + この Token は、
373 +
374 + **Content Repository から Site Repository の Workflow を起動するためのもの**
375 +
376 + です。
377 +
378 + ## Workflow の流れ
379 +
380 + 生成された Deployment Workflow は、概ね次の順番で処理します。
381 +
382 + ```mermaid id="hdbpqw"
383 + flowchart TD
384 + Start["Workflow開始"]
385 + CheckoutSite["1. SiteをCheckout"]
386 + CheckoutContent["2. 外部ContentをCheckout<br/>必要な場合のみ"]
387 + Node["3. Node.js 22"]
388 + Install["4. npm ci"]
389 + Cache["5. Riebeckite cacheを復元"]
390 + Check["6. riebeckite check"]
391 + Build["7. riebeckite build"]
392 + Deploy["8. CloudflareへDeploy"]
393 +
394 + Start --> CheckoutSite
395 + CheckoutSite --> CheckoutContent
396 + CheckoutContent --> Node
397 + Node --> Install
398 + Install --> Cache
399 + Cache --> Check
400 + Check --> Build
401 + Build --> Deploy
402 + ```
403 +
404 + ### 1. Site Repository を Checkout
405 +
406 + 最初に Site Repository を取得します。
407 +
408 + ```text id="cq3r5o"
409 + GitHub Runner
410 + ↓
411 + Site Repository
412 + ```
413 +
414 + ここには、
415 +
416 + - Riebeckite Config
417 + - Application
418 + - Plugin / Theme の設定
419 + - `package.json`
420 + - `package-lock.json`
421 +
422 + などが含まれます。
423 +
424 + ### 2. 外部 Content を Checkout
425 +
426 + Content が同じ Repository にある場合、この追加処理は必要ありません。
427 +
428 + 別 Repository を利用している場合は、Content Repository を、
429 +
430 + ```text id="7xb8gc"
431 + content/
432 + ```
433 +
434 + へ Checkout します。
435 +
436 + ```text id="1rhw6a"
437 + Runner
438 +
439 + Site Repository
440 + ├─ app/
441 + ├─ riebeckite.config.ts
442 + ├─ package.json
443 + └─ content/ ← 外部Content Repository
444 + ```
445 +
446 + その場合、Riebeckite 側では、
447 +
448 + ```ts id="k2zv1m"
449 + content: {
450 + directory: "content",
451 + },
452 + ```
453 +
454 + として読み込めます。
455 +
456 + ### 3. Node.js を設定
457 +
458 + 生成 Workflow では Node.js 22 を設定します。
459 +
460 + ```text id="db4q7u"
461 + GitHub Runner
462 + ↓
463 + Node.js 22
464 + ```
465 +
466 + その後の `npm ci` や Riebeckite CLI はこの環境で実行されます。
467 +
468 + ### 4. Package をインストール
469 +
470 + ```sh id="82x1ig"
471 + npm ci
472 + ```
473 +
474 + を実行します。
475 +
476 + `npm ci` は `package-lock.json` に従って依存 Package をインストールします。
477 +
478 + そのため、生成 Workflow を利用する場合は `package-lock.json` を Commit しておく必要があります。
479 +
480 + ### 5. Riebeckite の build state を復元
481 +
482 + 生成 Workflow は `actions/cache` で `.riebeckite/cache`(Markdown と Plugin の処理 cache)と `.riebeckite/build/content-state.json`(incremental build の state)を復元します。key には runner OS、`package-lock.json` の hash、run ごとの generation を含めます。各 run は run id と attempt で新しい generation として保存し、`restore-keys` が最新の互換 generation を取得するため、既存 entry をその場で上書きしません。lockfile の hash は大まかな互換性の境界にすぎず、実際の再利用は Riebeckite の schema version、app/pipeline/content fingerprint、Plugin の cacheVersion が判断します。output cache(`.riebeckite/ssg-output-cache.json`)は大きく、build 短縮分が転送コストに見合わないため意図的に永続化しません。`dist/` は cache しません。
483 +
484 + build 後は新しい cache generation が自動保存されます。build log の `Persistent content cache` 行にある `hits`、`misses`、`bypasses` を見ると、Actions cache の復元後に Riebeckite 内部で実際に再利用されたかを確認できます。cache を削除する、または workflow の cache step を外すと cold processing になりますが、出力の正しさには影響しません。古い cache generation は GitHub が自動的に破棄するため、cache 一覧は肥大しません。
485 +
486 + ### 6. Site を検証
487 +
488 + 次に、
489 +
490 + ```sh id="e8v6ki"
491 + npm exec riebeckite check
492 + ```
493 +
494 + を実行します。
495 +
496 + Config や Plugin の解決に問題があれば、Deploy 前にここで失敗します。
497 +
498 + ```text id="ryypt0"
499 + Checkout
500 + ↓
501 + Install
502 + ↓
503 + check
504 + ↓
505 + 問題があれば停止
506 + ```
507 +
508 + 壊れた設定のまま Deployment まで進めないための確認です。
509 +
510 + ### 7. Site を Build
511 +
512 + `check` が成功したら、
513 +
514 + ```sh id="4brn9u"
515 + npm exec riebeckite build
516 + ```
517 +
518 + を実行します。
519 +
520 + Riebeckite が公開用の、
521 +
522 + ```text id="qqd5y7"
523 + dist/
524 + ```
525 +
526 + を生成します。
527 +
528 + ```text id="k2bc05"
529 + Content
530 + Config
531 + Plugin
532 + Theme
533 + ↓
534 + riebeckite build
535 + ↓
536 + dist/
537 + ```
538 +
539 + ### 7. Cloudflare Workers へ Deploy
540 +
541 + 最後に、
542 +
543 + ```text id="b6nmf8"
544 + cloudflare/wrangler-action@v3
545 + ```
546 +
547 + を使って Cloudflare Workers へ Deploy します。
548 +
549 + ```mermaid id="sxq25c"
550 + flowchart LR
551 + Dist["dist/"]
552 + Wrangler["wrangler-action"]
553 + Workers["Cloudflare Workers"]
554 + Site["Public Site"]
555 +
556 + Dist --> Wrangler
557 + Wrangler --> Workers
558 + Workers --> Site
559 + ```
560 +
561 + ここで、
562 +
563 + ```text id="7y1w2d"
564 + CLOUDFLARE_API_TOKEN
565 + CLOUDFLARE_ACCOUNT_ID
566 + ```
567 +
568 + が利用されます。
569 +
570 + ## Private Content Repository を使う
571 +
572 + Content Repository が Public の場合と Private の場合では、Checkout の認証が異なります。
573 +
574 + Private Content Repository を読む場合は、Site Repository に、
575 +
576 + ```text id="c2wnxd"
577 + RIEBECKITE_CONTENT_READ_TOKEN
578 + ```
579 +
580 + を設定します。
581 +
582 + ```mermaid id="bhq18h"
583 + flowchart LR
584 + Site["Site Repository"]
585 + Token["RIEBECKITE_CONTENT_READ_TOKEN"]
586 + Content["Private Content Repository"]
587 +
588 + Site --> Token
589 + Token -->|"read"| Content
590 + ```
591 +
592 + この Token の役割は、
593 +
594 + **Site の Workflow から Private Content Repository を読み込むこと**
595 +
596 + です。
597 +
598 + ## 2つの Token を混同しない
599 +
600 + Repository を分離した構成では、似た名前の Token が2つ登場します。
601 +
602 + | Secret | 保存する場所 | 役割 |
603 + | --- | --- | --- |
604 + | `RIEBECKITE_CONTENT_READ_TOKEN` | Site Repository | Private Content Repository を読む |
605 + | `SITE_DISPATCH_TOKEN` | Content Repository | Site Repository に更新を通知する |
606 +
607 + 方向で覚えると分かりやすくなります。
608 +
609 + ```text id="xklxpf"
610 + RIEBECKITE_CONTENT_READ_TOKEN
611 +
612 + Site ─────read─────> Content
613 + ```
614 +
615 + ```text id="50j8kg"
616 + SITE_DISPATCH_TOKEN
617 +
618 + Content ───notify───> Site
619 + ```
620 +
621 + つまり、
622 +
623 + ```mermaid id="z6g3xm"
624 + flowchart LR
625 + Content["Content Repository"]
626 + Site["Site Repository"]
627 +
628 + Content -->|"SITE_DISPATCH_TOKEN<br/>更新を通知"| Site
629 + Site -->|"RIEBECKITE_CONTENT_READ_TOKEN<br/>Contentを取得"| Content
630 + ```
631 +
632 + です。
633 +
634 + ## Site Push と Content Push の違い
635 +
636 + Repository を分離した場合は、2つの Deployment 経路があります。
637 +
638 + ### Site を変更した場合
639 +
640 + ```text id="z48j9w"
641 + Site Repository
642 + ↓
643 + mainへpush
644 + ↓
645 + deploy.yml
646 + ↓
647 + ContentをCheckout
648 + ↓
649 + Build
650 + ↓
651 + Deploy
652 + ```
653 +
654 + Site の `push` が直接 Workflow を起動します。
655 +
656 + ### Content を変更した場合
657 +
658 + ```text id="rqr5jk"
659 + Content Repository
660 + ↓
661 + mainへpush
662 + ↓
663 + notify-site.yml
664 + ↓
665 + repository_dispatch
666 + ↓
667 + Site deploy.yml
668 + ↓
669 + ContentをCheckout
670 + ↓
671 + Build
672 + ↓
673 + Deploy
674 + ```
675 +
676 + こちらでは、Content Repository から Site Repository への通知が1段階追加されます。
677 +
678 + どちらの場合も、最終的に **Site Repository 側で Build する**点は同じです。
679 +
680 + ## 手動で Deploy Workflow を実行する
681 +
682 + 生成 Workflow は、
683 +
684 + ```text id="25pv89"
685 + workflow_dispatch
686 + ```
687 +
688 + にも対応しています。
689 +
690 + そのため、GitHub 上から Workflow を手動実行できます。
691 +
692 + ```text id="0coc2a"
693 + GitHub
694 + ↓
695 + Actions
696 + ↓
697 + Deploy Workflow
698 + ↓
699 + Run workflow
700 + ```
701 +
702 + Content や Site に新しい Commit を作らず、現在の状態でもう一度 Deployment したい場合などに利用できます。
703 +
704 + ## Deployment が動かない場合
705 +
706 + まず「Workflow が起動していない」のか、「Workflow は起動したが失敗した」のかを分けます。
707 +
708 + ```mermaid id="o5l9js"
709 + flowchart TD
710 + Problem["Deployされない"]
711 +
712 + Problem --> Started{"Workflowは起動した?"}
713 +
714 + Started -->|"No"| Trigger["Triggerを確認"]
715 + Started -->|"Yes"| Failed{"どこで失敗?"}
716 +
717 + Trigger --> Push["main push"]
718 + Trigger --> Manual["workflow_dispatch"]
719 + Trigger --> Dispatch["repository_dispatch"]
720 +
721 + Failed --> Checkout["Checkout"]
722 + Failed --> Install["npm ci"]
723 + Failed --> Check["riebeckite check"]
724 + Failed --> Build["riebeckite build"]
725 + Failed --> Deploy["Cloudflare Deploy"]
726 + ```
727 +
728 + ## Workflow が起動しない
729 +
730 + Site Repository への Push なら、
731 +
732 + ```text id="r3q62q"
733 + main
734 + ```
735 +
736 + へ Push しているか確認します。
737 +
738 + Content Repository への Push なら、
739 +
740 + ```text id="1xb7gc"
741 + notify-site.yml
742 + SITE_DISPATCH_TOKEN
743 + repository_dispatch
744 + content-updated
745 + ```
746 +
747 + を確認します。
748 +
749 + Content Repository への Push だけでは Site Workflow は起動しません。
750 +
751 + ## `npm ci` で失敗する
752 +
753 + 生成 Workflow は、
754 +
755 + ```sh id="dtah4e"
756 + npm ci
757 + ```
758 +
759 + を利用します。
760 +
761 + そのため、
762 +
763 + ```text id="afg8hg"
764 + package-lock.json
765 + ```
766 +
767 + が Repository に Commit されているか確認してください。
768 +
769 + ## Content の Checkout で失敗する
770 +
771 + Private Content Repository の場合は、
772 +
773 + ```text id="9d9gdo"
774 + RIEBECKITE_CONTENT_READ_TOKEN
775 + ```
776 +
777 + を確認します。
778 +
779 + Site Repository の Workflow が、その Token を使って Content Repository を読み取れる必要があります。
780 +
781 + ## `check` で失敗する
782 +
783 + ```sh id="5jffy5"
784 + npm exec riebeckite check
785 + ```
786 +
787 + と同じ Command を手元でも実行します。
788 +
789 + Config や Plugin の問題を修正してから Push してください。
790 +
791 + ## `build` で失敗する
792 +
793 + 手元で、
794 +
795 + ```sh id="o2n6np"
796 + npm exec riebeckite build
797 + ```
798 +
799 + を実行して再現するか確認します。
800 +
801 + Repository を分離している場合は、CI と同じ場所に Content が存在することも確認してください。
802 +
803 + ## Cloudflare Deployment で失敗する
804 +
805 + Build までは成功している場合は、
806 +
807 + ```text id="rxagkm"
808 + CLOUDFLARE_API_TOKEN
809 + CLOUDFLARE_ACCOUNT_ID
810 + wrangler.jsonc
811 + ```
812 +
813 + を確認します。
814 +
815 + Riebeckite の Build と Cloudflare Deployment は別の段階なので、どちらで失敗したかを分けて調べると原因を特定しやすくなります。
816 +
817 + ## まとめ
818 +
819 + 通常の Site Repository では、
820 +
821 + ```text id="8p29zx"
822 + mainへpush
823 + ↓
824 + GitHub Actions
825 + ↓
826 + npm ci
827 + ↓
828 + riebeckite check
829 + ↓
830 + riebeckite build
831 + ↓
832 + Cloudflare Workers
833 + ```
834 +
835 + という流れになります。
836 +
837 + Content Repository を分離している場合は、
838 +
839 + ```text id="yt0pvq"
840 + Contentをpush
841 + ↓
842 + notify-site.yml
843 + ↓
844 + repository_dispatch
845 + ↓
846 + Site Workflow
847 + ↓
848 + ContentをCheckout
849 + ↓
850 + Build
851 + ↓
852 + Deploy
853 + ```
854 +
855 + となります。
856 +
857 + 特に覚えておきたいのは、
858 +
859 + ```text id="30lm4f"
860 + SITE_DISPATCH_TOKEN
861 + → ContentからSiteへ通知する
862 +
863 + RIEBECKITE_CONTENT_READ_TOKEN
864 + → SiteからContentを読む
865 +
866 + CLOUDFLARE_API_TOKEN
867 + CLOUDFLARE_ACCOUNT_ID
868 + → CloudflareへDeployする
869 + ```
870 +
871 + という役割の違いです。
872 +
873 + ### 関連資料
874 +
875 + - [Deployment Guides](./README.ja.md) — Deployment 方法の選択
876 + - [Cloudflare Workers](./cloudflare-workers.ja.md) — Cloudflare Workers の設定と手動 Deployment
877 + - [Separate Content Repository](./separate-content-repository.ja.md) — Content と Site を別 Repository で運用する
878 +