GitLab Как сделать автоматическую проверку кода при push или merge request с уведомлением разработчика о результате и получением от него обр. связи?
Приветствую, хотел бы рассмотреть один кейс, который необходимо реализовать. Есть вопросы, разряда возможно/не возможно и как лучше сделать? Есть условно некий репозиторий с кодом, требуется сделать автоматическую проверку кода ИИ-шкой при push-е в репу или merge request. с ответом пользователю и получением обратной связи от него. В целом выглядеть это будет примерно так (для push):
1. Разработчик делает push кода со свое машины в центральную репу.
2. В центральной репе (GitLab) добавляем pipeline , который при запускается, получает измененные файлы и запускает скрипт python, который отправляет код из измененных файлов в ИИ для анализа.
3. ИИ возвращает ответ, этот ответ(условный отчет анализа) отправляется разработчику, тому, кто сделал push, по почте или например в мессенджер (сейчас не принципиально как, пусть по умолчанию будет на почту)
4. Разработчик ознакамливается с отчетом и в зависимости от него, каким-то образом сигнализирует, принять или отклонить push. Например в письме сделать две кнопки: "Принять отчёт", "Отклонить", если жмёт "Принять," то код сливается в основную репу, если жмёт отклонить, то операция push "отменяется".
Т.е разработчик условно, написал код, сливает его в основную репу, там срабатывает проверка, если код разработчика не содержит существенных ошибок, то можно сливать, иначе отклоняем.
Вопросы:
1. Возможно ли в целом такое реализовать в GitLab? Какие механизмы для этого использовать ?
В описании выше, я написал через выполнение pipeline, но до конца не уверен, можно ли с помощью этого механизма реализовать данный кейс? Если можно то как, куда копать?
2. Когда мы делаем push в gitlab, изменения сразу заливаются в репу, независимо от того, выполнился pipeline или нет или, пока весь pipeline не выполнится push не завершится? Можно ли как-то сделать так, что, если джоба не выполнится или выполнится не успешно(например, какая-нибудь переменная стала равна false), то отклонят этот push ?
Как сделать такое отклонение,- вызывать git reset или есть ещё какие-то способы на уровне pipeline?
3. по п.2. Когда срабатывает pipeline при push, мы может получить сам измененный файл, с добавленными в него изменениями, которые прилетели в push-е или когда срабатывает pipeline, у нас есть только, условный diff и файлы в репе еще не изменены?
4 по п.2 Если мы в job-е pipeline вызываем отправку запроса ИИ-шке (это обычный синхронный post запрос через requests.post()), job-а будет стоять и ждать, пока не отработает скрипт отправки, т.е пока мы не получим ответ от ИИ или скрипт запустится и выполнение перейдёт на следующую job?
WbICHA, Можно и отдельную ветку создать, а потом сделать merge request, но вопросы возникнуть примерно те же самые - как отправить код на анализ ИИ-ке и получив от неё ответ, уведомить разраба, получив от него обратную связь продолжить merge request ( чтобы он поступил ответственному на рассмотрение), либо отклонить его, чтобы ответственные его даже не видел.
По ИИ - у нас своя развернута, промт там задать можно довольно большой(сейчас точно не скажу, что-то вроде 10-30 тысяч токенов, возможно и больше). Сейчас иду в режиме сапёра, тыкаю палочкой, пробую понять, насколько реализуем кейс в части гатлаба, если возможно, то буду смотреть уже, на предмет ограничений ИИ,, как выкрутиться.
1. Да, возможно. Поднимаете отдельный CI/CD сервер, создаете задачу с нужным вам функционалом и на этом сервере её запускаете. Отчёт можно любым приложением/скриптом отправить/залить куда и как угодно. Например, можно сразу в коммит или в запрос запостить сообщение через API: https://docs.gitlab.com/api/commits/#post-comment-...
А при появлении сообщения в коммите/запросе гитлаб автоматом оповещает всех причастных, кто подписан. Просто настройте нужные вам оповещения — можно ботом в чат их слать в ТМ, на почту или ещё куда угодно.
Так же гитлаб поддерживает стандартные форматы отчётов тестов из коробки, что позволяет сразу в интерфейсе гитлаба увидеть все результаты тестов. Возможно в вашем случае это подойдёт, возможно нет.
Отдельный сервер нужен для того, чтобы не создавать проблемы и тормоза на основном сервере, где запущен гитлаб. А если запускаете на том же — убедитесь в установке ограничений производительности для задач. Иначе, когда у вас будет запускаться по сотне или даже тысяче задач в день — будет не очень комфортно работать с гитлабом.
2. Это не имеет смысла. Пуш — это по факту просто загрузка коммита на сервер. Есть PR — он легко блокируется через подтверждение со стороны определённых пользователей или групп пользователей, а так же в случае если задача завершилась с ошибкой. Это всё настраивается в настройках. Вам следует просто правильно организовать рабочий процесс. Используйте стандартный Github Flow. PR для того и придуманы, чтобы в PR принимать или отклонять изменения. Не, так-то если очень хочется, то можно откатывать одиночные коммиты, но правильнее это делать через PR.
3. Задача запускается сразу после пуша. В задаче есть полный доступ к репозиторию и всему коду. А т.к. это гит, то легко можно получить все изменения в любом виде в скрипте и делать что угодно с ними.
4. Да, это стандартное поведение всех задач. Задача, обычно, запускается в контейнере и пока контейнер работает — статус задачи не меняется. Либо это отдельный скрипт на сервере, завершение которого гитлаб будет ждать. Задачу даже можно разбить на несколько стадий и по мере их завершения менять статус самой задачи, а результат можно даже в реальном времени в самом гитлабе в задаче наблюдать.
push в GitLab не отменить через pipeline — коммит уже в репо, и только потом стартует CI. Блокировать именно push можно через server hooks (pre-receive), но там таймаут секунды — ИИ не вписать.
Нормальная схема: поставь protected branch на main (запрет прямого push), разраб пушит в ветку, открывает MR, CI запускает скрипт. Diff берёшь через
или через GitLab API изменений MR. Результат — комментарием в MR, если скрипт вернул ненулевой exit code — merge заблокирован при включённом "Pipelines must succeed".
requests.post() в job синхронный, job стоит и ждёт пока ИИ не ответит.