Deploy pe Vercel din CI când cel care face commit nu e membru al echipei
Muți un repo într-o organizație GitHub și Vercel începe discret să-ți blocheze deploy-urile: commit-ul „nu a putut fi asociat unui membru al echipei”. Iată cum fac deploy din GitHub Actions cu CLI-ul Vercel: commit-urile mele continuă să conteze în propriul graf GitHub, dashboardul arată în continuare cine a dat push, iar eu nu plătesc un loc pentru fiecare contribuitor.
Am mutat landee într-o organizație GitHub ca să-mi conteze commit-urile în propriul graf de contribuții. La următorul push, producția a încetat să facă deploy.
Dashboardul Vercel spunea doar atât — la fiecare push. Integrarea Git nativă devenise, discret, o barieră:
Deployment Blocked
The deployment was blocked because the commit could not be
matched to a team member.De ce blochează Vercel deploy-ul
Integrarea Git nativă a Vercel e un deploy prin webhook: GitHub trimite un eveniment de push, Vercel citește autorul commit-ului, verifică dacă e membru al echipei Vercel și blochează deploy-ul dacă nu. E un control de securitate — împiedică un contribuitor oarecare, sau pull request-ul unui fork, să ajungă automat în producție.
E rezonabil — până când cel care scrie codul nu e un membru plătit. Contul meu de GitHub e autorul commit-urilor, dar nu e membru al echipei Vercel. Așa că pentru integrare fiecare deploy vine de la un „non-membru”, și fiecare deploy e blocat.
Fă deploy cu CLI-ul, nu cu integrarea Git
CLI-ul e ieșirea. vercel deploy se autentifică printr-un token, nu prin autorul commit-ului — nu rulează niciodată verificarea de apartenență. Deci deconectează integrarea Git nativă și fă deploy din GitHub Actions: push → rulează workflow-ul → vercel deploy cu un token → Vercel construiește și publică.
name: Deploy Production (Vercel CLI)
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
steps:
- uses: actions/checkout@v7
- run: npm install -g vercel@latest
- run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
- run: vercel deploy --prod --token=${{ secrets.VERCEL_TOKEN }}Două lucruri fac din asta singura cale de deploy, ca CLI-ul și webhookul să nu se bată: vercel.json dezactivează auto-deploy-ul nativ, iar tu apeși Disconnect pe repo-ul Git din dashboardul Vercel.
{
"git": { "deploymentEnabled": false },
"installCommand": "pnpm install --frozen-lockfile"
}Păstrează-ți graful de contribuții GitHub
Tot rostul mutării în organizație era ca commit-urile să conteze în graful meu — deci commit-ul de pe GitHub trebuie să rămână scris de mine. Aici deja e așa: deploy-ul prin CLI rulează pe un checkout proaspăt în runner, iar nimic de acolo nu e vreodată împins înapoi în GitHub.
Așa că fac commit în numele meu, dau push, iar pătratele verzi se umplu. Tokenul care autorizează deploy-ul aparține proprietarului contului, nu mie — exact în asta constă un deploy din CI.
Fă dashboardul să arate cine a dat push
Un deploy simplu prin CLI apare în lista Vercel ca un hash gol — fără mesaj, fără ramură, fără autor. Ca să obții un rând în stil git adevărat (mesaj + ramură + avatar), Vercel trebuie să recunoască deploy-ul drept un commit git — iar tocmai această recunoaștere reia verificarea autorului.
Trucul: în runner, rescrie autorul lui HEAD către un membru al echipei, apoi fă deploy. Amend-ul nu e niciodată împins înapoi, așa că pe GitHub commit-ul rămâne al tău. Vercel citește autorul-membru din .git — deploy-ul e recunoscut și neblocat — iar tu pui în mesajul commit-ului pe cel care chiar a dat push, ca rândul să spună tot cine a publicat.
# In the runner only — this amend is NEVER pushed back, so on GitHub the
# commit stays authored by the real pusher (your contribution graph is intact).
MSG="$(git log -1 --pretty=%s)"
git -c user.name="CI Bot" -c user.email="ci@your-org.dev" \
commit --amend --author="CI Bot <ci@your-org.dev>" \
-m "[$GITHUB_ACTOR] $MSG"
# Vercel now reads a team-member author from .git → recognized AND not blocked.
vercel deploy --prod --token="$VERCEL_TOKEN"Un cont de serviciu prin care fac deploy toți
Generalizează: un cont de serviciu deține echipa Vercel și ține tokenul de deploy. Toți fac commit în numele lor; CI-ul rescrie autorul către contul de serviciu și face deploy cu tokenul acestuia. Rândul din dashboard spune [tu] mesajul tău de commit, iar GitHub păstrează autoratul tău real.
E versiunea plicticoasă și onestă a ceea ce caută multe echipe. Plătești pentru locurile celor care au nevoie de acces la dashboard — nu câte unul de contribuitor. Un token de CI care face deploy la codul tuturor e modelul documentat de Vercel; nu cumperi un loc cuiva doar fiindcă i se publică codul.
Detaliile care mușcă
Câteva lucruri care m-au costat o seară, ca să nu te coste pe tine una:
- pnpm pe Vercel. Imaginea de build poate fixa un pnpm vechi indiferent de câmpul tău
packageManager. Trimite--build-env ENABLE_EXPERIMENTAL_COREPACK=1cătrevercel deploy, ca corepack să folosească versiunea pe care chiar ai fixat-o. - Commit-uri verificate. Semnarea e separată — configurează semnarea SSH a commit-urilor și înregistrează cheia pe GitHub, iar commit-urile tale (cele reale) capătă insigna verde Verified. Amend-ul de unică folosință din runner nu are nevoie de semnătură.
- Rulări lizibile. Împarte singurul pas mare de shell în pași denumiți (re-author → deploy → summary), ca interfața Actions să arate etapa dintr-o privire.
- Teste. Deploy-ul construiește pe Vercel, dar nu-ți rulează niciodată testele — adaugă un workflow CI separat pentru asta și pornește Dependabot cât ești acolo.
Deploy-ul prin CLI e autorizat de un token, nu de cel care a scris commit-ul. În asta stă toată deblocarea — și e o cale documentată, de primă mână, de a publica.
Unde e linia
Să fim sinceri în privința limitei, fiindcă e ușor să te convingi să treci de ea. A face deploy la codul contribuitorilor printr-un token de CI e legitim și e gândit așa. A crea conturi false ca să ocolești plata pe loc nu e — asta e multi-cont, și încalcă termenii oricărei platforme.
| Ce faci | Legitim | Peste linie |
|---|---|---|
| Faci deploy la codul contribuitorilor printr-un token de CI | ✓ documentat | |
| Plătești un loc pentru cel care administrează dashboardul | ✓ | |
| Faci commit în numele tău; identitatea de serviciu doar în CI | ✓ statistici oneste | |
| Creezi conturi false/de serviciu ca să nu plătești locuri | ✗ multi-cont | |
| Împarți un login ca mulți să administreze fără locuri | ✗ partajare de acreditive |
Concluzii
- Integrarea Git nativă a Vercel blochează deploy-urile al căror autor de commit nu e membru al echipei — o barieră de securitate, nu un bug.
vercel deploycu un token nu verifică niciodată autorul; deconectează integrarea nativă și fă deploy din CI.- Fă commit în numele tău și nu împinge niciodată amend-ul din runner, iar graful tău GitHub rămâne intact.
- Rescrierea autorului lui
HEADcătre un membru în runner dă un rând real în dashboard fără blocaj — pune-l în mesaj pe cel care a dat push. - Plătești pentru locuri de dashboard, nu per contribuitor: un token de CI care face deploy la codul tuturor e modelul gândit.
- A crea conturi false ca să ocolești plata e multi-cont. Acolo e linia.
Nicio piesă din astea nu e exotică — CLI-ul, un token, un git amend care nu părăsește niciodată runnerul. Declicul e să înțelegi că zidul „non-membru” nu-ți spune să cumperi încă un loc; îți spune să faci deploy așa cum e menit CI-ul. Deconectează webhookul, dă tokenul runnerului — și lasă-l pe cel care a scris codul să rămână cu meritul.
Ai găsit o greșeală?
Un fapt greșit, o traducere stângace, ceva ce sună fals în acest articol? Scrie-mi — în limba ta.