
Eine der wichtigsten Funktionen, die in der kostenlosen GitLab-Version fehlt, ist die Möglichkeit, gegen das Zurücksetzen des Repositories zu stimmen und Merge Requests (MR) mithilfe einer obligatorischen Code-Überprüfung zu kontrollieren.
Wir werden die minimale Funktionalität selbst umsetzen – wir verbieten Merge, solange nicht mehrere Entwickler ein „Daumen hoch“ für den MR gegeben haben.
Warum ist das überhaupt nötig?
Unsere Organisation kann es sich durchaus leisten, eine Lizenz für GitLab zu erwerben. Da die Entwicklung jedoch in einem geschlossenen Rahmen ohne Internetzugang stattfindet und das Budget streng geplant ist, kann der Erwerb von self-managed Lizenzen mit den erforderlichen Funktionen Monate in Anspruch nehmen, und wir müssen bereits jetzt arbeiten.
Letztendlich bleibt uns nur:
- entweder Merge in geschützte Branches für einige Entwickler vollständig zu verbieten, wobei die Entwickler, die Merge-Rechte haben, bei der Zusammenführung fremder MRs Konflikte als Bonus erhalten;
- oder die Möglichkeit zu geben, unkontrollierte Zusammenführungen mit Ihrer Master-Branch ohne Code-Überprüfung durchzuführen, selbst wenn es sich um einen Junior handelt, der erst gestern angefangen hat.
Zuerst habe ich gegoogelt, in der Annahme, dass sicherlich schon jemand eine ähnliche Lösung (ohne Code-Anpassungen) gemacht hat, aber es stellte sich heraus, dass eine solche Implementierung in der Community-Version noch nicht vorhanden war.
Allgemeine Arbeitsweise
Als Beispiel konfigurieren wir die Genehmigungen für Merge-Requests in einem Test-Repository. :
- Wir erstellen ein Token für den Zugriff auf die GitLab-API (darüber erhalten wir Informationen über die Anzahl der Stimmen "dafür" und "dagegen").
- Fügen Sie das Token zu den GitLab-Variablen hinzu.
- Wir verbieten Merges bei Fehlern im Pipeline (wenn nicht genug Stimmen "dafür" vorliegen).
- Wir richten die Stimmenprüfung als Teil der CI/CD-Pipeline ein.
- Wir verbieten Commits in geschützte Branches, alle Änderungen erfolgen nur über MRs.
- Wir überprüfen, was am Ende herausgekommen ist.
1. Wir erstellen ein Token für den Zugriff auf die API.
Gehen Sie zu Benutzereinstellungen → Zugangstoken und notieren Sie sich das Token:

Konto zur Token-Erstellung
Der Zugriff auf die API ermöglicht nahezu alles mit Ihren Repositories, daher empfehle ich, ein separates GitLab-Konto zu erstellen, ihm minimale Berechtigungen für Ihre Repositories (z. B. Reporter) zu geben und das Token für dieses Konto zu erhalten.
2. Fügen Sie das Token zu den GitLab-Variablen hinzu.
Zum Beispiel haben wir im vorherigen Schritt ein Token erhalten. QmN2Y0NOUFlfeXhvd21ZS01aQzgK
Öffnen Sie Einstellungen → CI/CD → Variablen → Variable hinzufügen → GITLAB_TOKEN_FOR_CI

Insgesamt erhalten wir:

Dies kann sowohl für ein einzelnes Repository als auch für eine Gruppe von Repositories erfolgen.
3. Wir verbieten Merge, falls keine Genehmigungen von Kollegen nach der Code-Überprüfung vorliegen.
In unserem Fall wird das Verbot des Mergers dadurch verursacht, dass die Build-Pipeline einen Fehler zurückgibt, wenn nicht genügend Stimmen abgegeben wurden.
Gehen Sie zu Einstellungen → Allgemein → Merge-Anfragen → Merge-Prüfungen und aktivieren Sie die Option, dass die Build-Pipelines erfolgreich abgeschlossen sein müssen.

4. Wir konfigurieren die Pipeline.
Wenn Sie noch keinen CI/CD-Bauprozess für Ihre Anwendung eingerichtet haben,
erstellen Sie im Stammverzeichnis des Repositories eine Datei .gitlab-ci.yml mit folgendem minimalen 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 "Hello world"
Ein separates Repository für die CI/CD-Konfiguration.
Ich empfehle, ein separates Repository zu erstellen, in dem die Datei myapp.gitlab-ci.yml zur Konfiguration der Pipeline angelegt wird. So können Sie den Zugriff auf die Teilnehmer, die die Build-Pipeline ändern und ein Zugriffstoken erhalten können, besser steuern.
Der Speicherort der neuen Pipeline-Datei muss angegeben werden, indem Sie im Repository myapp — Einstellungen — CI/CD — Build-Optionen — Benutzerdefinierter CI-Konfigurationspfad — die neue Datei, beispielsweise, angeben myapp.gitlab-ci.yml@gitlab-ce-mr-approvals/Ci
Tipp: Verwenden Sie einen Linter, um Änderungen in GitLab CI-Dateien vorzunehmen.
Selbst wenn Sie allein arbeiten, ist es hilfreich, über Merge-Requests (MR) zu arbeiten und alle Ihre Änderungen an den Pipeline-Dateien durch den Linter laufen zu lassen. Wenn Sie einen Syntaxfehler in der YAML-Datei haben, wird dies Ihre aktive Pipeline nicht brechen, sondern einfach den Merge blockieren.
Beispiel-Container mit Lintern, die Sie in Ihre Pipeline integrieren können:
Und ein Beispiel für eine Überprüfungsphase:
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;
Es fehlen einige Parameter in Ihrem Pipeline, damit alles funktioniert:
Stufen:
- Test
Variablen:
NEED_VOTES: 1
einfügen:
- remote: "https://gitlab.com/gitlab-ce-mr-approvals/ci/-/raw/master/check-approve.gitlab-ci.yml"
Die Variable NEED_VOTES legt fest, wie viele «Daumen nach oben» ein MR haben muss, um zusammengeführt werden zu können. Ein Wert von eins bedeutet, dass Sie Ihren eigenen MR durch «Gefällt mir» genehmigen können.
Das Einfügen verbindet die Testphase, die die Anzahl der «Gefällt mir»-Angaben überprüft.
Eine einfache Pipeline am Beispiel von myapp.gitlab-ci.yml
Stufen:
- erstellen
- Test
Variablen:
NEED_VOTES: 0
einfügen:
- 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 von check-approve.gitlab-ci.yml
ci-mr:
Stadium: 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} Stimmenaufwertung = 1, Abwertung = -1, MR OK wenn Stimmen >=${NEED_VOTES_REAL}"
- if [ "${MR_VOTES}" -ge "$(expr ${NEED_VOTES_REAL})" ];
then
echo "MR OK";
else
echo "MR FEHLER Benötige mehr Stimmen";
exit 1;
fi
Image: laptevss/gitlab-api-util
Regeln:
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^release/.*$/'
Mehr darüber, was bei der Überprüfung passiert:
- Es ist festgelegt, dass die Überprüfung nur bei der Erstellung von MR in die master- oder release/*-Branches durchgeführt wird.
- Über die GitLab-API erhalten wir die Anzahl der «Gefällt mir»- und «Gefällt mir nicht»-Angaben.
- Wir berechnen die Differenz zwischen positiven und negativen Rückmeldungen.
- Wenn die Differenz kleiner ist als der von uns angegebene Wert in NEED_VOTES, blockieren wir die Möglichkeit des Merge.
5. Wir verbieten Commits in geschützte Branches.
Wir definieren die Branches, für die wir ein Code-Review durchführen müssen, und geben an, dass die Arbeit an ihnen nur über MR erfolgen kann.
Gehen Sie zu Einstellungen → Repository → Geschützte Branches:

6. Überprüfen
Setzen wir NEED_VOTES: 0
Erstellen Sie einen MR und geben Sie ein "Dislike".

In den Build-Protokollen:

Jetzt geben wir ein "Like" und starten die erneute Überprüfung:

Quelle: habr.com
