browserflow.lockからToolを解決します。そのため、同じチェックは手元のラップトップでもCIランナーでも同じ答えを返します。このページでは3つのCIパターンを扱います。
パターン1 — コンパイルでゲート
純粋な型チェックで副作用ゼロ。すべてのpull requestの既定ゲートです。
パターン2 — ライブSmoke
CIで
browserflow runを実行し、実ターゲットへ実際の副作用を発火します。パターン3 — リプレイ検証
記録済みJournal fixtureに対するhermeticなリプレイ。ライブ依存はゼロです。
ここでCIが決定論的になる理由
browserflow FlowをCIで安全かつ安定して実行できるのは、次の2つの性質があるためです。browserflow compile --checkは純粋です。 副作用なしでFlowを型チェックし、digestを出力します。また、固定済みToolの解決以外ではネットワークに触れません。コンパイラは(source, registry)の純粋関数なので、高速で、キャッシュ可能で、CIで安全に実行できます。- digestはランナー間で安定します。
browserflow.lockが存在すると、すべてのuse:範囲は、Registryにその時点である最新バージョンではなく、lockに記録された正確なバージョンとcontract digestへ解決されます。解決を決めるのはRegistryの最新状態ではなくlockです。だからこそ、browserflow compile --checkはローカルで見たものと同じdigestをCIで生成します。詳しくはFlowSpec IRを参照してください。
daily-price-watch Flowを実行例として使います。ブラウザーToolのsearch-price@1.2.0が価格を読み取り、transform手順がそれを整形し、条件付きのhttp.postがシークレットのwebhookへ通知します。シークレットはartifact内には一切入りません。実行時にCI環境自身のSecrets providerから渡されます(Launchers)。
パターン1 — コンパイルでゲートする
最も低コストなCIゲートは、Flowを型チェックし、そのdigestを出力するものです。副作用を実行しないため、pull requestチェックやpre-commit hookの既定として適しています。Flowがコンパイルできることを確認する
--checkはartifactを書き出さずに型チェックし、digestを出力します。型エラー、未解決のuse:、参照サイクル、ガードされていないskipは、実行時ではなくここでジョブを失敗させます。失敗時のdiagnosticsを読む
Compile diagnosticsは構造化されたsource map付きデータで、CLI、LSP、UIのどれでも同じ方法で表示されます。失敗時には、正確なYAML行、ルール名、修正案が示されます。完全なカタログ(
type_mismatch、unresolved_version、cycle、unguarded_skipなど)はDiagnosticsを参照してください。browserflow compile(および--check)は常に副作用がなく、プロンプトも表示しません。どのpipelineでも無人で安全に実行できます。パターン2 — CIでFlowを実行する
CIで実際にFlowを実行するには、shell stepとしてbrowserflow runを使います。browserflowは標準的なNode/Bunバイナリです。CI環境にインストールし、そのまま呼び出してください。
buildRunDepsだけで、エンジンとFlowSpecは一定だからです。手元のラップトップで確認済みのFlowは、そのFlowSpecとPack digestが同一であるため、ランナー上でも再現されます。詳しくはLaunchersを参照してください。
パターン3 — リプレイでToolアップグレードをゲートする
最も強力なCIゲートは、記録済みのJournalを移植可能で実行可能なfixtureとして使うものです。一度記録してfixtureをコミットし、CIで何も変わっていないことを検証します。ライブ依存はゼロです。fixtureをコミットする
生成artifactの既定出力先はgitignoreされた
out/ですが、fixtureとして固定したいJournalは意図的にコミットします。ここでは./fix/配下に置いています。Flowと一緒にGitへチェックインしてください。どのCIゲートを実行すべきですか?
| ゲート | コマンド | 副作用 | ネットワーク | 検出できるもの |
|---|---|---|---|---|
| Compile check | browserflow compile --check | なし | 固定済みToolの解決のみ | 型エラー、未解決バージョン、サイクル、ガードされていないskip、digest drift |
| Live smoke | browserflow run(Action経由) | あり | ライブTool + 副作用 | 実ターゲットに対するend-to-endの破損 |
| Replay verify | browserflow replay --verify | なし | なし(hermetic) | Toolアップグレードまたはリファクタ後の手順出力の変化 |
replay --verifyがネットワークにアクセスすることはありますか?
replay --verifyがネットワークにアクセスすることはありますか?
ありません。hermetic replayが既定であり、
--verifyは常に副作用なしです。ライブ依存なしで、記録済みのJournalから再実行し、プロンプトも表示しません。ライブ版にあたるbrowserflow replay --rerunは副作用を再発火するため、browserflow runと同じeffect summary and confirmの経路に従います。実ターゲットへアクセスする意図がある場合にのみ使ってください。CIと手元のラップトップでdigestが同じになるのはなぜですか?
CIと手元のラップトップでdigestが同じになるのはなぜですか?
browserflow.lockが存在すると解決が決定論的になるからです。範囲は、コンパイル時にRegistryがたまたま返すものではなく、lockに記録された正確なバージョンとcontract digestへ解決されます。その後、hash化の前にcanonicalizationがbyte単位で同一の形式(RFC 8785 JCS)を生成するため、同じsourceを同じlockに対してコンパイルする2つの環境は同じdigestを出力します。詳しくはFlowSpec IRを参照してください。CIでシークレットはどのようにFlowへ届きますか?
CIでシークレットはどのようにFlowへ届きますか?
シークレットは実行時にランナー自身の
Secrets providerから供給され、ログ、inspect、エラー、--dry plansを含むすべてのstreamでマスクされます。シークレットがFlowSpec、Pack export、Journalの中を移動することはありません。詳しくはSecretsを参照してください。関連
テストとリプレイ
Journalをfixtureとして記録し、それを中心に決定論的なテストスイートを構築します。
CLIリファレンス
compile、run、replayの完全なコマンドマップを、flagと例付きで示します。FlowSpec IR
解決、canonicalization、digestがCIをどのように安定させるか。
Launcher
CI stepは数あるLauncherの1つです。1つのFlow、多数のfrontです。