Code review у Gitlab CE: калі Merge request approvals няма, але вельмі жадаецца

Code review у Gitlab CE: калі Merge request approvals няма, але вельмі жадаецца

Адной з самых патрэбных функцый, якой няма ў бясплатнай версіі GitLab, з'яўляецца магчымасць галасавання супраць абнулення рэпазітара кантраляваць Merge request (MR), выкарыстоўваючы абавязковы code review.

Зробім мінімальны функцыянал самі - забаронім Merge, пакуль некалькі распрацоўшчыкаў не паставяць «палец уверх» на MR.

Навошта гэта ўвогуле?

Наша арганізацыя цалкам можа дазволіць сабе купіць ліцэнзію GitLab. Але, бо распрацоўка вядзецца ў зачыненым контуры без доступу ў інтэрнэт, і ёсць цвёрдае планаванне бюджэту, закуп ліцэнзій self-managed з патрэбным функцыяналам можа зацягнуцца на шматлікія месяцы, а працаваць трэба ўжо цяпер.

У выніку даводзіцца:

  • альбо зусім забараняць Merge у абароненыя галінкі для часткі распрацоўшчыкаў, але тады распрацоўшчыкі, якія маюць права на Merge, атрымліваюць канфлікты пры зліцці чужых MR як бонус;
  • альбо даваць магчымасць рабіць бескантрольныя зліцці з вашай майстар-галінкай без code review, нават калі гэта Junior, які ўладкаваўся толькі ўчора.

Перш за ўсё адправіўся гугліць, мяркуючы, што ўжо сапраўды хтосьці нешта падобнае ўжо зрабіў (без дапрацоўкі кода), але аказалася, што падобнай рэалізацыі ў community версіі яшчэ не было.

Агульная схема працы

У якасці прыкладу наладзім Merge request approvals на тэставым рэпазітары маё прыкладанне:

  1. Створым токен для доступу да API GitLab (праз яго будзем атрымліваць інфармацыю аб колькасці галасоў "за" і "супраць")
  2. Дадамо токен у зменныя GitLab
  3. Забаранім Merge пры памылках у пайплайне (калі галасоў "за" недастаткова)
  4. Наладзім праверку галасоў як частка пайплайну CI/CD
  5. Забаранім рабіць коміты ў абароненыя галінкі, усе змены праводзім толькі праз MR
  6. Праверым, што атрымалася ў выніку

1. Ствараем токен для доступу да API

Заходзім у Налады карыстальніка → Такены доступу і запісваем токен:

Code review у Gitlab CE: калі Merge request approvals няма, але вельмі жадаецца

Уліковы запіс для атрымання токена
Доступ да API дазваляе рабіць практычна ўсё з вашымі рэпазітарамі, таму раю стварыць асобны ўліковы запіс Gitlab, даць ёй мінімальныя правы на вашыя рэпазаторыі (напрыклад, Reporter) і атрымаць токен для гэтага ўліковага запісу.

2. Дадаем токен у зменныя Gitlab

Напрыклад, на папярэднім кроку мы атрымалі токен QmN2Y0NOUFlfeXhvd21ZS01aQzgK

Адкрываем паводле → CI/CD → Пераменныя → Дадаць зменную → GITLAB_TOKEN_FOR_CI

Code review у Gitlab CE: калі Merge request approvals няма, але вельмі жадаецца

У выніку атрымаем:

Code review у Gitlab CE: калі Merge request approvals няма, але вельмі жадаецца

Гэта можна зрабіць як на адным рэпазітары, так і на групе рэпазітароў.

3. Ставім забарону на Merge, калі не атрыманы адабрэнні калег пасля праведзенага code review

У нашым выпадку забаронай на Merge будзе з'яўляцца тое, што зборачны канвеер верне памылку пры недастатковай колькасці галасоў.

Заходзім у Налады → Асноўныя → Запыты на зліццё → Праверкі зліцця і ўключаем опцыю Зборачныя лініі павінны паспяхова выканацца.

Code review у Gitlab CE: калі Merge request approvals няма, але вельмі жадаецца

4. Наладжваем пайплайн

Калі вы яшчэ не рабілі CI/CD канвеер для вашага прыкладання
Ствараем у корані рэпазітара файл .gitlab-ci.yml з найпростым зместам:

stages:
  - build
  - test

variables:
  NEED_VOTES: 1

include:
  - remote: "https://gitlab.com/gitlab-ce-mr-approvals/ci/-/raw/master/check-approve.gitlab-ci.yml"

run-myapp:
  stage: build
  script: echo "Hello world"

Асобны рэпазітар для канфігурацыі CI/CD
Я б рэкамендаваў зрабіць асобны рэпазітар, у якім неабходна стварыць файл myapp.gitlab-ci.yml для налады канвеера. Дык вы зможаце лепш кантраляваць доступ удзельнікаў, якія могуць змяніць канвеер зборкі і атрымаць токен доступу.

Размяшчэнне новага файла канвеера трэба будзе паказаць, зойдучы ў рэпазітар myapp - Налады - CI/CD - Зборачныя лініі - Карыстацкі шлях канфігурацыі CI - паказаць новы файл, напрыклад myapp.gitlab-ci.yml@gitlab-ce-mr-approvals/Ci

Рада: выкарыстайце лінтэр для занясення змен у файлы GitLab CI
Нават калі вы працуеце адзін, добрым памагатым выступіць праца праз MR, праганяючы ўсе вашы змены файлаў пайплайна праз лінтэр. Калі вы памыліцеся ў сінтаксісе YAML-файла, гэта не дасць вам зламаць працоўны канвеер, а проста заблакуе Merge.

Прыклад кантэйнераў з лінтэрамі, якія вы можаце ўбудаваць у ваш пайплайн:

hub.docker.com/r/gableroux/gitlab-ci-lint
hub.docker.com/r/sebiwi/gitlab-ci-validate

І прыклад стадыі праверкі:

stages:
  - lint

lint:
  stage: lint
  image: sebiwi/gitlab-ci-validate:1.3.0
  variables:
    GITLAB_HOST: https://gitlab.com
  script:
    - CI_FILES=(./*.yml)
    - for f in "${CI_FILES[@]}"; do
        gitlab-ci-validate $f;
      done;

Засталося дадаць у ваш пайплайн некалькі параметраў, каб усё зарабіла:

stages:
- test

variables:
NEED_VOTES: 1

include:
- remote: "https://gitlab.com/gitlab-ce-mr-approvals/ci/-/raw/master/check-approve.gitlab-ci.yml"

Пераменная NEED_VOTES вызначае колькі "пальцаў уверх" павінна быць у MR, каб быў даступны Merge. Значэнне, роўнае адзінцы, азначае, што вы самі можаце ўхваліць свой MR, "лайкнуўшы" яго.

include падлучае стадыю test, якая правярае колькасць «лайкаў».

Найпросты пайплайн на прыкладзе myapp.gitlab-ci.yml
stages:
- build
- test

variables:
NEED_VOTES: 0

include:
- remote: "https://gitlab.com/gitlab-ce-mr-approvals/ci/-/raw/master/check-approve.gitlab-ci.yml"

run-myapp:
stage: build
image: openjdk
script:
- echo CI_MERGE_REQUEST_TARGET_BRANCH_NAME $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
- java HelloWorld.java

Змест check-approve.gitlab-ci.yml
ci-mr:
stage: test
script:
- echo ${CI_API_V4_URL}
- echo "CI_PROJECT_ID ${CI_PROJECT_ID}"
- echo "CI_COMMIT_SHA ${CI_COMMIT_SHA}"
- "export MR_ID=$(curl --silent --request GET --header "PRIVATE-TOKEN: $GITLAB_TOKEN_FOR_CI" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests | jq ".[] | if .sha == \"${CI_COMMIT_SHA}\" then .id else {} end" | grep --invert-match {})"
- "export MR_TITLE=$(curl --silent --request GET --header "PRIVATE-TOKEN: $GITLAB_TOKEN_FOR_CI" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests | jq ".[] | if .sha == \"${CI_COMMIT_SHA}\" then .title else {} end" | grep --invert-match {})"
- "export MR_WIP=$(curl --silent --request GET --header "PRIVATE-TOKEN: $GITLAB_TOKEN_FOR_CI" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests | jq ".[] | if .sha == \"${CI_COMMIT_SHA}\" then .work_in_progress else {} end" | grep --invert-match {})"
- "export MR_UPVOTES=$(curl --silent --request GET --header "PRIVATE-TOKEN: $GITLAB_TOKEN_FOR_CI" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests | jq ".[] | if .sha == \"${CI_COMMIT_SHA}\" then .upvotes else {} end" | grep --invert-match {})"
- "export MR_DOWNVOTES=$(curl --silent --request GET --header "PRIVATE-TOKEN: $GITLAB_TOKEN_FOR_CI" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests | jq ".[] | if .sha == \"${CI_COMMIT_SHA}\" then .downvotes else {} end" | grep --invert-match {})"
- MR_VOTES=$(expr ${MR_UPVOTES} - ${MR_DOWNVOTES})
- NEED_VOTES_REAL=${NEED_VOTES:-1}
- echo "MR_ID ${MR_ID} MR_TITLE ${MR_TITLE} MR_WIP ${MR_WIP} MR_UPVOTES ${MR_UPVOTES} MR_DOWNVOTES ${MR_DOWNVOTES}"
- echo "MR_VOTES ${MR_VOTES} Up vote = 1, down vote = -1, MR OK if votes >=${NEED_VOTES_REAL}"
- if [ "${MR_VOTES}" -ge "$(expr ${NEED_VOTES_REAL})" ];
then
echo "MR OK";
else
echo "MR ERROR Need more votes";
exit 1;
fi
image: laptevss/gitlab-api-util
rules:
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^release/.*$/'

Падрабязней аб тым, што адбываецца пры праверцы:

  • устаноўлена абмежаванне, што праверка будзе толькі пры стварэнні MR у галінкі master ці release/*
  • выкарыстоўваючы API GitLab, атрымліваем колькасць "лайкаў" і "дызлайкаў"
  • вылічаем рознасць паміж станоўчымі і адмоўнымі водгукамі
  • калі рознасць менш зададзенага намі значэння ў NEED_VOTES, то блакуем магчымасць зрабіць зліццё

5. Забараняем коміты ў абароненыя галінкі

Вызначаем галінкі, для якіх мы павінны праводзіць code review і паказваем, што працаваць з імі можна толькі праз MR.

Для гэтага заходзім у паводле → Рэпазітар → Protected Branches:

Code review у Gitlab CE: калі Merge request approvals няма, але вельмі жадаецца

6. Правяраем

Зададзім NEED_VOTES: 0

Які робіцца MR і ставім «дызлайк».

Code review у Gitlab CE: калі Merge request approvals няма, але вельмі жадаецца

У логах зборкі:

Code review у Gitlab CE: калі Merge request approvals няма, але вельмі жадаецца

Цяпер ставім «лайк» і запускаем паўторную праверку:

Code review у Gitlab CE: калі Merge request approvals няма, але вельмі жадаецца

Крыніца: habr.com

Дадаць каментар