0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

「公開できる」を自動判定する――Release Gateを組み立てる【第45回】

0
Last updated at Posted at 2026-09-24

4Hえんぴつ|React+TypeScriptでWeb RPGを作る
第8章「Web公開・互換性・永続化」
第45回:「公開できる」を自動判定する――Release Gateを組み立てる

連載トップ・第0回はこちら

1. 「全部だいたい大丈夫」では公開判定できない

ここまで、

  • セーブ互換性
  • 破損セーブ復旧
  • IndexedDB
  • Vitest
  • Playwright
  • Chromium/WebKit
  • スマートフォン
  • SPA fallback
  • production E2E
  • rollback

まで確認してきました。

一つひとつは動いています。

しかし、正式公開するときに、

セーブも大丈夫そう
E2Eも通っていた
スマートフォンも見た
rollbackも確認した

という記憶だけで、

「公開してよい」と判断するのは危険です。

そこで最後に、

必要な確認がすべてPASSしたときだけ、正式公開へ進める

というRelease Gateを作りました。


2. Release Gateは最後にテストを増やす仕組みではない

Release Gateというと、

公開直前に新しい巨大なテストを実行するようにも見えます。

今回の考え方は少し違います。

これまで作ってきた、

Unit / Integration
E2E
Browser
Device
Hosting
Rollback
Artifact

という確認結果を、

一つの公開判定へ集約する

仕組みです。

つまり、

個別の品質確認
↓
Release Gate
↓
公開可否

という関係です。


3. 最初にクリーンな状態から確認する

公開判定では、

開発者のPCに残っている状態へ依存したくありません。

例えば、

以前installしたnode_modules
過去のbuild成果物
一時ファイル
ローカルだけの状態

があると、

本当は再現できない候補が動いているように見えることがあります。

そのため、

まずクリーンな依存関係から確認します。

正式公開判定では、

clean npm ci
↓
PASS

を確認しました。


4. Vitestだけ通っても公開はしない

次に、

ユニット/統合テストです。

正式候補では、

Vitest
7 / 7 files
68 / 68 tests

がPASSしました。

しかし、

ここで、

68件通った
↓
公開

とはしません。

Vitestが確認しているのは、

品質全体の一部分だからです。


5. 型チェックも独立したGateにする

テストが通っていても、

TypeScript上の問題が残っている可能性があります。

そのため、

application typecheck
↓
PASS

E2E typecheck
↓
PASS

を別に確認します。

アプリ本体だけでなく、

テストコード自身も型チェック対象

にしています。


6. lintとproduction buildも必要になる

さらに、

lint
↓
PASS

を確認します。

そして、

開発サーバーで動くことではなく、

実際に公開する形式へbuildできることも確認します。

production build
↓
PASS

です。

ここで初めて、

公開候補となる成果物を作れます。


7. 依存関係の監査もGateへ入れる

アプリコードが正常でも、

依存パッケージ側に問題がある可能性があります。

そのため、

正式公開判定では、

npm audit
↓
0 vulnerabilities

npm audit --omit=dev
↓
0 vulnerabilities

も確認しています。

つまり、

アプリが動く

だけでなく、

依存関係も含めて公開候補を確認する

ようにしました。


8. ブラウザE2EもRelease Gateの一部にする

第38~40回で扱ったPlaywrightも、

最終判定へ入ります。

正式公開候補では、

Chromium
15 / 15 PASS

WebKit + iPhone emulation
7 / 7 PASS

でした。

これによって、

ロジックとして正しい

だけでなく、

実際のブラウザで
プレイヤー操作として成立する

ことを確認します。


9. console/pageerrorも0件を要求する

シナリオが最後まで通っても、

内部でエラーが発生していてはいけません。

そこで、

console warning/error
↓
0

pageerror
↓
0

もGateへ入れます。

つまり、

画面上では遊べた

だけでPASSにはしません。

ブラウザ内部でも想定外の問題が発生していない

ところまで確認します。


10. localhostだけでなくproductionもGateにする

第43回では、

同じ候補を、

local hostingとproduction hostingの両方で確認しました。

正式判定では、

local production-hosting
7 / 7 PASS

production hosting
7 / 7 PASS

です。

この7項目には、

直URL、

再読み込み、

未知URL、

期限切れURL、

console/pageerror、

セーブからの復帰

などが含まれています。

つまり、

本当に公開される場所で動いたこと

も正式公開の条件です。


11. rollbackもPASSして初めて「出せる」と考える

第44回では、

初回リリースでも戻れるように、

INITIAL_RELEASE_ANCHOR

を作りました。

そして、

anchor確認
↓
一時Publish
↓
fresh session確認
↓
元deployへ復元
↓
復元後hosting 7 / 7 PASS

まで確認しました。

Release Gateでは、

公開できる

だけではなく、

問題があれば戻れる

ことも条件にします。


12. Blocker/Highが0であることを確認する

テストがすべてPASSしていても、

未解決Issueに重大な問題が残っている可能性があります。

そこで、

新規Blocker
↓
0

新規High
↓
0

も確認します。

ここで重要なのは、

既知課題を0件にすること

ではありません。

実際、正式公開時にもMediumの継続課題は残っています。

必要なのは、

公開を止める重大な問題が残っていないこと

です。


13. Mediumが残っていても公開できる場合がある

今回残った既知課題の一つが、

スマートフォンでNetlifyのバッジが、

画面下部固定操作領域の一部へ重なる問題でした。

しかし確認した結果、

操作可能領域あり
ゲーム進行への影響なし
保存・ロードへの影響なし
console/pageerrorへの影響なし

でした。

そこで、

Medium
非Blocker

として継続管理しています。

Release Gateは、

問題が1件でもあればFAIL

という仕組みではありません。

重要度を判断したうえで公開可否を決める

仕組みです。


14. 成果物そのものもGateにする

ここまでの確認が全部通っていても、

最後に渡すZIPや判定書が壊れていたら困ります。

実際、正式判定書の生成では、

PowerShellの文字列生成に起因して、

BEL制御文字
未展開placeholder

が混入する問題が発生しました。

これはアプリ本体の不具合ではありません。

しかし、

正式成果物としては不合格

です。


15. テスト環境障害とアプリ不具合を区別する

正式判定では、

Vitest workerが起動できず、

テスト本文へ入る前に停止する問題も発生しました。

最終的には、

ASCII-onlyの短い作業パスを使うことで解消しました。

この場合、

テストFAIL
=
アプリ不具合

ではありません。

Application Failure
Test Failure
Test Environment Failure

を切り分けます。

ただし、

原因が試験環境だからといって、

Gateを無視して公開するのでもありません。

正常にテストを完走できる環境を作り直して、改めてPASSを確認する

ようにしました。


16. manifestと判定書も機械的に確認する

正式リリースでは、

成果物についても、

Release名
Production deploy ID
Candidate SHA
package-lock SHA

などを照合しています。

さらに、

判定書について、

制御文字
↓
0

BEL
↓
0

未展開placeholder
↓
0

をhard gateにしました。

つまり、

Release Gateは、

アプリの実行結果だけではありません。

Application
Tests
Hosting
Rollback
Artifacts
Reports

まで含めています。


17. 「正式候補」を途中で変えない

Release Gateを通している途中に、

コードを修正してしまうと、

最初にテストしたものと、

最後に公開するものが違ってしまいます。

そこで、

Candidateを凍結
↓
Gateを実行
↓
同じCandidateを公開

とします。

もし修正したなら、

それは新しい候補です。

原則として、

必要なGateをもう一度通します。


18. Release Gateを一つの表にすると判断しやすい

最終的な公開判定は、

概念的には次のように整理できます。

Gate 結果
PACK_MANIFEST 8/8 PASS
clean npm ci PASS
Vitest 7/7 files・68/68 tests
application typecheck PASS
E2E typecheck PASS
lint PASS
production build PASS
hosting artifact verification PASS
npm audit 0 vulnerabilities
Chromium 15/15 PASS
WebKit+iPhone emulation 7/7 PASS
local hosting 7/7 PASS
production hosting 7/7 PASS
console warning/error 0
pageerror 0
rollback PASS
新規Blocker / High 0

一つずつ見れば、

これまでの記事で扱ってきたものです。

最後に、

全部を同時に満たしているか

を確認します。


19. Release Gateは「公開ボタン」の前に置く

流れを整理すると、

Implementation
↓
Unit / Integration Test
↓
Build
↓
Browser E2E
↓
Device / A11y
↓
Local Hosting
↓
Production Hosting
↓
Rollback
↓
Artifact Verification
↓
Release Gate
↓
Formal Release

です。

つまり、

Release Gateは、

公開したあとに作る報告書ではありません。

正式公開へ進んでよいかを判断する直前の関門

です。


20. 「全部PASS」を人の記憶に任せない

確認項目が少ないうちは、

人が、

これは確認済み
あれも確認済み

と覚えていられます。

しかし項目が増えると、

実はproductionだけ未確認だった
rollback後の再確認を忘れた
判定書のplaceholderが残っていた

といった抜けが起こります。

そこで、

可能なものは、

機械的なPASS/FAILへ寄せる

ようにします。


21. ただし最終判断まで完全自動にはしない

Release Gateを自動化しても、

すべてを機械だけで決めるわけではありません。

例えば、

Mediumの既知課題を、

公開可能

と判断するかどうかは、

影響範囲を見て判断する必要があります。

つまり、

機械
↓
事実をそろえる

人
↓
その事実をもとに
正式公開を判断する

という役割分担です。


22. 正式公開とは「動く」より広い

このWeb RPGでは、

正式公開完了を、

単に、

ブラウザで遊べる

とは定義しませんでした。

最終的には、

セーブ互換性
破損復旧
自動回帰
ブラウザ差
スマートフォン
A11y
SPA直URL
HTTPS
production
console/pageerror
rollback
成果物完全性

まで確認しています。

正式公開資料でも、これらを一連の品質ゲートとして確認したうえで公開した、と整理しています。


23. 今回のポイント

今回のポイントは3つです。

  • Unit/E2E/browser/device/hosting/rollbackなど、これまでの確認を一つのRelease Gateへ集約する
  • アプリだけでなく、production環境・正式成果物・判定書までGateの対象にする
  • 可能な判定は自動化しつつ、既知課題の重要度など最終的な公開判断は人が行う

整理すると、

Tests
+
Build
+
Browser
+
Device
+
Production
+
Rollback
+
Artifacts
↓
Release Gate
↓
Formal Release Judgment

です。

今回の結論は、

「公開できる」とは、ゲームが動くことではなく、あらかじめ決めた公開条件をすべて確認し、その結果を説明できる状態になること

です。


24. 次回

次回は、

正式公開までに作った品質基盤を振り返る【第46回】

です。

第30回から、

saveSchemaVersion
Migration
future schema
IndexedDB
破損復旧
Vitest
Playwright
ブラウザ
スマートフォン
production
rollback
Release Gate

まで進んできました。

次回は、一つひとつの技術をさらに掘り下げるのではなく、

小さなWeb RPGが、どのように「公開に耐えられるWeb MVP」へ変わっていったのか

を整理し、第8章をまとめます。


この記事を最後まで読んでいただき、ありがとうございます。
「いいね」を押していただけるとうれしいです。これからの記事づくりの励みになります。
もし気に入っていただけましたら、フォローもよろしくお願いします。


前の記事

第44回 初回リリースでも戻れるようにする――rollback anchorの設計

次の記事

第46回 正式公開までに作った品質基盤を振り返る


連載トップ

第0回 React+TypeScriptで異世界RPGを作る――連載の目的と開発ロードマップ

note関連記事

正式公開の前に、どこまで確認したか #26

noteでは、正式公開直前に、セーブ互換性・破損復旧・自動テスト・スマートフォン・本番環境・rollbackまでを、どのように公開判断へまとめたのかを制作側の視点から書いています。

note「正式公開の前に、どこまで確認したか #26」を読む

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?