UTAF / 自走式ごみ箱 — 00
自分のPCの中にあるHTMLファイルを、世界中のブラウザから開ける状態にします。 Git・GitHub・Cloudflare の3つを順に通します。
デプロイとは、手元にあるファイルを、他人のブラウザから届く場所に置くことである。
いまあなたがこのページを読んでいるという事実が、この教材のゴールです。
このページは C:\Users\0yory\dev\utaf-trashbot\docs\00_git-github-cloudflare.html
という1つのファイルとして作られ、そこから3つの場所を経由して、あなたの画面に届いています。
この教材では、その3つの場所を順に通していきます。 手を動かす部分は、すべて実際に打ったコマンドと、実際に返ってきた文字をそのまま載せます。
「ファイルを他の人に見せたい」だけなら、もっと簡単な方法がいくつもあります。 OneDrive の共有リンクを送る、Google ドライブに置く、Slack に添付する。 それで足りる場面も実際にあります。
では、なぜこのプロジェクトではわざわざ Git・GitHub・Cloudflare を通すのか。 困りごとが4つあって、そのどれも上の方法では解決しないからです。
HTMLファイルは、ブラウザが読む設計図です。 OneDrive や Slack にHTMLファイルを置いてリンクを送ると、多くの場合 ブラウザはそれを「ページ」として表示せず、ダウンロードしてしまいます。 スマホだと特にそうなります。ダウンロードしたHTMLファイルをスマホで開くのは、かなり面倒です。
「ページとして表示する」ためには、ファイルを置いた場所が
「これはHTMLです」とブラウザに宣言してくれる必要があります。
この宣言を Content-Type と言います。あとで実物を見ます。
Cloudflare のような配信サービスは、この宣言をやってくれる場所です。
クラウドセッション(Anthropic 側のコンピュータで Claude を動かす仕組み)は、 手元のフォルダをアップロードして作業できます。ただし上限が100MBです。
UTAFフォルダの大きさを測ると、こうなりました。
1.3G C:\Users\0yory\OneDrive\Apps\UTAF
439M lerobot/
403M curriculum/
174M urdf/
63M slides/
47M materials/
ファイル数: 27958
1.3GB。上限の13倍です。物理的に送れません。
だから「ごみ箱プロジェクトだけの、軽い別フォルダ」を作る必要がありました。
これが C:\Users\0yory\dev\utaf-trashbot です。
この先で使う Git は、フォルダの中に .git という隠しフォルダを作って、
そこに履歴を全部しまいます。.git の中では、
何千個もの小さなファイルが、決まった順番で書き換わります。
OneDrive は「ファイルが変わったら同期する」サービスです。 この2つを重ねると、OneDrive が同期している最中に Git が次の書き換えを始めて、 履歴が壊れることがあります。 壊れ方が分かりにくいのが厄介で、「ある日突然、過去のコミットが読めなくなる」といった形で出ます。
だから C:\Users\0yory\dev\、つまり OneDrive の外 に置きました。
「バックアップが無くなるのでは」と思うかもしれませんが、逆です。
Git リポジトリのバックアップは GitHub が担います。しかも OneDrive より丁寧に、
「いつ・誰が・どの行を・なぜ変えたか」まで残ります。
クラウドセッションを使うと、Claude が勝手にファイルを書き換えていきます。 同時に自分も書き換えます。何本も並列で走らせると、同じファイルを2人(2セッション)が触ります。
このとき 「最新版はどれか」を決める仕組みが無いと、 後から保存した方が前の作業を消します。 Git は、この衝突を検出して「両方残したうえで、どう混ぜるか決めろ」と言ってくれます。 実際に今日それが起きたので、あとで実例として出します。
まとめると ── HTMLをページとして配信するため(1)、クラウドセッションに送れる大きさにするため(2)、 履歴を壊さないため(3)、同時編集の衝突を解決するため(4)。 この4つのために、3つの場所を通します。
通る場所は3つです。それぞれ役割がはっきり違います。
| 場所 | 役割 | これが無いと |
|---|---|---|
| ① Git (手元) |
変更の履歴を記録する | いつ何を変えたか分からない。衝突したとき直せない |
| ② GitHub (ネット上) |
履歴を預ける。他の人やクラウドセッションがそこを読む | 自分のPCを開いている間しか作業できない |
| ③ Cloudflare (ネット上) |
HTMLをページとして配信する | URLが存在しない。スマホで開けない |
.git という隠しフォルダに入っています。
ここで引っかかりやすいのが、「保存」と「コミット」は別物だという点です。 エディタで Ctrl+S を押すのは「保存」です。ファイルが書き換わります。 でもその時点では、Git は何も記録していません。
コミットは、自分で「いまの状態を記録しろ」と命令したときだけ作られます。 つまり Git の履歴は、自動では増えません。 これは不便に見えますが、意図があります。 「意味のある区切り」でだけ記録したいからです。
今日このリポジトリを作ったときのコマンドを、全部そのまま載せます。 1行ずつ意味を見ていきます。
cd /c/Users/0yory/dev/utaf-trashbot
git init -b main
git config user.name "Half-and-Half-run"
git config user.email "263915778+Half-and-Half-run@users.noreply.github.com"
git add -A
git commit -m "プロジェクトの土台を作る"
いまいるフォルダをリポジトリにします。.git フォルダがここで作られます。
実行前は、こう言われます。
fatal: not a git repository (or any of the parent directories): .git
「ここはリポジトリじゃない」という意味です。
.git が無いので履歴を記録する場所が無い、と言っています。
このエラーを見たら git init を忘れています。
-b main は「最初のブランチの名前を main にする」という指定です。
main は「本線」という意味の慣習的な名前です。
ブランチが複数あると、本線を壊さずに実験できます。
クラウドセッションは作業ごとに別のブランチを作って、
あとで本線に合流させる(これをマージと言います)形で動きます。
-b main を付けないと、Git のバージョンによって master という名前になります。
GitHub 側が main を標準にしているので、合わせておかないと後で名前の食い違いが起きます。
コミットには「誰が作ったか」が必ず刻まれます。その名前とメールアドレスの設定です。
ここで実際に問題が起きました。設定を確認したら、こうなっていました。
$ git config --global user.name
Half-and-Half-run
$ git config --global user.email
your-email@example.com
メールアドレスが your-email@example.com、つまり初期値のままでした。
このままコミットすると、履歴に存在しないアドレスが永久に残ります。
ではどのアドレスを入れるか。ここに落とし穴があります。 コミットに刻まれたメールアドレスは、リポジトリを公開した瞬間に誰でも読めます。 しかも履歴なので、あとから消すのが非常に面倒です。
そのための仕組みが GitHub にあります。noreply アドレスです。
263915778+Half-and-Half-run@users.noreply.github.com
↑ ↑
ユーザーID ユーザー名
これは GitHub が用意している「あなた専用だが、個人のメールではない」アドレスです。 GitHub 側ではあなたのアカウントと紐づくので、コミットは正しくあなたのものとして表示されます。 でも個人の Gmail は漏れません。
なぜ --global を付けなかったか。
--global を付けると、そのPCの全リポジトリに適用されます。
付けないと、いまいるリポジトリだけの設定になります。
今回は「このリポジトリだけ noreply にする」という判断なので、付けていません。
ここが、Git を初めて触る人が一番つまずく場所です。
git add は「次のコミットに含めるファイルを選ぶ」命令です。
-A は「全部」という意味です。
この選ぶ場所のことを ステージング(staging) と言います。
なぜ2段階に分かれているのか。 10個のファイルを直したけれど、そのうち3個だけを「この修正」として記録したい、 ということが実際にあります。残り7個は別の作業なので、別のコミットにしたい。 ステージングがあると、それができます。
1段階だと「直したもの全部が、まとめて1つの記録になる」しかなく、 あとから履歴を読んだときに「このコミット、何をしたやつだ?」が分からなくなります。
ステージングに乗っているものを、履歴に刻みます。
-m はメッセージの指定です。このメッセージが履歴に残り、
あとから「何をしたコミットか」を読む唯一の手がかりになります。
実行すると、こう返ってきました。
warning: in the working copy of 'CLAUDE.md',
LF will be replaced by CRLF the next time Git touches it
04a4c61 プロジェクトの土台を作る
04a4c61 がコミットの名前です。コミットハッシュと言います。
中身から機械的に計算された文字列で、世界中で重複しません。
「あのときの状態に戻したい」と言うとき、この7文字で指定します。
上に出ている warning は、放っておいて構いません。
ただ必ず出るので、意味を知っておくと驚かずに済みます。
テキストファイルの「改行」は、見えない文字で表されています。 そしてこの文字が、OS によって違います。
| 書き方 | 中身 | 使うOS |
|---|---|---|
| LF | 改行を1文字で表す | Linux / macOS |
| CRLF | 改行を2文字で表す | Windows |
Git は履歴の中では LF で統一し、Windows のフォルダに取り出すときは CRLF に戻します。 その変換が起きることを教えてくれているだけです。 ファイルが壊れるという警告ではありません。
push で送り、fetch で受け取れます。
慣習で origin という名前を付けます。
ここで大事なのは、GitHub は「バックアップ置き場」ではないということです。 履歴ごと預かる場所なので、GitHub 側でも「誰がいつ何の行を変えたか」が全部読めます。 そしてクラウドセッションは、あなたのPCではなくGitHub を読んで作業します。
これが重要な帰結を持ちます。 push していない変更は、クラウドセッションには存在しません。 手元でどれだけ書いても、push するまでクラウドの Claude には見えません。
gh repo create utaf-trashbot --private --source=. --push
| 部分 | 意味 |
|---|---|
gh | GitHub を操作するコマンド。GitHub CLI という道具 |
repo create | ネット上に新しいリポジトリを作る |
utaf-trashbot | リポジトリの名前 |
--private | 非公開にする。これが無いと公開になる |
--source=. | いまいるフォルダを中身として使う |
--push | 作ったあと、履歴をすぐ送る |
このリポジトリは --private にしました。理由は、
プロジェクトの仕様書に予算と部品単価とメンバーの名前が入っているからです。
コード自体は公開して困るものではありませんが、公開する理由も特にありません。
判断の基準は「公開して困るものが1つでも入っているか」です。1つでもあれば private です。
後から gh repo edit --visibility public で公開に切り替えられるので、
迷ったら private にしておくのが安全です。逆向き(公開→非公開)は手遅れです。
一度公開されたものは、誰かが既にコピーしている可能性を消せません。
上のコマンドを実行したら、こう返ってきました。
GraphQL: Name already exists on this account (createRepository)
「その名前はこのアカウントに既にあります」。
つまり utaf-trashbot がすでに作られていたということです。
ここで絶対にやってはいけないのが、無理に上書きすることです。 中に何が入っているか分からないまま上書きすると、他人の作業を消します。 なので、まず中を見ます。
$ gh api repos/Half-and-Half-run/utaf-trashbot/commits \
--jq '.[] | "\(.commit.author.date) \(.commit.author.name) \(.commit.message)"'
2026-10-28T10:29:25Z Ryouji Kawashima Update project name in CLAUDE.md
2026-10-28T10:21:51Z Half-and-Half-run プロジェクトの土台を作る
読めたことはこうです。
プロジェクトの土台を作る は、手元で作ったコミットと同じもの。つまり誰かが push 済みUpdate project name in CLAUDE.md は、手元には無いコミット。
GitHub の画面で直接編集されたものつまり 手元とネット上で、履歴が枝分かれしていた状態です。
状況を図にすると、こうです。
やってはいけないのは git push --force です。
これは「手元の履歴で、ネット上の履歴を上書きしろ」という命令です。
実行すると 上の枝(本人の手編集)が消えます。
正しい手順は、まず相手の枝を取ってきて、自分の変更をその上に載せ直すことです。 これを リベース(rebase) と言います。
git remote add origin https://github.com/Half-and-Half-run/utaf-trashbot.git
git fetch origin
git merge-base HEAD origin/main
04a4c61b3cc1f94792389e6b4955ba6b6c209958
git rebase origin/main
Successfully rebased and updated refs/heads/main
| コマンド | やっていること |
|---|---|
git remote add origin … |
ネット上の置き場所を origin という名前で登録する |
git fetch origin |
相手の履歴を取ってくる。手元のファイルはまだ変わらない |
git merge-base HEAD origin/main |
「どこから枝分かれしたか」を調べる。共通の土台を教えてくれる |
git rebase origin/main |
自分のコミットを、相手の枝の先に載せ直す |
fetch で手元のファイルが変わらない、という点は覚えておく価値があります。
「取ってくるだけ」と「手元に反映する」が分かれているので、
取ってきて中を見てから、どうするか決められます。
リベース後の履歴を確認すると、こうなりました。
$ git log --oneline
bc3b384 公開先を Cloudflare Pages にする ← 自分の変更が上に乗った
61e8def Update project name in CLAUDE.md ← 本人の手編集が残っている
04a4c61 プロジェクトの土台を作る
$ grep -n "Autonomy Forge" CLAUDE.md
5:UTAF(The University of Tokyo Autonomy Forge)のプロジェクト。
一直線になりました。本人が直した The University of Tokyo も残っています。
どちらの作業も失われていません。 これがリベースの目的です。
原則として覚えておくこと。
人が手で直したものは、機械が作ったものより優先します。
--force で押し流す前に、必ず fetch して中を見る。
これは Git の作法というより、共同作業の作法です。
ここが見落としやすい点です。claude.ai と GitHub を連携しても、 private リポジトリはそれだけでは読めません。
理由は、GitHub の権限の仕組みにあります。 「あなたのアカウントと繋がっている」ことと、 「このリポジトリを読んでよい」ことは別の許可だからです。 後者は GitHub App という単位で、リポジトリごとに与えます。
だから private リポジトリでクラウドセッションを使うには、 Claude GitHub App をそのリポジトリに入れる必要があります。 同じ理由で、Cloudflare にも Cloudflare 用の GitHub App を入れました。 サービスごとに別のアプリで、別に許可します。
アプリを入れるとき、どのリポジトリに許可するか選びます。
| 選択 | 意味 | 向いている場面 |
|---|---|---|
| Only select repositories |
選んだリポジトリだけ | private リポジトリが複数あり、片方だけ見せたいとき |
| All repositories | 全部。今後作るものも自動で含む | private が1つだけ、または全部そのサービスで使うとき |
判断の材料は 「private リポジトリがいくつあるか」 です。
公開リポジトリはもともと誰でも読めるので、許可しても実質的に何も増えません。
今回のアカウントは private が utaf-trashbot の1つだけだったので、
All repositories でも実質的な差がありませんでした。
Cloudflare で静的なサイトを公開する方法は、長く Cloudflare Pages でした。
UTAF の既存の教材サイト(utaf-curriculum.pages.dev)もこれです。
ところが今回 Pages を選ぼうとしたら、画面に legacy と出ました。
調べると、Cloudflare は新規プロジェクトには Workers を勧めるようになっていました。
Pages は既存プロジェクトのために維持されるものの、新しい機能は追加されません。
廃止日は発表されていませんが、今から新しく作るなら Workers 側が正解です。
| Pages | Workers(Static Assets) | |
|---|---|---|
| 立場 | 既存プロジェクトの維持 | 新規はこちら |
| 公開するフォルダの指定 | 画面で Build output directory に入力 |
リポジトリの wrangler.jsonc に書く |
_headers | 使える | 使える |
| 料金 | 無料枠あり | 静的ファイルの配信は無料 |
この違いが、画面を見たときの混乱の原因になります。
Workers の画面には Build output directory という欄がありません。
代わりに Deploy command が出ます。
「設定する場所が、画面からリポジトリの中のファイルに移った」と理解してください。
これがリポジトリ直下に置いたファイルの全文です。これだけです。
{
// docs/ の中身をそのまま配信するだけの設定。
// Worker のコード(main)は書かない。静的ファイルだけを公開する。
"name": "utaf-trashbot",
"compatibility_date": "2026-10-28",
"assets": {
"directory": "./docs"
}
}
| 行 | 意味 | 間違えると |
|---|---|---|
"name" |
Worker の名前。URL になる(utaf-trashbot.〇〇.workers.dev) |
画面で作った名前と違うと、Worker が2つできる |
"compatibility_date" |
「この日の Cloudflare の挙動で動かす」という固定。作った日を入れる | 無いとデプロイが拒否される |
"assets". |
配信するフォルダ。./docs を指定 |
./ にすると README.md や CLAUDE.md まで公開される |
ふつうの JSON ファイルには コメントが書けません。
// から始まる行を入れると、読み込みに失敗します。
.jsonc は「コメントを書ける JSON」です(c は comment)。
上のファイルの1行目と2行目がコメントです。
設定ファイルは、半年後の自分が読んで意味が分からなくなりがちなので、
コメントが書ける形式を選んでいます。
Workers は本来、プログラムを動かす仕組みです。
リクエストが来たら何か計算して返す、という処理を書けます。
その処理を書いたファイルを main で指定します。
今回は main を書いていません。
教材はただのHTMLファイルで、計算する必要が無いからです。
assets だけを書くと、「ファイルをそのまま返すだけの Worker」になります。
教材が8枚とも「未作成」の状態で Google の検索結果に出てしまうと、 困ります。中身が無いページが「UTAF 教材」として見つかってしまいます。
これを防ぐのが _headers です。
docs/ の中、つまり配信するフォルダの直下に置きます。
/*
X-Robots-Tag: noindex
| 行 | 意味 |
|---|---|
/* | どのURLに適用するか。* は「何でも」なので全ページ |
| (字下げした行) | 付けるヘッダ。字下げが必須。無いとURL指定と解釈される |
X-Robots-Tag: noindex |
検索エンジンに「この内容を検索結果に載せないで」と伝える |
大事なのは、これは「見られなくする」設定ではないということです。 URL を知っている人は普通に読めます。検索から見つからなくなるだけです。 この状態を「限定公開」と呼んだりします。
完成して人に広めてよくなったら、このファイルを消します。 それだけで検索に載るようになります。
Worker name : utaf-trashbot ← wrangler.jsonc の name と揃える
Branch : main
Build command : (空欄)
Deploy command : npx wrangler deploy
Root directory : / ← docs にしてはいけない
Root directory を docs にしてしまうのが、ありがちな間違いです。
「公開したいのは docs だから」と思ってしまいますが、逆です。
Root directory は 「wrangler.jsonc がどこにあるか」の指定です。
設定ファイルはリポジトリ直下にあるので / です。
そして公開するフォルダは、その設定ファイルの中で ./docs と指定済みです。
役割が二重になっているように見えて、実は別の話です。
npx wrangler deploy は、wrangler(Cloudflare を操作する道具)を
事前にインストールしていなくても、その場で取ってきて実行してくれます。
初回だけ時間がかかるのはこのためです。
ここまでで utaf-trashbot.kubokubo456z.workers.dev が動きました。
読めますが、人に口で伝えるには長すぎます。
learn.utaf.dev にします。
learn.utaf.dev のような名前を、
サーバーの住所(IPアドレス)に変換する仕組み。
電話帳のようなものです。ブラウザは、名前を打たれたらまず DNS に住所を聞きに行きます。
utaf.dev の前に付ける名前。
learn.utaf.dev の learn の部分です。
ドメインを1つ持っていれば、サブドメインは好きな数だけ無料で作れます。
UTAF のウェブサイト(www.utaf.dev)を設定したときのメモが残っていました。
Type: CNAME
Name: www
Target: 1fdfc120acf8c45d.vercel-dns-017.com
Proxy status: DNS only ← グレーの雲にする
このときは、Vercel という別のサービスが出した住所を、
手でコピーして Cloudflare に入力しました。
CNAME は「この名前は、別の名前と同じ場所を指す」という種類のレコードです。
今回はこの作業が要りませんでした。理由は、 ドメインと配信先が同じ Cloudflare アカウントの中にあるからです。 Cloudflare 側で「このドメインは自分が管理している」と分かるので、 カスタムドメインを追加した瞬間に、必要なレコードを自分で作ります。
実際、追加した直後に確認したらこうなっていました。
$ nslookup learn.utaf.dev
Name: learn.utaf.dev
Addresses: 2606:4700:3033::6815:3fa4
2606:4700:3034::ac43:ab10
住所が返ってきました。手で何も入力していません。
新しいサブドメインを足した直後は、証明書の発行がまだ終わっていないことがあります。 その間は https で繋がりません。数分から十数分で発行されます。 実際に確認したら、こうなっていました。
$ echo | openssl s_client -connect learn.utaf.dev:443 \
-servername learn.utaf.dev
depth=2 C=US, O=Google Trust Services LLC, CN=GTS Root R4
depth=1 C=US, O=Google Trust Services, CN=WE1
depth=0 CN=utaf.dev
verify return:1
verify return:1 は「検証が通った」という意味です。
発行は終わっていました。
ところが、同じタイミングでページを取ろうとすると失敗しました。
$ curl -s -o /dev/null -w "status=%{http_code}\n" https://learn.utaf.dev/
status=000
status は、サーバーが返す3桁の番号です。
200 なら成功、404 ならページが無い、500 ならサーバーの故障。
ところが 000 は、そのどれでもありません。
000 は「サーバーまで届かなかった」という意味です。
番号を返してもらう前の段階で失敗しています。
つまりサイトの問題ではなく、繋ぐ経路の問題です。
原因を切り分けるために、経路を変えて試しました。
$ curl -s -4 -o /dev/null -w "status=%{http_code}\n" https://learn.utaf.dev/
status=200
通りました。-4 は「IPv4 で繋げ」という指定です。
192.0.2.1 のような形、IPv6 は 2606:4700:… のような形です。
住所が足りなくなったので新しい書き方(IPv6)が作られましたが、
両方が混在して使われています。
先の nslookup の結果を見返すと、返ってきた住所は IPv6 だけでした。
そして確認に使った環境は IPv6 の経路が通っていなかった。
サイトは最初から正常で、こちらの環境の問題だったというだけの話です。
ここから学べること。 エラーが出たとき「何が壊れたか」を決めつける前に、条件を1つだけ変えて試す。 今回変えたのは経路(IPv6 → IPv4)だけです。 それで結果が変わったので、「サイトではなく経路が原因」と確定できました。 これは切り分け(isolation)といって、あらゆるデバッグの基本です。
$ curl -sI -4 https://learn.utaf.dev/
HTTP/1.1 200 OK
Content-Type: text/html
x-robots-tag: noindex
CF-RAY: a5196c1ec86de358-NRT
| 行 | 何が分かるか |
|---|---|
200 OK | 正常に返っている |
Content-Type: text/html |
「これはHTMLです」という宣言。 これがあるからブラウザがページとして表示する。困りごと1の答え |
x-robots-tag: noindex |
docs/_headers が効いている。検索に出ない |
CF-RAY: …-NRT |
どこのサーバーが返したか。NRT は成田、つまり東京。
だから速い(0.1秒) |
この4行が揃っていれば、公開は完了しています。
読むだけでは身に付かないので、実際に1行変えて、結果を見てください。 どれも元に戻せます。
docs/index.html を開いて、見出しの下の1行を探します。
<p class="lede">TurtleBot3 を土台に、呼ぶと来るごみ箱ロボットを作る。…</p>
この文の最後に、自分の名前でも何でもいいので1単語足してください。そして:
git add -A
git commit -m "確認用に1行変える"
git push
1〜2分待って、スマホで learn.utaf.dev を開き直します。
足した単語が出ていれば、自動反映が効いています。
出てこないなら Git 連携ができていないので、Cloudflare の
Settings → Build を見てください。
これは演習というより、仕組みが繋がっているかの検査です。 一番最初にやる価値があります。
wrangler.jsonc の directory を "./" に変えて push します。
"assets": {
"directory": "./" ← ./docs から変える
}
反映されたら learn.utaf.dev/CLAUDE.md を開いてみてください。
作業ルールが全世界に読めるようになっています。
これが docs/ を切り分けている理由です。
「公開するもの」と「リポジトリに置くもの」は別だという前提で作られています。
確認したら "./docs" に戻して push してください。
docs/_headers に1行足します。
/*
X-Robots-Tag: noindex
X-UTAF-Test: hello
push して反映されたら、こう確認します。
curl -sI https://learn.utaf.dev/
x-utaf-test: hello が出てくれば、
自分でヘッダを足せたということです。
字下げを忘れると効かないので、そこも試してみてください。
確認したら足した行を消します。
今日実際に出たものを、全部そのまま載せます。
fatal: not a git repository (or any of the parent directories): .git
git init をしていないフォルダで git のコマンドを打つと出ます。
あるいは、別のフォルダにいます。
pwd(いまどこにいるか表示)で場所を確かめてください。
GraphQL: Name already exists on this account (createRepository)
同じ名前のリポジトリが既にあります。
消す前に中を見てください。自分で作ったのを忘れているか、
誰かが作っています。確認は gh repo view 名前 と
gh api repos/所有者/名前/commits です。
$ curl -s -o /dev/null -w "status=%{http_code}\n" \
https://learn.utaf.dev/00_git-github-cloudflare.html
status=307
これは失敗ではありません。
307 は「その住所は別の住所に移った」という意味の返事です。
Cloudflare Workers は既定で、URLから .html を外した形を正式なURLにします。
つまり本当のURLはこちらです。
https://learn.utaf.dev/00_git-github-cloudflare
.html を付けて開いても、自動でこちらに連れて行かれるので問題ありません。
ただし curl で確認するときは -L
(リダイレクトを追う)を付けないと 307 で止まります。
これを知らずに「200が返らない=デプロイ失敗」と判断すると、
動いているものを壊しに行くことになります。
$ curl -sS -L -o /dev/null -w "%{http_code} %{url_effective}\n" \
https://learn.utaf.dev/00_git-github-cloudflare.html
200 https://learn.utaf.dev/00_git-github-cloudflare
返事の番号は3桁の最初の数字で大きく分かれます。
2xx は成功、3xx は移動、4xx はこちらの間違い、
5xx は向こうの故障。3xx を失敗と数えないこと。
status=000
サーバーまで届いていません。サイトの故障ではなく経路の問題です。
-4 を付けて IPv4 で試す、別の回線で試す、数分待つ。
証明書の発行待ちでも同じ症状になります。
壊れていません。Workers の画面を見ています。
その役目は wrangler.jsonc の assets.directory が引き受けています。
画面には Deploy command が出ているはずなので、
そこに npx wrangler deploy と入れてください。
wrangler.jsonc が見つからず、デプロイが失敗します。
Root directory は「設定ファイルの場所」で、
「公開するフォルダ」ではありません。/ に戻してください。
warning: in the working copy of 'CLAUDE.md',
LF will be replaced by CRLF the next time Git touches it
無視してよい警告です。改行文字の書き方が Windows と Linux で違うので、変換が起きることを教えているだけです。 ファイルは壊れません。Windows で Git を使うと、ほぼ毎回出ます。
push していないからです。
クラウドセッションはあなたのPCではなく GitHub を読みます。
手元にしか無いコミットは、存在しないものとして扱われます。
クラウドに作業を投げる前に git push してください。
docs/_template.html は、
新しい教材を作るときの雛形です。配色とスマホ対応が最初から入っています
CLAUDE.md にあります。
クラウドセッションは毎回これを読んでから着手します