Деплой на 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-ов | ✗ шаринг доступа |
Главное
- Нативная Git-интеграция Vercel блокирует деплои, чей автор коммита не член команды — это защита, а не баг.
vercel deployс токеном не проверяет автора; отключи нативную интеграцию и деплой из CI.- Коммить под собой и никогда не пуш amend из раннера — граф остаётся твоим.
- Amend автора
HEADна члена команды даёт нормальную строку без блока — впиши реального пушера в сообщение. - Ты платишь за seat-ы доступа к дашборду, а не по контрибьютору: CI-токен для кода всех — это задуманная модель.
- Плодить фейки ради обхода оплаты — это multi-accounting. Вот и граница.
Ни один из этих кусочков не экзотичен — CLI, токен, git amend, который никогда не покидает раннер. Сдвиг — в осознании, что стена «не член» не говорит тебе купить ещё один seat; она говорит деплоить так, как и задуман CI. Отключи вебхук, отдай токен раннеру — и пусть тот, кто написал код, останется его автором.
Заметили ошибку?
Неверный факт, кривой перевод, что-то звучит неправдой в этой статье? Напишите мне — на своём языке.