Appearance
GitLab Post-Receive Hook: Auto MR + YouTrack Integration
Summary
Server-side post-receive hook для GitLab, который при пуше ветки автоматически создаёт Merge Request и линкует его с задачей в YouTrack.
Decisions
| Вопрос | Решение |
|---|---|
| Паттерн task ID | [A-Z]+-\d+ — первое вхождение в любом месте имени ветки |
| Конвенция веток | Любой формат: DEV-123-desc, feature/DEV-123-desc, fix/DEP-45 |
| Target branch | hotfix/* → main, всё остальное → develop |
| Валидация задачи | YouTrack API — MR создаётся только если задача существует |
| Если задача не найдена | Warning в git push output, пуш проходит |
| Статусы в YouTrack | Не менять — хук только создаёт MR |
| Title MR | {TASK_ID}: {summary из YouTrack} |
| Дедупликация | Проверка existing opened MR по source_branch через GitLab API |
| Несколько task ID в ветке | Берём первый найденный |
| Управление хуком | Отдельный репозиторий partizap-hooks (версионирование, review) |
| Масштабирование | Пока один проект (partizap-frontend), расширяемо на мульти-репо |
Architecture
Инфраструктура
Всё на VPS2 (2a03:6f00:a::1:c28f, доступ через VPS1 85.239.48.136, ключ partizap_main).
Репозиторий partizap-hooks
partizap-hooks/
├── hooks/
│ └── post-receive # Основной скрипт хука (bash)
├── config/
│ └── hook.conf.example # Шаблон конфига (без секретов)
├── deploy.sh # Деплой хука в GitLab bare-репо
└── README.mdКонфиг (hook.conf на сервере, не в репо)
bash
GITLAB_URL="https://gitlab.partizap.ru"
GITLAB_TOKEN="glpat-xxxx"
GITLAB_PROJECT_ID="1"
YOUTRACK_URL="https://youtrack.partizap.ru"
YOUTRACK_TOKEN="perm:xxxx"Расположение хука на сервере
/var/opt/gitlab/git-data/repositories/<namespace>/<project>.git/custom_hooks/post-receiveAlgorithm
foreach line in stdin:
parse old_sha, new_sha, ref
skip if: delete branch (new_sha = 0000...0)
skip if: not refs/heads/* (tags, etc.)
branch = ref без "refs/heads/"
skip if: branch == "main" or "develop"
task_id = первый match [A-Z]+-\d+ в branch
skip if: не найден
# YouTrack: проверяем задачу
response = GET {YOUTRACK_URL}/api/issues/{task_id}?fields=summary
if 404 or error:
echo "⚠ Task {task_id} not found in YouTrack, MR not created"
exit 0 # пуш всегда проходит
task_summary = response.summary
# GitLab: дедупликация
existing = GET {GITLAB_URL}/api/v4/projects/{PROJECT_ID}/merge_requests
?source_branch={branch}&state=opened
if existing не пустой:
echo "ℹ MR already exists for {branch}"
exit 0
# Target branch
target = "main" if branch starts with "hotfix/" else "develop"
# GitLab: создаём MR
POST {GITLAB_URL}/api/v4/projects/{PROJECT_ID}/merge_requests
title: "{task_id}: {task_summary}"
source_branch: branch
target_branch: target
remove_source_branch: true
echo "✓ MR created: {task_id}: {task_summary} → {target}"Edge Cases
| Кейс | Поведение |
|---|---|
| Удаление ветки | Пропуск |
Пуш в main/develop | Пропуск |
| Нет task ID в имени ветки | Пропуск (без warning) |
| Задача не найдена в YouTrack | Warning в output, пуш проходит |
| MR уже существует (opened) | Info в output, пропуск |
| MR был закрыт/замержен | Создаётся новый MR |
| Несколько task ID в ветке | Берётся первый |
Пуш нескольких веток (--all) | Обрабатывается каждая независимо |
| API недоступен (сеть, таймаут) | Warning, пуш проходит |
| Таймаут API | curl --max-time 5 |
YouTrack ↔ GitLab Integration
Хук создаёт MR. Связка MR ↔ задача в YouTrack обеспечивается встроенной VCS-интеграцией YouTrack:
- YouTrack → Administration → VCS Integrations → New → GitLab
- URL:
https://gitlab.partizap.ru - GitLab Personal Access Token (scopes:
api,read_repository) - Выбрать проекты для отслеживания
После этого YouTrack автоматически показывает коммиты и MR в карточке задачи.
Deploy
bash
# На VPS2:
cd partizap-hooks
./deploy.shdeploy.sh копирует hooks/post-receive в custom_hooks директорию bare-репо и ставит chmod +x.
Future: Multi-repo
Для расширения на другие проекты:
- Добавить массив target-директорий в
deploy.sh - Или по конфигу на проект (
hook.conf.frontend,hook.conf.backend) - Сам хук универсальный —
PROJECT_IDберёт из конфига