−25%

la planurile Windows anuale, până pe 31 oct. Vezi planurile

EQVPS
Începe

Sandbox pentru CI: rulări de teste izolate, sub un cent fiecare

Rulează teste pentru cod în care nu ai încredere — un pull request de la un necunoscut, un patch generat — într-o microVM nouă, ștearsă după rulare. Facturare la secundă, SDK Python/TS, cinstit despre limitele de concurență.

Runnerele CI proprii au o proprietate incomodă: țin minte. Cache-uri, tokenuri, o cheie de deploy pe care cineva a adăugat-o „temporar” primăvara trecută. Pentru propriile branchuri e în regulă. Devine o problemă în clipa în care sosește un pull request de la cineva de care n-ai auzit niciodată — sau de la propriul tău agent AI, care a scris un patch pe care încă nu l-a citit nimeni.

Răspunsul curat e o mașină per rulare. Clonezi, instalezi, testezi, arunci mașina.

Cum arată rularea

Un sandbox e o microVM Firecracker care pornește în aproximativ o secundă, cu Python 3.12, Node.js 22, git și curl. Internetul spre exterior funcționează, deci git clone și pip install -r requirements.txt se comportă ca de obicei. Nu există porturi de intrare — nimic nu poate apela mediul de test cât rulează.

Dintr-o sarcină CI, totul e un script scurt. Iată-l cu SDK-ul Python, apelat din orice sarcină CI:

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)

Tokenul stă în secretele CI ca EQVPS_API_KEY. Nimic altceva din CI-ul tău — nici chei de deploy, nici date de acces cloud — nu intră în sandbox. Când se termină blocul with, sandboxul e șters, chiar și dacă sarcina a căzut la jumătate.

Rularea testelor e o sarcină de fundal, pentru că o singură comandă sincronă se oprește la 55 de secunde. O sarcină de fundal își transmite ieșirea cât rulează și poate merge până la TTL-ul sandboxului — setat aici la 30 de minute, ca un test blocat să nu umfle factura.

Limitele de care te vei lovi de fapt

Să fim cinstiți cu ele te scutește de o după-amiază.

Concurența. Un cont poate avea 20 de sandboxuri, dar doar 2 comenzi se execută în același timp. Pentru CI asta înseamnă două sarcini care rulează cu adevărat în paralel. Zece PR-uri care sosesc deodată vor aștepta la coadă. Dacă pipeline-ul tău împarte testele pe 16 workeri, asta e unealta greșită pentru pipeline-ul principal — ține-l pe propriile tale runnere de pe un VPS și folosește sandboxurile pentru culoarul cu cod nesigur.

Fără containere înăuntru. Docker nu e inclus în sandbox. Testele unitare și de integrare care au nevoie de un container Postgres nu vor merge așa cum sunt; testele pe SQLite sau pe o simulare în memorie, da.

Fișierele. Încărcările și descărcările prin API merg până la 5 MB per fișier. Ia codul cu git din interiorul sandboxului, în loc să încarci o arhivă.

Cât costă

Plătești la secundă vCPU-ul și RAM-ul tarifului, minimum 60 de secunde, dintr-un sold preplătit — fără abonament.

RulareTarifCost aproximativ
Lint + teste unitare, 1 minsmall (0,5 vCPU, 1 GB)$0.0006
Suita completă, 3 minstandard (1 vCPU, 2 GB)$0.0033
Build + teste, 10 minplus (2 vCPU, 4 GB)$0.022

La prețurile astea, întrebarea interesantă nu e costul, ci dacă testele tale se termină în timpul pe care l-ai setat. Lasă TTL-ului ceva rezervă peste cea mai lentă rulare verde.

O împărțire rezonabilă

Recomandarea noastră: ține branchurile de încredere pe runnerul tău rapid, cu cache. Trimite tot ce n-ai scris tu — forkuri, contributori externi, patchuri generate de agenți — întâi printr-un sandbox. Dacă rularea din sandbox e verde și un om s-a uitat la diff, promovează-l în pipeline-ul de încredere.

Așa ai un culoar în care contează viteza și cache-ul și unul în care contează mașina curată, fără să forțezi o singură unealtă să le facă pe amândouă.

Pornește cu prezentarea sandboxurilor și ghidul de conectare — conturile noi primesc $1 de timp în sandbox, ceea ce acoperă câteva sute de rulări scurte de teste. Fiecare metodă folosită mai sus e în referința SDK, iar regulile exacte de facturare sunt în limitele și facturarea sandboxurilor.

Legate: sandbox pentru code review și verificarea PR-urilor și sandbox pentru agenți AI.

Gata de deploy? Plătește cu cripto, fără KYC — online în aproximativ un minut.

Pornește acum →

Întrebări frecvente

De ce să nu rulez pull requesturile nesigure pe runnerul meu propriu?

Un runner propriu păstrează starea între sarcini și ține de obicei chei de deploy sau date de acces cloud. Un pull request de la cineva pe care nu-l cunoști le poate citi dintr-un singur pas. Un sandbox pornește curat de fiecare dată și nu ține nimic în afară de codul testat.

Poate un test să ruleze mai mult de 55 de secunde?

Da. Limita de 55 de secunde e pentru fiecare comandă sincronă. Pornește suita de teste ca sarcină de fundal, citește-i periodic ieșirea, iar ea poate rula până se termină durata de viață a sandboxului — până la 24 de ore pentru un sandbox efemer.

Câte rulări de teste pot merge în paralel?

Până la 20 de sandboxuri per cont, dar doar 2 comenzi executate în același timp per cont. Pentru CI asta înseamnă două sarcini care rulează efectiv deodată; restul așteaptă la coadă. Dacă ai nevoie de multe shard-uri în paralel, o flotă de runnere pe VPS se potrivește mai bine.

E disponibil Docker în sandbox?

Sandboxul vine cu Python 3.12, Node.js 22, bash, git și curl, iar dependențele le instalezi cu pip sau npm. Docker nu face parte din el — dacă testele tale pornesc containere, rulează-le pe un runner VPS.

Cât costă o rulare?

La secundă, minimum 60 de secunde, pentru vCPU-ul și RAM-ul tarifului. O rulare de trei minute pe tariful standard (1 vCPU, 2 GB) costă în jur de $0.0033.

Comentarii

Încă nu există comentarii. Fii primul.

Lasă un comentariu

Comentariile sunt moderate înainte să apară.