Multica Docs

Интеграция GitHub

Подключите GitHub App один раз — PR, в ветке, заголовке или теле которого есть идентификатор issue, автоматически привяжется к этому issue, а merge PR переведёт issue в Done.

Подключите аккаунт или организацию GitHub один раз в Settings → GitHub. После этого любой pull request, в имени ветки, заголовке или теле которого есть идентификатор issue (например MUL-123), автоматически связывается с этим issue, появляется в блоке Pull requests на боковой панели issue и — при merge PR — переводит issue в Done.

Отдельной настройки на каждый issue нет. Весь поток строится на идентификаторах.

Что делает интеграция

ПоверхностьПоведение
Settings → GitHubАдминистраторы workspace видят вкладку GitHub с master toggle, кнопкой Connect GitHub и переключателями функций (PR sidebar, Co-authored-by, auto-link). После установки вы возвращаетесь на вкладку GitHub.
Issue sidebar → Pull requestsВсе PR, автоматически связанные с этим issue: заголовок, repo, состояние (Open / Draft / Merged / Closed) и автор. Клик по строке открывает PR на GitHub.
Webhook (фон)На каждое событие pull_request Multica upsert-ит строку PR, сканирует PR на идентификаторы issue и (пере)строит строки связей. Идемпотентно — повторная доставка — no-op.
Auto-status при mergeКогда PR переходит в merged, каждый связанный issue, ещё не в Done или Cancelled, переводится в Done. Смена статуса попадает в timeline с источником github_pr_merged.

Зеркалируется только сам PR. Commits, ссылки на ветки без открытого PR и состояния CI checks не моделируются. Интеграция намеренно узкая.

Как сопоставляются идентификаторы

Webhook извлекает идентификаторы из трёх полей в таком порядке: PR head branch, PR title, PR body. Matcher:

  • Без учёта регистра — mul-123, MUL-123, Mul-123 совпадают.
  • С границами — \b слева и digit anchor справа не дают захватить номера версий вроде v1.2-3 или строки в стиле email.
  • В пределах workspace — совпадает только issue prefix этого workspace. FOO-1 в workspace с префиксом MUL игнорируется, даже если число совпадает с другим issue.
  • С дедупликацией — MUL-1, MUL-1 в body связывает issue один раз.

В одном PR можно сослаться на несколько issue. Closes MUL-1, MUL-2 связывает PR с обоими, и merge переводит оба в Done.

Правило auto-merge в Done

Когда поле merged у PR становится true, оценивается каждый связанный issue:

Текущий статус issueРезультат
doneБез изменений (уже терминальный).
cancelledБез изменений — cancelled значит, что вы явно отказались от работы; интеграция этот сигнал не перебивает.
Всё остальное (todo, in_progress, in_review, blocked, backlog)Перевод в done.

Закрытие PR без merge только обновляет состояние карточки PR на Closed. Связанные issue остаются как были — смысл «закрыть без merge» решаете вы.

Действие в timeline приписывается актору system. Подписчики issue получают уведомление в inbox о смене статуса — так же, как если бы статус сменил человек.

Что не связывается автоматически

  • Идентификаторы в commit messages — сканируются только branch / title / body. Commit с текстом MUL-123: fix login не свяжется, если та же строка не есть в title или body PR.
  • Идентификаторы в комментариях PR — сканируются только метаданные самого PR; последующие комментарии на GitHub игнорируются.
  • PR в repo, где App не установлен — без App Multica не получит webhook.
  • Ручная привязка PR к issue — UI для этого пока нет. Если команда кладёт идентификаторы туда, откуда Multica не читает, добавьте их в title или body PR.

Отключение

В Settings → GitHub нет списка установок — существующими установками управляете напрямую на GitHub:

  • С GitHub — удалите Multica GitHub App на https://github.com/settings/installations (личный аккаунт) или https://github.com/organizations/<org>/settings/installations (org). Multica получит webhook installation.deleted и удалит строку в реальном времени; открытая вкладка Settings обновится без refresh.
  • Disconnect из Multica — только для admin — кнопка Disconnect на вкладке GitHub скрыта для не-admin. Она доступна даже когда master switch GitHub выключен, чтобы admin мог отозвать устаревшую установку после одношагового отключения функции.

После disconnect зеркалированные строки PR остаются в базе — исторические sidebar issue сохраняют связи, но новые webhook-события от этой установки не принимаются.

Права и видимость

  • Connect / disconnect требуют роли workspace owner или admin. Members видят описание карточки, но не кнопку Connect.
  • Блок Pull requests на issue виден всем, кто может читать issue — те же права, что и на остальную деталь issue.
  • GitHub App запрашивает read-only доступ к pull requests и metadata. Multica не пушит commits, comments и status checks обратно на GitHub.

Настройка self-host

На Multica Cloud интеграция уже настроена — этот раздел можно пропустить.

Для self-host создаёте один GitHub App, указываете на свой server и задаёте две переменные окружения. Полный поток ниже.

1. Создайте GitHub App

Перейдите на один из адресов:

  • Личный аккаунт → https://github.com/settings/apps/new
  • Organization → https://github.com/organizations/<org>/settings/apps/new

Заполните:

ПолеЗначение
GitHub App nameЛюбое узнаваемое имя, например Multica или Multica (staging).
Homepage URLFrontend Multica, например https://multica.example.com.
Callback URLОставьте пустым — Multica не использует OAuth user identity.
Setup URLhttps://<api-host>/api/github/setup. Включите «Redirect on update».
Webhook → ActiveEnabled.
Webhook URLhttps://<api-host>/api/webhooks/github.
Webhook secretДлинная случайная строка (например openssl rand -hex 32). То же значение вставите в env Multica на шаге 2.
Permissions → Repository → Pull requestsRead-only.
Permissions → Repository → MetadataRead-only (обязательно).
Subscribe to eventsОтметьте Pull request.
Where can this GitHub App be installed?На ваш выбор. Only on this account подходит для single-org.

После Create GitHub App запишите с страницы App:

  • Public link вверху — хвост URL это slug. https://github.com/apps/multica-acme → slug = multica-acme.
  • Webhook secret, который вы только что сгенерировали (GitHub потом не покажет его снова — сохраните сейчас).

Webhook secret ≠ Client secret. На странице настроек App оба поля рядом. Webhook secret подписывает payload pull_request — его и нужен Multica. Client secret для OAuth и этой интеграцией не используется. Перепутать их — получить 401 invalid signature на каждой доставке webhook.

2. Задайте переменные окружения

На API server:

GITHUB_APP_SLUG=multica-acme
GITHUB_WEBHOOK_SECRET=<the webhook secret you generated>

# Optional but recommended — populates the connected account name on
# install instead of waiting for the first webhook to refresh it:
GITHUB_APP_ID=<numeric App ID from the App's settings page>
GITHUB_APP_PRIVATE_KEY=<full PEM block, including BEGIN/END lines>

GITHUB_APP_SLUG и GITHUB_WEBHOOK_SECRET обязательны. Если одной из них нет:

  • Connect GitHub в Settings отключён и показывает подсказку «not configured».
  • Endpoint /api/webhooks/github возвращает 503 github webhooks not configured — Multica не обрабатывает события без secret, а не молча считает любую подпись валидной.

GITHUB_APP_ID и GITHUB_APP_PRIVATE_KEY опциональны. Setup callback может вызвать App-authenticated endpoint GitHub /app/installations/{id} и сразу получить имя org или user при install. Без них карточка подключения кратко показывает Connected to unknown, пока GitHub не доставит webhook installation.created (обычно за несколько секунд); Multica обновит строку и разошлёт realtime update — открытая вкладка Settings обновится без ручного refresh. Private key: Private keys → Generate a private key на странице App; вставьте полный PEM-блок (включая строки -----BEGIN/END RSA PRIVATE KEY-----) в env var, сохранив переносы строк.

FRONTEND_ORIGIN тоже должен быть задан (для production self-host он уже есть); setup callback возвращает пользователя на <FRONTEND_ORIGIN>/settings?tab=github после install.

Перезапустите API после задания env vars.

3. Запустите migrations

Таблицы интеграции в migration 079_github_integration. При upgrade старого deployment:

make migrate-up

Создаются три таблицы: github_installation, github_pull_request, issue_pull_request. Они cascade-delete вместе с workspace — удаление workspace очищает их автоматически.

4. Подключите из UI

В Multica:

  1. Откройте Settings → GitHub как owner или admin.
  2. Нажмите Connect GitHub. GitHub откроется в новой вкладке.
  3. Выберите repo для доступа и Install.
  4. GitHub перенаправит на <api-host>/api/github/setup, который запишет installation и вернёт вас на <FRONTEND_ORIGIN>/settings?tab=github&github_connected=1.

После этого откройте любой PR, в branch / title / body которого есть идентификатор issue — через несколько секунд блок Pull requests появится на странице этого issue.

5. Проверка curl probe

Если на GitHub Recent Deliveries после install показывает 401 invalid signature, secret на двух сторонах различается. Быстрее всего проверить, обойдя GitHub:

SECRET="<the value you put in GITHUB_WEBHOOK_SECRET>"
BODY='{"zen":"test"}'
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SECRET" -hex | awk '{print $NF}')
curl -i -X POST https://<api-host>/api/webhooks/github \
  -H "X-Hub-Signature-256: sha256=$SIG" \
  -H "X-GitHub-Event: ping" \
  -H "Content-Type: application/json" \
  -d "$BODY"
HTTP statusЗначениеИсправление
200 {"ok":"pong"}Secret в процессе совпадает с вашим $SECRET. Несовпадение на стороне GitHub.App → Webhook secret → вставьте то же значениеSave changes (клик вне поля без Save оставляет старый secret). Redeliver.
401 invalid signatureSecret в процессе не тот, что вы думаете.Убедитесь, что env var попал в running process (например kubectl exec → `echo -n "$GITHUB_WEBHOOK_SECRET"
503 github webhooks not configuredGITHUB_WEBHOOK_SECRET пуст в процессе.Задайте env var, перезапустите API.

Ограничения

Несколько шероховатостей на сегодня:

  • Ручной link UI пока нет — единственный способ связать PR — идентификатор в branch, title или body.
  • Нет CI / check state — зеркалируется только PR. Build status, review comments и reviewers в Multica не показываются.
  • Нет workspace-level config для правила merge → Done — фиксированный default (merged → done, кроме cancelled). Настраиваемые mapping — в планах.
  • Несколько PR на один issue — консервативно при merge — если два PR ссылаются на MUL-123 и первый merge-ится, issue сразу переходит в Done. Ожидание merge всех связанных PR перед advance — в работе.

Далее

  • Issues — идентификаторы issue (MUL-123) из PR
  • Workspaces — где задаётся issue prefix workspace
  • Environment variables — полный справочник env, включая GitHub variables выше