Страницы

Поиск по вопросам

понедельник, 8 июля 2019 г.

Проверка коммита на сервере GitLab Community

Проблема в следующем: Заказчик использует GitLab Community в качестве git сервера. Надо запретить push на сервер коммитов, в которых коментарий не содержит номер таска из джиры (формат например: #JIRA-1234). В какую сторону копать? Заранее спасибо.


Ответ

Нужно использовать git hook, проверяющий сообщение коммита.
Как написать хук post-receive
Полная инструкция с примерами есть в документации git.
Кратко: хук получит на вход строку вроде
ab3c291835832c309 b2fed56890cab348 new-branch
В ней:
Хеш предыдущего коммита Хеш нового коммита Название ветки, которую вы запушили на сервер
Имея хеш нового коммита, вы можете получить его сообщение, чтобы проверить его регулярным выражением.
Если оно соответствует требованиям, хук должен вернуть 0, если нет — 1
Как установить его в GitLab
Для установки хука на сервер GitLab нужны права администратора.
Кратко:
Открыть директорию /var/opt/gitlab/git-data/repositories//.git Создать в ней директорию custom_hooks/ А в ней файл pre-receive (это полное имя, расширение не нужно.) Выдайте этому файлу права на выполнение:
chmod +x /var/opt/gitlab/git-data/repositories//.git/custom_hooks/pre-receive Содержимое этого файла — код на любом интерпретируемом языке (bash, python, ruby...), который есть в системе.
Подробная инструкция по установке в GitLab: https://docs.gitlab.com/ce/administration/custom_hooks.html#setup
Пример хука post-receive
Вот подходящий пример хука (источник). Есть также статья от автора хука, объясняющая его работу.
За проверку коммита отвечает вот эта строка:
match = re.search(r'TICKET-[0-9]{2,5}|#TICKET-[0-9]{2,5}|HOTFIX|FORCE', rev)
Соответственно, вам нужно её поменять так, чтобы вместо TICKET был буквенный код проекта в джире (явно это не JIRA).
Смысл HOTFIX и FORCE в том, что иногда бывают коммиты, не принадлежащие ни к какой задаче. Просто нашли ошибку и быстро исправили. Если не предусмотреть такие «волшебные слова», то придётся заводить по задаче на каждую опечатку в комментариях. Но и злоупотреблять ими тоже не нужно.
Код полностью:
#!/bin/python import sys import re import subprocess
#Format: "oldref newref branch" line = sys.stdin.read() (base, commit, ref) = line.strip().split() new_branch_push = re.match(r'[^1-9]+', base) branch_deleted = re.match(r'[^1-9]+', commit) contains_commit_msg = False if not new_branch_push: revs = base + "..." + commit proc = subprocess.Popen(['git', 'rev-list','--oneline','--first-parent', revs], stdout=subprocess.PIPE) lines = proc.stdout.readlines() if lines: for line in lines: rev = str(line) match = re.search(r'TICKET-[0-9]{2,5}|#TICKET-[0-9]{2,5}|HOTFIX|FORCE', rev) if match is not None: contains_commit_msg = True if contains_commit_msg or new_branch_push or branch_deleted: exit(0) else: print "Commit does not contain the story associated with the commit in the format: TICKET-123 or #TICKET-123" exit(1)

Комментариев нет:

Отправить комментарий