self-hosted の CI runner には厄介な性質があります。すべてを覚えているのです。キャッシュ、トークン、去年の春に誰かが「一時的に」追加したデプロイキー。自分たちのブランチなら問題ありません。問題になるのは、聞いたこともない人から pull request が届いたとき、あるいはまだ誰も読んでいないパッチを自社の AI エージェントが書いたときです。
すっきりした答えは、実行ごとに1台のマシンを使うことです。クローンし、インストールし、テストし、マシンを捨てる。
実行の流れ
サンドボックスは、Python 3.12、Node.js 22、git、curl を備えて約1秒で起動する Firecracker microVM です。外向きのインターネットは使えるので、git clone や pip install -r requirements.txt はいつも通り動きます。受信ポートはありません。実行中のテスト環境に外部から接続することはできません。
CI ジョブから見れば、全体は短いスクリプトです。どの CI ジョブからでも呼び出せる Python SDK 版はこちらです。
import os, sys
from eqvps import Sandbox
repo, ref = os.environ["REPO_URL"], os.environ["PR_SHA"]
with Sandbox.create(tariff="standard", ttl=1800) as sb:
sb.exec(f"git clone {repo} /root/app && cd /root/app && git checkout {ref}", timeout=55)
sb.exec("cd /root/app && pip install -r requirements.txt", timeout=55)
task = sb.exec("cd /root/app && python3 -m pytest -q", background=True)
result = task.wait(on_output=lambda out, err: print(out, end=""))
sys.exit(result.exit_code or 0)
トークンは CI のシークレットに EQVPS_API_KEY として保存します。CI のそれ以外のもの、つまりデプロイキーもクラウドの認証情報もサンドボックスには入りません。with ブロックが終わるとサンドボックスは削除されます。ジョブが途中でクラッシュした場合も同じです。
テストの実行自体はバックグラウンドタスクです。同期コマンドは55秒で止まるためです。バックグラウンドタスクは動作中に出力をストリーミングし、サンドボックスの TTL まで実行を続けられます。ここでは、ハングしたテストで請求が膨らまないよう 30 分に設定しています。
実際にぶつかる制限
これを正直に伝えておけば、午後をまるごと無駄にせずに済みます。
同時実行。 アカウントは20個のサンドボックスを保持できますが、同時に実行されるコマンドは2つだけです。CI では、本当に並列に動くジョブが2つということです。同時に届いた10件の PR は順番待ちになります。パイプラインがテストを16のワーカーに分割しているなら、メインのパイプラインには向いていません。メインは VPS 上の自前 runner に残し、信頼できないレーンにサンドボックスを使ってください。
内部でコンテナは使えません。 サンドボックスに Docker は付属していません。Postgres コンテナが必要なユニットテストや統合テストはそのままでは動きませんが、SQLite やインメモリのフェイクを使うテストは動きます。
ファイル。 API 経由のアップロードとダウンロードは1ファイル最大 5 MB です。アーカイブをアップロードするのではなく、サンドボックス内で git を使ってコードを取得してください。
費用
プランの vCPU と RAM に対して秒単位、最低60秒で、プリペイド残高から支払います。サブスクリプションは不要です。
| 実行内容 | プラン | おおよその費用 |
|---|---|---|
| Lint + ユニットテスト、1分 | small(0.5 vCPU、1 GB) | $0.0006 |
| フルスイート、3分 | standard(1 vCPU、2 GB) | $0.0033 |
| ビルド + テスト、10分 | plus(2 vCPU、4 GB) | $0.022 |
この価格帯では、気にすべきは費用ではなく、設定した時間内にテストが終わるかどうかです。最も遅いグリーンの実行より少し余裕を持たせて TTL を設定してください。
妥当な役割分担
おすすめは次の通りです。信頼できるブランチは、キャッシュの効いた高速な runner に残す。自分たちが書いていないもの、つまりフォーク、外部コントリビューター、エージェントが生成したパッチは、まずサンドボックスを通す。サンドボックスでの実行がグリーンで、人間が diff を確認したら、信頼できるパイプラインに昇格させる。
こうすれば、速度とキャッシュが重要なレーンと、クリーンなマシンが重要なレーンを分けられ、1つのツールに両方の役割を押し付けずに済みます。
まずはサンドボックスの概要と接続ガイドから始めてください。新規アカウントには $1 分のサンドボックス利用時間が付与され、短いテストなら数百回実行できます。上で使ったメソッドはすべて SDK リファレンスに、正確な課金ルールはサンドボックスの制限と課金にあります。
コメント
まだコメントはありません。最初になりましょう。