Code-Review in GitLab CE: Wenn es keine Genehmigungen für den Merge-Request gibt, es aber unbedingt gewünscht ist.

Code-Review in GitLab CE: Wenn es keine Genehmigungen für den Merge-Request gibt, es aber unbedingt gewünscht ist.

Eine der nützlichsten Funktionen, die in der kostenlosen Version von GitLab fehlt, ist die Möglichkeit, gegen das Zurücksetzen des Repositories abzustimmen, während der Merge-Request (MR) mithilfe einer obligatorischen Code-Überprüfung kontrolliert wird.

Lass uns das minimale Feature selbst erstellen – wir verbieten den Merge, bis mehrere Entwickler ein „Daumen hoch“ für den MR geben.

Warum das überhaupt?

Unsere Organisation kann es sich durchaus leisten, eine GitLab-Lizenz zu kaufen. Da die Entwicklung jedoch in einer geschlossenen Umgebung ohne Internetzugang stattfindet und es eine strenge Budgetplanung gibt, kann der Erwerb von Self-Managed-Lizenzen mit den notwendigen Funktionen Monate in Anspruch nehmen, während wir bereits jetzt arbeiten müssen.

Am Ende bleibt uns nichts anderes übrig, als:

  • Entweder den Merge in geschützte Branches für einen Teil der Entwickler komplett zu verbieten, wobei Entwickler, die das Recht zum Mergen haben, beim Zusammenführen fremder MR Konflikte als Bonus erhalten;
  • oder die Möglichkeit zu geben, unkontrollierte Merges mit deinem Master-Branch ohne Code-Überprüfung zu machen, selbst wenn es ein Junior ist, der erst gestern angefangen hat.

Zuerst habe ich angefangen zu googeln, in der Annahme, dass jemand so etwas sicherlich schon gemacht hat (ohne Codeanpassung), aber es stellte sich heraus, dass es eine solche Implementierung in der Community-Version noch nicht gab.

Allgemeines Arbeitsdiagramm

Als Beispiel konfigurieren wir die Genehmigungen für Merge-Requests in einem Testrepository. myapp:

  1. Wir erstellen einen Token für den Zugang zur GitLab API (über den wir Informationen über die Anzahl der „Ja“- und „Nein“-Stimmen erhalten).
  2. Fügen Sie den Token den GitLab-Variablen hinzu.
  3. Verbieten wir den Merge bei Fehlern im Pipeline (wenn die Anzahl der „Ja“-Stimmen unzureichend ist).
  4. Wir konfigurieren die Stimmenprüfung als Teil der CI/CD-Pipeline.
  5. Verbieten wir es, Commits in geschützte Branches zu erstellen, alle Änderungen werden ausschließlich über MRs vorgenommen.
  6. Prüfen wir, was wir erreicht haben.

1. Erstellen Sie einen Token für den API-Zugang.

Gehen Sie zu Benutzer Einstellungen → Zugriffstoken und schreiben Sie den Token auf:

Code-Review in GitLab CE: Wenn es keine Genehmigungen für den Merge-Request gibt, es aber unbedingt gewünscht ist.

Konto für den Erhalt des Tokens.
Der Zugang zur API ermöglicht es, quasi alles mit Ihren Repositories zu tun. Daher empfehle ich, ein separates GitLab-Konto zu erstellen, ihm minimale Berechtigungen für Ihre Repositories (zum Beispiel Reporter) zu geben und den Token für dieses Konto zu erhalten.

2. Fügen Sie den Token den GitLab-Variablen hinzu.

Zum Beispiel haben wir im vorherigen Schritt den Token erhalten. QmN2Y0NOUFlfeXhvd21ZS01aQzgK

Öffnen Sie Einstellungen → CI/CD → Variablen → Variable hinzufügen → GITLAB_TOKEN_FOR_CI

Code-Review in GitLab CE: Wenn es keine Genehmigungen für den Merge-Request gibt, es aber unbedingt gewünscht ist.

$$display$$F(phi)=|y|^2=frac{sin^2(pi frac{Nd}{lambda}sinphi)}{sin^2(pi frac{d}{lambda}sinphi)} $$display$$

Code-Review in GitLab CE: Wenn es keine Genehmigungen für den Merge-Request gibt, es aber unbedingt gewünscht ist.

Das kann sowohl für ein einzelnes Repository als auch für eine Gruppe von Repositories erfolgen.

3. Wir setzen eine Merge-Sperre, wenn nach der Code-Überprüfung keine Genehmigungen von Kollegen eingeholt wurden.

In unserem Fall besteht die Merge-Sperre darin, dass die Build-Pipeline einen Fehler zurückgibt, wenn nicht genügend Stimmen abgegeben wurden.

Gehe zu Einstellungen → Allgemein → Merge-Anfragen → Merge-Checks und aktiviere die Option 'Build-Pipelines müssen erfolgreich ausgeführt werden'.

Code-Review in GitLab CE: Wenn es keine Genehmigungen für den Merge-Request gibt, es aber unbedingt gewünscht ist.

4. Konfigurieren der Pipeline

Wenn du noch keine CI/CD-Pipeline für deine Anwendung erstellt hast
Erstelle eine Datei im Stammverzeichnis des Repositories .gitlab-ci.yml mit folgendem einfachen Inhalt:

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 "Hallo Welt"

Ein separates Repository für die CI/CD-Konfiguration
Ich würde empfehlen, ein separates Repository zu erstellen, in dem du die Datei myapp.gitlab-ci.yml für die Pipeline-Konfiguration anlegst. So kannst du den Zugriff der Teilnehmer, die die Build-Pipeline ändern und ein Zugangstoken erhalten können, besser kontrollieren.

Den Speicherort der neuen Pipeline-Datei musst du angeben, indem du ins Repository myapp gehst – Einstellungen – CI/CD – Build-Pipelines – Benutzerdefinierter CI-Konfigurationspfad – die neue Datei angeben, zum Beispiel myapp.gitlab-ci.yml@gitlab-ce-mr-approvals/Ci

Tipp: Verwende einen Linter für Änderungen in den GitLab CI-Dateien.
Selbst wenn du alleine arbeitest, ist es hilfreich, über MR zu arbeiten und alle Änderungen an den Pipeline-Dateien über den Linter zu laufen. Wenn du einen Fehler im YAML-Dateisyntax hast, wird dies die funktionierende Pipeline nicht beeinträchtigen, sondern einfach das Merge blockieren.

Beispiel für Container mit Lintern, die du in deine Pipeline integrieren kannst:

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

Und ein Beispiel für eine Prüfungsstufe:

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;

Jetzt musst du deiner Pipeline einige Parameter hinzufügen, damit alles funktioniert:

Phasen:
- Test

variables:
NEED_VOTES: 1

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

Die Variable NEED_VOTES definiert, wie viele 'Daumen hoch' die MR haben muss, damit ein Merge möglich ist. Ein Wert von eins bedeutet, dass du deinen eigenen MR genehmigen kannst, indem du ihn 'likest'.

include fügt die Teststufe hinzu, die die Anzahl der 'Likes' überprüft.

Die einfachste Pipeline am Beispiel myapp.gitlab-ci.yml
Phasen:
- bauen
- 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
Skript:
- echo CI_MERGE_REQUEST_TARGET_BRANCH_NAME $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
- java HelloWorld.java

Inhalt check-approve.gitlab-ci.yml
ci-mr:
Stufe: Test
Skript:
- 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} Upvote = 1, Downvote = -1, MR OK wenn Stimmen >=${NEED_VOTES_REAL}"
- if [ "${MR_VOTES}" -ge "$(expr ${NEED_VOTES_REAL})" ];
then
echo "MR OK";
else
echo "MR FEHLER: Mehr Stimmen erforderlich";
exit 1;
fi
Bild: laptevss/gitlab-api-util
Regeln:
- wenn: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ \/^release\/.*$\/'

Weitere Informationen zu dem, was bei der Überprüfung passiert:

  • Es gibt eine Einschränkung, dass die Überprüfung nur beim Erstellen eines MR in die master- oder release/*-Branch erfolgt.
  • Wir erhalten die Anzahl der «Likes» und «Dislikes» über die GitLab-API.
  • Wir berechnen die Differenz zwischen positiven und negativen Rückmeldungen.
  • Wenn die Differenz kleiner als der von uns festgelegte Wert in NEED_VOTES ist, sperren wir die Möglichkeit, einen Merge durchzuführen.

5. Wir verbieten Commits in geschützte Branches.

Wir definieren die Branches, für die wir eine Code-Überprüfung durchführen müssen, und geben an, dass die Arbeit nur über MR erfolgen kann.

Dazu gehen wir zu Einstellungen → Repository → Geschützte Branches:

Code-Review in GitLab CE: Wenn es keine Genehmigungen für den Merge-Request gibt, es aber unbedingt gewünscht ist.

6. Überprüfen

Setzen wir NEED_VOTES: 0

Wir erstellen einen MR und setzen ein «Dislike».

Code-Review in GitLab CE: Wenn es keine Genehmigungen für den Merge-Request gibt, es aber unbedingt gewünscht ist.

In den Build-Logs:

Code-Review in GitLab CE: Wenn es keine Genehmigungen für den Merge-Request gibt, es aber unbedingt gewünscht ist.

Jetzt setzen wir ein «Like» und starten die erneute Überprüfung:

Code-Review in GitLab CE: Wenn es keine Genehmigungen für den Merge-Request gibt, es aber unbedingt gewünscht ist.

Quelle: habr.com

60GB SSD 8Gb DDR4