L'une des fonctionnalités les plus nécessaires qui ne figure pas dans la version gratuite de GitLab est la possibilité de voter contre la mise à zéro du référentiel pour contrôler la demande de fusion (MR) à l'aide de la révision de code obligatoire.
Nous ferons le minimum de fonctionnalités nous-mêmes - nous désactiverons Merge jusqu'à ce que plusieurs développeurs donnent un « pouce en l'air » à MR.
Pourquoi est-ce du tout?
Notre organisation peut se permettre d'acheter une licence GitLab. Mais, comme le développement est effectué en boucle fermée sans accès à Internet et qu'il existe une planification budgétaire stricte, l'achat de licences autogérées avec les fonctionnalités nécessaires peut prendre plusieurs mois et vous devez travailler maintenant.
En conséquence, vous devez :
- ou interdire complètement la fusion dans des branches protégées pour certains développeurs, mais les développeurs qui ont le droit de fusionner reçoivent des conflits lors de la fusion des MR d'autres personnes en bonus ;
- ou vous permettre de faire des fusions incontrôlées avec votre branche master sans revue de code, même s'il s'agit d'un Junior qui vient de s'installer hier.
La première chose que j'ai faite a été d'aller sur Google, croyant que quelqu'un avait déjà fait quelque chose de similaire (sans affiner le code), mais il s'est avéré qu'il n'y avait pas encore une telle implémentation dans la version communautaire.
Plan général de travail
Par exemple, configurons les approbations de demande de fusion sur un référentiel de test
- Créons un jeton pour accéder à l'API GitLab (à travers lui, nous recevrons des informations sur le nombre de votes pour et contre)
- Ajouter un jeton aux variables GitLab
- Désactiver la fusion s'il y a des erreurs dans le pipeline (s'il n'y a pas assez de votes "pour")
- Configurer la validation des votes dans le cadre du pipeline CI/CD
- Nous interdirons de faire des commits sur des branches protégées, nous effectuons toutes les modifications uniquement via MR
- Vérifions ce qui s'est passé à la fin
1. Créez un jeton pour accéder à l'API
Accédez à Paramètres utilisateur → Jetons d'accès et notez le jeton :
Compte pour recevoir le jeton
L'accès à l'API vous permet de faire presque n'importe quoi avec vos référentiels, je vous suggère donc de créer un compte Gitlab séparé, de lui donner des droits minimaux sur vos référentiels (comme Reporter) et d'obtenir un jeton pour ce compte.
2. Ajouter le jeton aux variables Gitlab
Par exemple, à l'étape précédente, nous avons reçu un jeton QmN2Y0NOUFlfeXhvd21ZS01aQzgK
Ouvrez Paramètres → CI/CD → Variables → Ajouter une variable → GITLAB_TOKEN_FOR_CI
En conséquence, nous obtenons :
Cela peut être fait à la fois sur un référentiel et sur un groupe de référentiels.
3. Nous interdisons Merge si l'approbation des collègues n'est pas reçue après la révision du code
Dans notre cas, l'interdiction de Merge sera que le pipeline d'assemblage renverra une erreur s'il n'y a pas assez de votes.
Accédez à Paramètres → Général → Demandes de fusion → Contrôles de fusion et activez l'option Les lignes d'assemblage doivent s'exécuter avec succès.
4. Configurer le pipeline
Si vous n'avez pas encore créé de pipeline CI/CD pour votre application
Créer un fichier à la racine du dépôt .gitlab-ci.yml avec un contenu simple :
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"
Référentiel séparé pour la configuration CI/CD
Je recommanderais de créer un référentiel séparé dans lequel vous devez créer un fichier myapp.gitlab-ci.yml pour configurer le pipeline. De cette façon, vous pouvez mieux contrôler l'accès des contributeurs qui peuvent modifier le pipeline de construction et obtenir un jeton d'accès.
L'emplacement du nouveau fichier de pipeline devra être spécifié en allant dans le référentiel myapp - Paramètres - CI / CD - Lignes d'assemblage - Chemin de configuration CI personnalisé - spécifiez un nouveau fichier, par exemple monapp.gitlab-ci.yml@gitlab-ce-mr-approvals/Ci
Astuce : Utilisez un linter pour apporter des modifications aux fichiers GitLab CI
Même si vous travaillez seul, travailler via MR sera une bonne aide, en exécutant toutes vos modifications sur les fichiers de pipeline via le linter. Si vous faites une erreur dans la syntaxe du fichier YAML, cela ne vous permettra pas de casser le pipeline de travail, mais bloquera simplement Merge.
Un exemple de conteneurs avec des linters que vous pouvez intégrer dans votre pipeline :
Et un exemple de l'étape de validation :
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;
Il reste à ajouter quelques paramètres à votre pipeline pour le faire fonctionner :
stages:
- test
variables:
NEED_VOTES: 1
include:
- remote: "https://gitlab.com/gitlab-ce-mr-approvals/ci/-/raw/master/check-approve.gitlab-ci.yml"
La variable NEED_VOTES détermine le nombre de "pouces vers le haut" que MR doit avoir pour que Merge soit disponible. Une valeur de un signifie que vous pouvez vous-même approuver votre MR en "l'aimant".
include comprend l'étape de test, qui vérifie le nombre de "j'aime".
Le pipeline le plus simple utilisant myapp.gitlab-ci.yml comme exemple
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
Contenu de 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/.*$/'
En savoir plus sur ce qui se passe lors de la vérification :
- la restriction est définie que la vérification ne sera effectuée que lors de la création d'un MR dans les branches master ou release /*
- en utilisant l'API GitLab, obtenez le nombre de "j'aime" et de "je n'aime pas"
- calculer la différence entre les réponses positives et négatives
- si la différence est inférieure à la valeur que nous avons définie dans NEED_VOTES, nous bloquons la possibilité de fusionner
5. Désactiver les commits sur les branches protégées
Nous déterminons les branches pour lesquelles nous devons effectuer une révision du code et indiquons qu'elles ne peuvent être travaillées que via MR.
Pour cela, rendez-vous dans Paramètres → Référentiel → Branches protégées :
6. Vérification
Définir NEED_VOTES : 0
On fait du MR et on met un "je n'aime pas".
Dans les journaux de compilation :
Maintenant, mettez "j'aime" et exécutez une nouvelle vérification :
Source: habr.com