Skip to main content
Назад к блогу
VercelGitHub ActionsCI/CDDeploymentMonorepo

Деплой на Vercel из CI, когда автор коммита не член команды

Перенеси репозиторий в GitHub-организацию — и Vercel тихо начинает блокировать деплои: коммит «не удалось сопоставить с членом команды». Вот как я деплою через GitHub Actions и Vercel CLI: коммиты по-прежнему идут в мой GitHub-граф, дашборд показывает, кто запушил, и я не покупаю seat на каждого контрибьютора.

Опубликовано 10 августа 2026 г.8 мин чтения

Я перенёс 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 собирает и катит.

.github/workflows/deploy-production.yml
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.

vercel.json
{
  "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. Отключи вебхук, отдай токен раннеру — и пусть тот, кто написал код, останется его автором.

Заметили ошибку?

Неверный факт, кривой перевод, что-то звучит неправдой в этой статье? Напишите мне — на своём языке.