
L'une des fonctionnalités les plus nécessaires, qui n'est pas présente dans la version gratuite de GitLab, est la possibilité de voter contre la réinitialisation du dépÎt pour contrÎler la demande de fusion (MR) en utilisant une revue de code obligatoire.
Nous allons crĂ©er nous-mĂȘmes un minimum de fonctionnalitĂ©s - interdire la fusion tant que plusieurs dĂ©veloppeurs n'ont pas mis un « pouce vers le haut » sur la MR.
Pourquoi faire cela ?
Notre organisation peut tout à fait se permettre d'acheter une licence GitLab. Mais, puisque le développement se fait dans un environnement fermé sans accÚs à Internet, et qu'il y a une planification budgétaire stricte, l'achat de licences auto-gérées avec les fonctionnalités nécessaires peut prendre plusieurs mois, alors qu'il faut déjà travailler maintenant.
En fin de compte, cela signifie :
- soit interdire complÚtement la fusion dans les branches protégées pour certains développeurs, mais alors les développeurs ayant le droit de fusionner reçoivent des conflits lors de la fusion des MR des autres en bonus ;
- soit permettre des fusions incontrĂŽlĂ©es avec votre branche principale sans revue de code, mĂȘme si c'est un Junior qui vient juste d'arriver.
La premiÚre chose que j'ai faite a été de googler, pensant que quelqu'un avait certainement déjà fait quelque chose de similaire (sans modification de code), mais il s'est avéré qu'une telle implémentation n'existait pas encore dans la version communautaire.
Schéma général de fonctionnement
à titre d'exemple, configurons les approbations de demande de fusion sur un dépÎt de test :
- Créons un token pour accéder à l'API GitLab (via lequel nous obtiendrons des informations sur le nombre de votes « pour » et « contre »)
- Ajoutons le token aux variables GitLab
- Interdirons la fusion en cas d'erreurs dans le pipeline (si le nombre de votes « pour » n'est pas suffisant)
- Configurerons la vérification des votes comme partie du pipeline CI/CD
- Interdirons de faire des commits dans des branches protégées, toutes les modifications ne se font que par le biais de MR
- Vérifions ce que nous avons obtenu au final
1. Créons un token pour accéder à l'API
Allons dans ParamĂštres utilisateur â Tokens d'accĂšs et notons le token :

Compte pour obtenir le token
L'accÚs à l'API permet de faire presque tout avec vos dépÎts, donc je conseille de créer un compte Gitlab distinct, de lui donner des droits minimaux sur vos dépÎts (par exemple, Reporter) et d'obtenir un token pour ce compte.
2. Ajoutons le token aux variables Gitlab
Par exemple, à l'étape précédente, nous avons obtenu le token QmN2Y0NOUFlfeXhvd21ZS01aQzgK
Ouvrons ParamĂštres â CI/CD â Variables â Ajouter une variable â GITLAB_TOKEN_FOR_CI

Nous obtiendrons :

Cela peut ĂȘtre fait Ă la fois sur un seul dĂ©pĂŽt et sur un groupe de dĂ©pĂŽts.
3. Nous interdisons le Merge si nous n'avons pas obtenu les approbations des collĂšgues aprĂšs un code review.
Dans notre cas, l'interdiction de merge sera que le pipeline de compilation renvoie une erreur en cas de nombre insuffisant de votes.
AccĂ©dez Ă ParamĂštres â GĂ©nĂ©ral â Demandes de fusion â VĂ©rifications de fusion et activez l'option Les pipelines doivent rĂ©ussir.

4. Configurer le pipeline
Si vous n'avez pas encore mis en place de pipeline CI/CD pour votre application,
Créez à la racine du dépÎt un fichier .gitlab-ci.yml avec le contenu le plus 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"
DépÎt séparé pour la configuration CI/CD
Je recommanderais de crĂ©er un dĂ©pĂŽt sĂ©parĂ© oĂč il faudrait crĂ©er le fichier myapp.gitlab-ci.yml pour configurer le pipeline. Ainsi, vous pourrez mieux contrĂŽler l'accĂšs des participants qui peuvent modifier le pipeline de compilation et obtenir un token d'accĂšs.
L'emplacement du nouveau fichier de pipeline devra ĂȘtre indiquĂ© en accĂ©dant au dĂ©pĂŽt myapp â ParamĂštres â CI/CD â Pipelines â Chemin de configuration CI personnalisĂ© â indiquer le nouveau fichier, par exemple myapp.gitlab-ci.yml@gitlab-ce-mr-approvals/Ci
Conseil : utilisez un linter pour apporter des modifications aux fichiers GitLab CI
MĂȘme si vous travaillez seul, faire passer vos modifications de fichiers de pipeline par un merge request peut ĂȘtre un bon assistant. Si vous faites une erreur dans la syntaxe du fichier YAML, cela ne cassera pas votre pipeline fonctionnel, mais empĂȘchera simplement le merge.
Exemples de conteneurs avec des linter que vous pouvez intégrer dans votre pipeline :
Et un exemple de phase de vérification :
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 ne reste plus qu'Ă ajouter quelques paramĂštres Ă votre pipeline afin que tout fonctionne :
étapes :
- 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 combien de « j'aime » doivent ĂȘtre attribuĂ©s Ă la demande de fusion pour que le merge soit disponible. Une valeur de un signifie que vous pouvez approuver vous-mĂȘme votre demande de fusion en lui « donnant un like ».
include inclut la phase test, vérifiant le nombre de « likes ».
Un pipeline simple avec l'exemple myapp.gitlab-ci.yml
étapes :
- construire
- test
variables :
NEED_VOTES: 0
include :
- remote: "https://gitlab.com/gitlab-ce-mr-approvals/ci/-/raw/master/check-approve.gitlab-ci.yml"
run-myapp :
étape : 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 :
étape : 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 si votes >=${NEED_VOTES_REAL}"
- if [ "${MR_VOTES}" -ge "$(expr ${NEED_VOTES_REAL})" ];
alors
echo "MR OK";
sinon
echo "MR ERROR Besoin de plus de votes";
exit 1;
fi
image : laptevss\/gitlab-api-util
rĂšgles :
- if : '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ \/^release\/.*$\/'
Plus d'informations sur ce qui se passe lors de la vérification :
- il y a une restriction qui indique que la vérification ne se fera que lors de la création d'un MR dans les branches master ou release/*
- en utilisant l'API GitLab, nous obtenons le nombre de « j'aime » et de « je n'aime pas »
- nous calculons la différence entre les retours positifs et négatifs
- si la différence est inférieure à la valeur que nous avons déterminée dans NEED_VOTES, nous bloquons la possibilité de fusion
5. Interdire les commits dans les branches protégées
Nous définissons les branches pour lesquelles nous devons effectuer une revue de code et indiquons que le travail avec elles ne peut se faire que par le biais de MR.
Pour cela, accĂ©dez Ă ParamĂštres â RĂ©pertoire â Branches protĂ©gĂ©es :

6. Vérification
Définissons NEED_VOTES : 0
Faisons un MR et mettons un « je n'aime pas ».

Dans les journaux de construction :

Maintenant, mettons un « j'aime » et relançons la vérification :

Source : habr.com
