fix(pages): favicon SVG 同梱 + post-deploy 404 検知 gate を追加 - #585
Conversation
GitHub Pages 上で /piper-plus/favicon.ico が 404 を返し、 ブラウザの自動 fetch がコンソールエラーとして可視化されていた (Failed to load resource: status 404 / favicon.ico:1)。 これは <link rel="icon"> 不在による defacto auto-fetch であり、 HF Space の sdk_version drift と同じく「CI / deploy 工程は通っているが利用時に 初めて顕在化する」 silent failure。 deploy-pages は upload が通れば常に green、 deploy 後に live URL を確認していなかったため気付けなかった。 修正: - SVG favicon (304B、 #4CAF50 アクセント + 音声バーモチーフ) を新規作成 - 多言語デモ HTML に <link rel="icon" type="image/svg+xml"> を追加 - deploy workflow に .nojekyll 同梱を追加 (underscore-prefix 抑止) - pre-deploy gate: bundle 内の必須 artifact + favicon link 不在を fail-fast - post-deploy gate: live URL を HEAD probe、 404 が 1 件でも残れば deploy 失敗 verify_pages_assets.py は HF Space の verify_hf_space_runtime.py と同一哲学。 favicon.ico 自体は要求しない (<link rel=icon> 付与で auto-fetch は抑止される、 binary blob を repo に commit する必要なし)。
Action SHA drift reportCollected pins (3 actions) — expected_total_pins=3
Summary: total=3, ok=3 |
Required status-check gate (deferred)Head SHA |
There was a problem hiding this comment.
Pull request overview
GitHub Pages デプロイ後に初めて顕在化する “silent 404” を防ぐため、favicon を明示同梱しつつ、デプロイ前後でアセット存在確認を行う CI ゲートを追加する PR です(Pages での favicon.ico 自動 fetch 404 を根本的に解消し、再発も検知)。
Changes:
- SVG favicon を追加し、デモ HTML に
<link rel="icon">を明示 - Pages デプロイ bundle に
.nojekyllを追加して Jekyll の自動処理を無効化 - Pre-deploy の bundle 完全性チェックと、Post-deploy の live URL HEAD probe 検証スクリプトを追加
Reviewed changes
Copilot reviewed 3 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/wasm/openjtalk-web/test/multilingual-demo/index.html | favicon の <link rel="icon"> を追加 |
| src/wasm/openjtalk-web/assets/favicon.svg | 新規 SVG favicon を追加 |
| scripts/verify_pages_assets.py | Pages の post-deploy 検証(HEAD probe + retry)を新設 |
| .gitignore | 新設スクリプトを ignore 例外に追加 |
| .github/workflows/deploy-webassembly-demo.yml | .nojekyll 追加、pre/post deploy ゲートを追加 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Runtime Parity Deep — audio (informational tier)Pairs compared: 15, failing: 13, runtimes skipped: 0.
|
Bundle size gate
Summary: 0 fail / 6 skip / 0 ok SKIP means the artifact was not built in this job, or the baseline is a placeholder. The gate never fails on SKIP. |
Multi-Runtime RTF BenchmarkPolicy: warn-only (thresholds: RTF +/-10%, P50 +/-10%, P95 +/-15%) Model:
|
1. scripts/verify_pages_assets.py
- verify() に渡された Iterable を tuple() で materialize してから for ループ
- 旧コードは for で消費した後 len(list(paths)) を再評価しており、
caller が generator を渡すと success 行が「OK: all 0 assets」と誤報する
- caller は現状 list を渡しているので無症状だが contract 上のバグ。
generator を渡した unit test で 0→正数になることを確認
2. .github/workflows/deploy-webassembly-demo.yml (pre-deploy gate)
- REQUIRED 配列に deploy/multilingual-demo/index.html を追加
- 旧コードの favicon-link 検証 for ループは
`for html in ... deploy/multilingual-demo/*.html` で
subdir が空 / 不在の場合 glob が literal のまま残り `[ -f ]` で全件 skip。
結果 pre-deploy gate が favicon 検証「0 件」で silent pass する穴があった
- shopt -s nullglob で空配列に展開し、 ${#HTMLS[@]} -lt 3 を assert。
subdir absent / empty / populated の 3 scenario をローカルで検証済み
PR #585 で追加した pre-deploy gate が初回デプロイで favicon-<link> 不在を 4 件検出 (multilingual.html / piper-espeak-{complete,english}.html / simple-multilingual.html)。 gate が gate として機能したケース。 PR #585 では index.html のみに <link rel="icon"> を追加していたため、 deploy bundle にコピーされる他の demo HTML 4 個では browser auto-fetch による favicon.ico 404 が残る状態だった。 root cause を直す (gate を緩める band-aid は採らない、 feedback_no_band_aid_fixes)。 5 個全 HTML が deploy 後に <link rel="icon" type="image/svg+xml" href="../../assets/favicon.svg"> を持ち、 deploy 側 sed で multilingual-demo/ subdir 配置の場合は ../assets/favicon.svg に 正しく書き換わる。
Summary
GitHub Pages (
https://ayutaz.github.io/piper-plus/) のブラウザコンソールにfavicon.ico:1 Failed to load resource: 404が出続けていた。 HTML に<link rel="icon">が無く、 ブラウザの defacto auto-fetch が/favicon.icoを 404 にしていた状態。 HF Space のsdk_versiondrift と同じ「deploy 工程は green / 利用時に初めて顕在化する」silent failure で、 deploy 後の live URL 検証が無いことが根本原因。Affected Components
Type
Risk Level
Contract Impact
docs/spec/*.tomlへの影響なし。 deploy bundle と CI gate のみの変更で、 ランタイム / API / 音響パリティに変更なし変更内容
src/wasm/openjtalk-web/assets/favicon.svg(304B、#4CAF50アクセント + 音声バーモチーフ) を deploy bundle に同梱/favicon.icoauto-fetch が 404 を返し、 コンソールに毎ロード 2 行のエラーが残る<link rel="icon">明示multilingual-demo/index.html(および sed 経由で deploy 後のindex.html/404.html/multilingual-demo/index.html) に<link rel="icon" type="image/svg+xml" href="../../assets/favicon.svg">を追加/favicon.icoが走り 404 を出す.nojekyll同梱deploy/.nojekyllを deploy 直前にtouch_始まりの将来追加ファイル / ディレクトリを silently filter する潜在リスクdeploy/.nojekyll/deploy/assets/favicon.svg/ 主要 JS/WASM の存在を bundle build 直後にチェック。 全 HTML に<link rel="icon">が含まれることも検証scripts/verify_pages_assets.py新設)actions/deploy-pages完了後に live URL を HEAD probe、 主要 14 アセットいずれかが non-2xx で deploy job を fail させる (リトライ 6 回 / 15s 間隔で Pages の伝播ラグを吸収)deploy-pagesは upload accept で常に green。 live URL の 404 が誰かが画面を開くまで気付かれない (今回の favicon 404 と同じ failure mode)設計判断
<link rel="icon">が存在すれば Chrome/Firefox/Safari は/favicon.icoの auto-fetch を抑止するため、 binary blob の commit は不要。 SVG 1 ファイルで完結し grep / diff 可能#4CAF50の音声バー (4 本): ページ内アクセント色と一致、 16×16 でも判別可能、 既存etc/logo.svg(横長バナー、 favicon としては不適) と用途分離verify_hf_space_runtime.py) と統一: deploy-pages / upload_folder の non-deterministic な「accept 後の build / 配信」 phase を post-deploy で polling、 silent 404 / BUILD_ERROR を即 CI red に昇格。 同じ機構を pages / HF Space で重複させ単一抽象化しないのは、 retry / poll / 完了判定の semantics が両者で異なるため (HF は stage 名で判定、 Pages は HTTP code)--retries 6 --retry-delay-seconds 15= 約 90 秒の伝播ラグ吸収。 Pages CDN cache invalidation が稀に 30-60 秒かかる事例を考慮、 余裕を持って 90 秒。 これ以上長くすると本物の broken deploy 検出が遅れる/favicon.ico自体は post-deploy gate の必須リストから除外:<link rel=icon>付与で auto-fetch は抑止される定説に依拠。 仮に一部古い browser で fetch が残っても機能影響ゼロ (single 404 の cosmetic noise) なので binary 追加コストに見合わないTest Plan
python scripts/verify_pages_assets.py --base-url https://ayutaz.github.io/piper-plus --retries 0をローカル実行し、 現状 (favicon.svg 未配信) で 2 件の FAIL が出ることを確認 (PR merge 前)python scripts/verify_pages_assets.py --base-url https://ayutaz.github.io/piper-plus --retries 6を PR merge → deploy 完走後 に再実行し、 全 13 アセット 2xx を確認https://ayutaz.github.io/piper-plus/をブラウザで開き、 DevTools console にfavicon.ico/Failed to load resourceの 404 が 出ないこと を確認assets/favicon.svgが 200 で読まれていることを確認python - <<<'import yaml; yaml.safe_load(open(".github/workflows/deploy-webassembly-demo.yml"))'で YAML 構文健全性確認python -m py_compile scripts/verify_pages_assets.pyで syntax 確認Deploy WebAssembly Demo to GitHub Pagesworkflow が Pre-deploy gate / Post-deploy verification の両ステップで全 200 を返して greenChecklist
.gitignoreの allowlist に新 script を登録済みRelated Issues
なし (本 PR が PR #583 の HF Space 修正に続く「deploy 後の live 検証」フェーズの GitHub Pages 版)