Revizuirea codului în Gitlab CE: dacă aprobările cererii de fuziune nu există, dar este foarte tentant.

Revizuirea codului în Gitlab CE: dacă aprobările cererii de fuziune nu există, dar este foarte tentant.

Una dintre cele mai necesare funcții care lipsesc în versiunea gratuită a GitLab este posibilitatea de a vota împotriva resettării unui repository pentru a controla Merge request (MR) folosind o revizuire de cod obligatorie.

Vom implementa un minim de funcționalitate noi – vom interzice Merge-ul, până când câțiva dezvoltatori nu vor da «thumbs up» pentru MR.

De ce este necesar acest lucru?

Organizația noastră își poate permite să achiziționeze o licență GitLab. Totuși, deoarece dezvoltarea se desfășoară într-un mediu închis, fără acces la internet, și există o planificare strictă a bugetului, achiziția licențelor self-managed cu funcționalitatea necesară poate dura multe luni, iar munca trebuie să înceapă deja acum.

În consecință, se ajunge la:

  • fie să interzicem complet Merge-ul în ramurile protejate pentru o parte dintre dezvoltatori, dar atunci dezvoltatorii care au dreptul de a face Merge vor obține conflicte la fuzionarea MR-urilor altora, ca bonus;
  • fie să oferim posibilitatea de a face fuzionări necontrolate cu ramura principală, fără revizuire de cod, chiar dacă este vorba de un Junior care abia a fost angajat ieri.

Primul lucru pe care l-am făcut a fost să caut pe Google, presupunând că cu siguranță cineva a realizat deja ceva similar (fără modificarea codului), dar s-a dovedit că o astfel de implementare în versiunea community nu existase încă.

Schema generală de lucru

Ca exemplu, vom configura aprobările pentru Merge request-uri pe un repository de test. . Instanța pornită va căuta configurarea sa:

  1. Vom crea un token pentru accesul la API-ul GitLab (prin care vom obține informații despre numărul de voturi «pentru» și «împotrivă»)
  2. Vom adăuga tokenul în variabilele GitLab
  3. Vom interzice Merge-ul în cazul unor erori în pipeline (dacă nu sunt suficiente voturi «pentru»)
  4. Vom configura verificarea voturilor ca parte a pipeline-ului CI/CD
  5. Vom interzice realizarea commit-urilor în ramurile protejate, toate modificările fiind efectuate numai prin MR.
  6. Vom verifica ce am obținut în final

1. Creăm un token pentru accesul la API

Accesăm Setările utilizatorului → Tokenuri de acces și notăm tokenul:

Revizuirea codului în Gitlab CE: dacă aprobările cererii de fuziune nu există, dar este foarte tentant.

Contul pentru obținerea tokenului
Accesul la API permite practic orice acțiune cu repositoarele dvs., așa că recomand să creați un cont GitLab separat, să-i oferiți drepturi minime asupra repositoarelor dvs. (de exemplu, Reporter) și să obțineți un token pentru acest cont.

2. Adăugăm tokenul în variabilele GitLab

De exemplu, în pasul anterior am obținut tokenul QmN2Y0NOUFlfeXhvd21ZS01aQzgK

Accesăm Setări → CI/CD → Variabile → Adăugați variabilă → GITLAB_TOKEN_FOR_CI

Revizuirea codului în Gitlab CE: dacă aprobările cererii de fuziune nu există, dar este foarte tentant.

În rezultatul final vom obține:

Revizuirea codului în Gitlab CE: dacă aprobările cererii de fuziune nu există, dar este foarte tentant.

Acest lucru se poate face atât pe un singur repository, cât și pe un grup de repositoare.

3. Interzicem fuzionarea dacă nu primim aprobările colegilor după revizuirea codului

În cazul nostru, interzicerea fuzionării va fi că linia de construcție va returna o eroare în cazul unui număr insuficient de voturi.

Accesăm Setări → Generale → Cereri de fuzionare → Verificări de fuzionare și activăm opțiunea Linile de construcție trebuie să fie finalizate cu succes.

Revizuirea codului în Gitlab CE: dacă aprobările cererii de fuziune nu există, dar este foarte tentant.

4. Configurăm pipeline-ul

Dacă nu ați creat încă un pipeline CI/CD pentru aplicația dvs.
Creăm în rădăcina repository-ului un fișier .gitlab-ci.yml cu conținut simplu:

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"

Repository separat pentru configurația CI/CD
V-aș recomanda să creați un repository separat în care să creați fișierul myapp.gitlab-ci.yml pentru configurarea pipeline-ului. Așa veți putea controla mai bine accesul participanților care pot schimba pipeline-ul de construcție și obține un token de acces.

Locația noului fișier pipeline va trebui specificată, intrând în repository-ul myapp — Setări — CI/CD — Linii de construcție — Calea de configurare CI personalizată — specificați noul fișier, de exemplu myapp.gitlab-ci.yml@gitlab-ce-mr-approvals/Ci

Sfaturi: folosiți un linter pentru a face modificări în fișierele GitLab CI
Chiar dacă lucrați singur, o idee bună este să lucrați prin MR, rulat toate modificările fișierelor pipeline-ului prin linter. Dacă greșiți în sintaxa fișierului YAML, acest lucru nu vă va strica pipeline-ul funcțional, ci va bloca pur și simplu fuzionarea.

Exemplu de containere cu lintere pe care le puteți integra în pipeline-ul dvs.:

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

Și un exemplu de etapă de verificare:

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;

Rămâne să adăugați în pipeline-ul dvs. câteva variabile pentru ca totul să funcționeze:

etape:
- test

variables:
NEED_VOTES: 1

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

Variabila NEED_VOTES determină câte "like-uri" trebuie să aibă MR pentru a permite fuzionarea. O valoare de unu înseamnă că puteți aproba singur MR-ul dvs., "apreciindu-l".

include includează etapa test care verifică numărul de "like-uri".

Pipeline-ul cel mai simplu pe exemplul myapp.gitlab-ci.yml
etape:
- construiește
- 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

Conținutul check-approve.gitlab-ci.yml
ci-mr:
stadiu: 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} Vot A = 1, vot Ă = -1, MR OK dacă voturile >=${NEED_VOTES_REAL}"
- if [ "${MR_VOTES}" -ge "$(expr ${NEED_VOTES_REAL})" ];
atunci
echo "MR OK";
altfel
echo "MR ERROR Necesită mai multe voturi";
exit 1;
fi
imagine: laptevss\/gitlab-api-util
reguli:
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ \/^release\/.*$\/'

Mai multe informații despre ce se întâmplă în timpul verificării:

  • s-a stabilit o restricție astfel încât verificarea să se facă numai la crearea MR în ramurile master sau release/*
  • folosind API-ul GitLab, obținem numărul de «like-uri» și «dislike-uri»
  • calculăm diferența dintre răspunsurile pozitive și negative
  • dacă diferența este mai mică decât valoarea stabilită de noi în NEED_VOTES, blocăm posibilitatea de a face un merge

5. Interzicerea commit-urilor în ramuri protejate

Definim ramurile pentru care trebuie să efectuăm code review și specificăm că lucrul cu acestea se poate face doar prin MR.

Pentru aceasta, mergem la Setări → Repositoriu → Ramuri Protejate:

Revizuirea codului în Gitlab CE: dacă aprobările cererii de fuziune nu există, dar este foarte tentant.

6. Verificăm

Să stabilim NEED_VOTES: 0

Facem MR și punem «dislike».

Revizuirea codului în Gitlab CE: dacă aprobările cererii de fuziune nu există, dar este foarte tentant.

În log-urile de construire:

Revizuirea codului în Gitlab CE: dacă aprobările cererii de fuziune nu există, dar este foarte tentant.

Acum punem «like» și reluăm verificarea:

Revizuirea codului în Gitlab CE: dacă aprobările cererii de fuziune nu există, dar este foarte tentant.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster