Комментарии 18
Зачем вообще использовать approve rules?
Или компании нужно получить сертификат по безопасности и эти правила нужны для прохождения аудита. Может быть следствием SOX(Sarbanes–Oxley Act).
Апи гитлаба это просто сундук с сокровищами:) Вытащить много что можно.
Прикольная идея, но я бы завернул эту реализацию в python скрипт(я про часть с блоком script).
Привет, спасибо) простора для улучшения много, как ты и написал, статья больше про идею
Что именно в этом конкретном случае позволит вам реализовать скрипт на python из того, что нельзя реализовать на bash?
Вкусовщина:)
я больше про то, что лично мне не нравится, когда ты создаешь еще один файл с ci и складываешь туда целые блоки bash "техник" :) Поэтому ответил, что реализацию яб написал через python(тут на самом деле не важно на чем писать, можно и bash оставить) и только добавил доп стадию в основной gitlab-ci.yml
создаешь еще один файл с ci и складываешь туда целые блоки bash
Но вы хотите создать ещё один файл и положить туда целые блоки python. Не вижу логики.
К тому же используя нативный для Gitlab include, почти что так, как сделал автор, можно переиспользовать ci templates без необходимости делать clone какого-то tool репозитория (куда бы вы положили ваш python скрипт, если бы вы использовали его в более чем одном репозитории). И bash также нативен для Gitlab pipelines + нет необходимости ставить какие-то python requirements и т.п. не нужное здесь.
Пример с нехватающим у автора версионированием:
include:
- project: 'test/pipelines'
file: '.gitlab-ci-check-approve.yml'
ref: v1.0.0
Вы явно не поняли реализацию. Сейчас опишу, так, как я ее вижу и как я ее благополучно реализовал на своем проекте рабочем.
Я взял тот блок кода на bash из .gitlab-ci-check-approve.yml и переписал "на коленках" его на python(код не жалко, можно спокойно использовать):
import os
import requests
import sys
def main():
gitlab_token = os.getenv("CI_GITLAB_API_TOKEN")
api_url = os.getenv("CI_API_V4_URL")
project_id = os.getenv("CI_PROJECT_ID")
commit_sha = os.getenv("CI_COMMIT_SHA")
target_branch = os.getenv("CI_MERGE_REQUEST_TARGET_BRANCH_NAME")
approval_authors = os.getenv("APPROVAL_AUTHORS", "").split(',')
# Получаем информацию о merge request
response = requests.get(
f"{api_url}/projects/{project_id}/merge_requests",
headers={"PRIVATE-TOKEN": gitlab_token}
)
merge_requests = response.json()
#print(merge_requests)
mr_info = [mr for mr in merge_requests if mr['sha'] == commit_sha and mr['state'] == "opened" and mr['target_branch'] == target_branch]
if not mr_info:
print("Merge request not found.")
sys.exit(1)
mr_id = mr_info[0]["iid"]
# Получаем approval
response = requests.get(
f"{api_url}/projects/{project_id}/merge_requests/{mr_id}/approvals",
headers={"PRIVATE-TOKEN": gitlab_token}
)
approvals = response.json()
approved = False
for author in approval_authors:
if any(user['user']['username'] == author for user in approvals['approved_by']):
approved = True
break
if approved:
print("Great job! Your merge request has been approved!")
else:
print(f"Almost there! Please get approval from one of the following users: {', '.join(approval_authors)} to proceed.")
sys.exit(1)
if __name__ == "__main__":
main()
Дальше мы его компилируем и получаем бинарный файл:pyinstaller --onefile approved.py
А дальше все еще проще:)
Мы кладем бинарь на сервер в /usr/local/bin, где у нас обитает gitlab-runner и дописываем основной gitlab-ci.yml у нужного проекта, где мы просто указываем доп стадию:
stages:
- check_ap
- Build
- test
- deploy
check_approv:
stage: check_ap
script:
- approved
variables:
CI_GITLAB_API_TOKEN: ${CI_GITLAB_API_TOKEN}
APPROVAL_AUTHORS: "i.ivanov"
rules:
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "stage"'
tags:
- docker
Перед этим обязательно нужно выполнить Шаг 1-4, которые описал автор этой статьи.
И все, апрув чек благополучно работает, так как задумал автор:
Almost there! Please get approval from one of the following users: i.ivanov to proceed.
Cleaning up project directory and file based variables00:00
ERROR: Job failed: exit status 1

Great job! Your merge request has been approved!
Cleaning up project directory and file based variables
Job succeeded

Итого мы имеем:
1) Завернули реализацию как отдельный мини сервис. Для его компиляции мучится не нужно, одна команда на сбор бинарника и в путь.
2) Если нужны доработки(например отправлять пуши ответственным, если кинули мерж), то завел отдельный проект, дорабатывай спокойно скрипт, собирай и скидывай на сервер с раннером. Все, если в ci не нужно будет дописывать переменные, то проекты вообще трогать не нужно для изменения.
3) Удобно подключать проекты, где такая проверка нужна. У меня 100+ реп в gitlab и намного проще и удобнее добавить одну стадию в уже готовый gitlab-ci.yaml и все.
Не нужно создавать доп ci манифесты на каждом проекте (-1-2 действия в экономии времени)
Переменные вообще можно сделать глобальные для групп в гитлабе.
4) Простой и читаемый код(который 100% можно еще лучше сделать. Повторюсь написал пример на коленках). Да можно с таким же методом использовать bash, но bash скрипты очень плохо читаются. Смотришь на эту "кашу" и хочется закрыть сразу :)
Я же правильно понимаю что ничего автоматом при простановке аппрувов происходить не будет, и надо руками перезапускать пайплайн, чтобы он осознал изменившееся количество голосов?
Привет, ага, пайплайн придется перезапускать, в рамках задачи это удовлетворило заказчика
Пишут что можно ранить на аппруве. https://stackoverflow.com/a/63893810
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"'
При аппруве не возникает никакого события, пайплайн все равно нужно перезапускать руками. Или вы нашли конкретное решение?
Поискал в доках и нечего не нашёл, что именно этот event значит. Видимо да никакого события на апруве не выкидывается.
- echo "${GITLAB_TOKEN_FOR_CI}"
Гитлаб заменяет это звёздачками в выводе?
Не кидайте тапками за неоптимальность скрипта, да, можно написать более элегантно, не забирая лишнюю информацию, сократив сам код и т.д. Суть не в этом.
Выкладывать от лица компании которая предоставляет услуги DevOps в публичное пространство такой код не стоит. Это в том числе говорит о качестве предоставляемых услуг.
Настраиваем approve rules для merge request в бесплатной версии GitLab CE