
Jednou z najdôležitejších funkcií, ktorá chýba vo verzii GitLab, je možnosť hlasovať proti zrušeniu repozitára prostredníctvom kontroly Merge requestu (MR) s povinným code review.
Vytvoríme minimálnu funkcionalitu sami - zakážeme Merge, kým niekoľko vývojárov nedá 'palec hore' na MR.
Prečo je to vôbec dôležité?
Naša organizácia si celkom môže dovoliť zakúpiť licenciu GitLab. Ale pretože sa vývoj realizuje vo uzavretom prostredí bez prístupu na internet a je prísne plánovanie rozpočtu, nákup licencií self-managed s potrebnou funkcionalitou sa môže predĺžiť na mnoho mesiacov, a je potrebné pracovať už teraz.
Nakoniec musíme:
- buď úplne zakázať Merge do chránených vetiev pre niektorých vývojárov, ale potom vývojári, ktorí majú právo na Merge, dostávajú pri zlúčení cudzích MR ako bonus konflikty;
- alebo umožniť bezkontrolované zlúčenia s vašou master vetvou bez code review, aj keď je to Junior, ktorý sa pripojil len včera.
Hneď som začal googliť, pričom som si myslel, že určite už niekto niečo podobné urobil (bez úprav kódu), ale ukázalo sa, že takáto implementácia v community verzii ešte neexistovala.
Celková schéma práce
Ako príklad nastavíme schválenia Merge requestov na testovacom repozitári :
- Vytvoríme token pre prístup k API GitLab (cez ktorý získame informácie o počte hlasov 'za' a 'proti')
- Pridáme token do premenných GitLab
- Zakážeme Merge pri chybách v pipeline (ak je málo hlasov 'za')
- Nastavíme kontrolu hlasov ako súčasť pipeline CI/CD
- Zakážeme vykonávať commity do chránených vetiev, všetky zmeny vykonávame iba cez MR
- Skontrolujeme, čo sa nakoniec podarilo
1. Vytvoríme token pre prístup k API
Prejdeme do Nastavenia používateľa → Tokeny prístupu a zapíšeme si token:

Účet pre získanie tokenu
Prístup k API umožňuje robiť takmer všetko s vašimi repozitármi, takže odporúčam vytvoriť samostatný účet Gitlab, dať mu minimálne práva na vaše repozitáre (napríklad Reporter) a získať token pre tento účet.
2. Pridáme token do premenných Gitlab
Napríklad, na predchádzajúcom kroku sme získali token QmN2Y0NOUFlfeXhvd21ZS01aQzgK
Otvoríme Nastavenia → CI/CD → Premenné → Pridať premennú → GITLAB_TOKEN_FOR_CI

Nakoniec dostaneme:

Toto je možné urobiť ako na jednom repozitári, tak aj na skupine repozitárov.
3. Zakážte Merge, ak nie sú schválenia od kolegov po vykonaní code review.
V našom prípade bude zákazom na Merge to, že zostavovací pipeline vráti chybu pri nedostatočnom počte hlasov.
Prejdite do Nastavenia → Základné → Požiadavky na slúčenie → Kontroly slúčenia a zapnite možnosť Zostavovacie línie musia byť úspešne vykonané.

4. Nastavte pipeline
Ak ste ešte nevytvorili CI/CD pipeline pre vašu aplikáciu
Vytvorte v koreňovom repozitári súbor .gitlab-ci.yml s najjednoduchším obsahom:
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"
Samostatný repozitár pre konfiguráciu CI/CD
Odporúčam vytvoriť samostatný repozitár, v ktorom potrebujete vytvoriť súbor myapp.gitlab-ci.yml na nastavenie pipeline. Tak budete mať lepšiu kontrolu nad prístupom účastníkov, ktorí môžu zmeniť zostavovací pipeline a získať prístupový token.
Miesto nového súboru pipeline bude potrebné uviesť tak, že prejdete do repozitára myapp — Nastavenia — CI/CD — Zostavovacie línie — Používateľská cesta konfigurácie CI — uviesť nový súbor, napríklad myapp.gitlab-ci.yml@gitlab-ce-mr-approvals/Ci
Tip: používajte linter na vykonávanie zmien v súboroch GitLab CI
Aj keby ste pracovali sami, dobrým pomocníkom bude práca cez MR, aby ste prešli všetky vaše zmeny súborov pipeline cez linter. Ak urobíte chybu v syntaxi YAML súboru, to vám nepovolí rozbiť pracovný pipeline, ale jednoducho zablokuje Merge.
Príklad kontajnerov s linters, ktoré môžete integrovať do vášho pipeline:
A príklad etapy kontroly:
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;
Zostáva pridať do vášho pipeline niekoľko parametrov, aby to všetko fungovalo:
etapy:
- test
variables:
NEED_VOTES: 1
include:
- remote: "https://gitlab.com/gitlab-ce-mr-approvals/ci/-/raw/master/check-approve.gitlab-ci.yml"
Premenná NEED_VOTES určuje, koľko „výťahov“ musí mať MR, aby bol dostupný Merge. Hodnota rovná sa jednej znamená, že môžete sami schváliť svoj MR, „lajknutím“ ho.
include zapája etapu test, ktorá kontroluje počet „lajkov“.
Najjednoduchší pipeline na príklade myapp.gitlab-ci.yml
etapy:
- vytvoriť
- 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
Obsah 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\/.*$\/'
Viac informácií o tom, čo sa deje počas kontroly:
- bolo nastavené obmedzenie, že kontrola bude prebiehať len pri vytváraní MR do vetiev master alebo release/*
- pomocou GitLab API získavame počet „lajkov“ a „nelajkov“
- vypočítavame rozdiel medzi pozitívnymi a negatívnymi reakciami
- ak je rozdiel menší ako hodnota, ktorú sme nastavili v NEED_VOTES, blokujeme možnosť uskutočniť zlúčenie
5. Zakazujeme commity do chránených vetiev
Definujeme vetvy, pre ktoré musíme vykonávať code review a uvádzame, že s nimi môžeme pracovať iba cez MR.
Na to prejdeme do Nastavenia → Repozitár → Chránené vetvy:

6. Kontrolujeme
Nastavíme NEED_VOTES: 0
Vytvoríme MR a dáme „nelajk“.

V logoch zostavenia:

Teraz dáme „lajk“ a spustíme opätovnú kontrolu:

Zdroj: habr.com
