Деплой на Vercel із CI, коли автор коміту не член команди
Перенеси репо в GitHub-організацію — і Vercel тихо починає блокувати деплої: коміт «не вдалося зіставити з членом команди». Ось як я деплою через GitHub Actions і Vercel CLI: коміти все одно йдуть у мій GitHub-графік, дашборд показує, хто пушив, і я не купую seat на кожного контриб’ютора.
Я переніс landee у GitHub-організацію, щоб мої коміти зараховувались у мій графік контриб’ютів. Наступним же пушем продакшн перестав деплоїтись.
Дашборд Vercel писав отаке — на кожен пуш. Нативна Git-інтеграція тихо перетворилась на шлагбаум:
Deployment Blocked
The deployment was blocked because the commit could not be
matched to a team member.Чому Vercel блокує деплой
Нативна Git-інтеграція Vercel — це деплой по вебхуку: GitHub шле push-подію, Vercel читає автора коміту, перевіряє, чи є він членом команди, і блокує, якщо ні. Це захист: він не дає випадковому контриб’ютору чи форк-PR автоматично викотитись у продакшн.
Це розумно — аж поки той, хто пише код, не є оплаченим членом. Мій GitHub-акаунт авторить коміти, але він не член Vercel-команди. Тож кожен деплой для інтеграції — «не член», і кожен блокується.
Деплой через CLI, а не Git-інтеграцію
Вихід — CLI. vercel deploy авторизується токеном, а не автором коміту — і ніколи не запускає перевірку членства. Тож відключаємо нативну Git-інтеграцію й деплоїмо з GitHub Actions: push → workflow → vercel deploy з токеном → Vercel білдить і котить.
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 }}Дві речі роблять це єдиним шляхом деплою, щоб CLI і вебхук не гонились: vercel.json вимикає нативний авто-деплой, а ти тиснеш Disconnect на Git-репо в дашборді Vercel.
{
"git": { "deploymentEnabled": false },
"installCommand": "pnpm install --frozen-lockfile"
}Зберегти свій GitHub-графік
Увесь сенс переносу в org — щоб коміти йшли у мій графік, тож коміт на GitHub має лишатись за моїм авторством. Тут це вже так: CLI-деплой працює на свіжому чекауті в раннері, і нічого звідти назад у GitHub не пушиться.
Тож я комічу під собою, пушу — і зелені квадратики заповнюються. Токен, який авторизує деплой, належить власнику акаунта, а не мені — це й є суть CI-деплою.
Показати в дашборді, хто пушив
Звичайний CLI-деплой у списку Vercel — це голий хеш: без повідомлення, гілки, автора. Щоб був нормальний git-рядок (повідомлення + гілка + аватар), Vercel має розпізнати деплой як git-коміт — а саме це й запускає перевірку автора.
Трюк: у раннері переписуємо автора HEAD на члена команди, потім деплоїмо. Цей amend ніколи не пушиться назад, тож на GitHub коміт лишається твоїм. Vercel читає автора-члена з .git — деплой розпізнаний і не заблокований — а реального пушера вписуєш у повідомлення коміту.
# 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"Один сервісний акаунт — усі деплоять через нього
Узагальнюємо: один сервісний акаунт володіє Vercel-командою й тримає деплой-токен. Усі комітять під собою; CI переписує автора на сервісний акаунт і деплоїть його токеном. У дашборді рядок — [ти] твоє повідомлення, а GitHub тримає твоє справжнє авторство.
Це нудна, чесна версія того, до чого тягнеться багато команд. Ти платиш за seat-и тих, кому потрібен доступ до дашборду, — а не по одному на контриб’ютора. CI-токен, що деплоїть код усіх, — це модель, яку Vercel сам документує.
Деталі, що кусають
Кілька речей, які забрали в мене вечір — щоб не забрали в тебе:
- pnpm на Vercel. Білд-образ може взяти старий pnpm, ігноруючи
packageManager. Передай--build-env ENABLE_EXPERIMENTAL_COREPACK=1уvercel deploy— і corepack візьме саме ту версію, яку ти закріпив. - Verified-коміти. Підпис — окрема тема: налаштуй SSH-підпис комітів і додай ключ на GitHub — твої (справжні) коміти отримають бейдж Verified. Тимчасовому amend у раннері підпис не потрібен.
- Читабельні рани. Розбий один великий shell-крок на названі кроки (re-author → deploy → summary), щоб у Actions було видно етап з першого погляду.
- Тести. Деплой білдить на Vercel, але ніколи не ганяє тести — додай окремий CI-workflow, і заодно увімкни Dependabot.
CLI-деплой авторизує токен, а не той, хто написав коміт. Це й є весь розблок — і це документований, повноцінний спосіб деплою.
Де межа
Будьмо чесні щодо межі, бо її легко проговорити. Деплоїти код контриб’юторів через CI-токен — легітимно й задумано так. Клепати фейкові акаунти, щоб обійти оплату seat-ів, — ні— це multi-accounting, і це проти правил будь-якої платформи.
| Що ти робиш | Легітимно | За межею |
|---|---|---|
| Деплоїти код контриб’юторів через CI-токен | ✓ по доках | |
| Один seat для того, хто керує дашбордом | ✓ | |
| Комітити під собою; сервісна ідентичність лише в CI | ✓ чесна статистика | |
| Клепати фейкові акаунти, щоб не платити за seat-и | ✗ multi-accounting | |
| Один логін на багатьох, щоб керувати без seat-ів | ✗ credential-sharing |
Головне
- Нативна Git-інтеграція Vercel блокує деплої, чий автор коміту не член команди — це захист, а не баг.
vercel deployз токеном не перевіряє автора; відключи нативну інтеграцію й деплой з CI.- Коміть під собою й ніколи не пуш amend із раннера — графік лишається твоїм.
- Amend автора
HEADна члена команди дає нормальний рядок без блоку — впиши реального пушера в повідомлення. - Ти платиш за seat-и доступу до дашборду, а не по контриб’ютору: CI-токен для коду всіх — це задумана модель.
- Клепати фейки заради обходу оплати — це multi-accounting. Отут і межа.
Жоден із цих шматків не екзотичний — CLI, токен, git amend, що ніколи не покидає раннер. Зсув — у тому, що стіна «не член» не каже тобі купувати ще один seat; вона каже деплоїти так, як і має робити CI. Відключи вебхук, віддай токен раннеру — і нехай той, хто написав код, залишиться його автором.
Помітили помилку?
Невірний факт, кривий переклад, щось звучить неправдиво в цій статті? Напишіть мені — своєю мовою.