
En av de mest efterfrÄgade funktionerna, som saknas i den kostnadsfria versionen av GitLab, Àr möjligheten att rösta emot att ÄterstÀlla ett repository och kontrollera merge-förfrÄgningar (MR) med hjÀlp av obligatorisk kodgranskning.
Vi ska skapa minimal funktionalitet sjÀlva - förbjuda merge tills flera utvecklare har gett "tummen upp" pÄ MR.
Varför behövs detta överhuvudtaget?
VÄr organisation kan absolut ha rÄd med en licens för GitLab. Men eftersom utvecklingen sker i en sluten miljö utan internetÄtkomst, och det finns strikt budgetplanering, kan anskaffningen av self-managed licenser med nödvÀndig funktionalitet dra ut pÄ tiden i flera mÄnader, medan vi redan mÄste arbeta nu.
Resultatet blir att vi:
- antingen helt förbjuder merges i skyddade grenar för vissa utvecklare, men dÄ fÄr utvecklare som har rÀtt att merge konflikter vid sammanslagning av andras MR som en bonus;
- eller sÄ ger vi möjlighet till okontrollerade sammanslagningar med din mastergren utan kodgranskning, Àven om det Àr en Junior som anstÀlldes just igÄr.
Först och frÀmst började jag googla och trodde att nÄgon helt sÀkert hade gjort nÄgot liknande tidigare (utan kodÀndringar), men det visade sig att en sÄdan implementation Ànnu inte funnits i community-versionen.
AllmÀn arbetsprocess
Som exempel ska vi stÀlla in godkÀnnanden av merge-förfrÄgningar pÄ ett testrepository :
- Skapa en token för Ätkomst till GitLab API (genom den kommer vi att fÄ information om antalet röster "för" och "emot")
- LĂ€gg till token i GitLab-variabler
- Förbjud merge vid fel i pipelinen (om antalet röster "för" Àr otillrÀckligt)
- StÀll in röstkontroll som en del av CI/CD-pipelinen
- Förbjud att göra commits i skyddade grenar, alla Àndringar görs endast genom MR
- Kontrollera vad vi har uppnÄtt
1. Skapa en token för Ätkomst till API
GĂ„ till AnvĂ€ndarinstĂ€llningar â Ă tkomsttokens och notera token:

Ett konto för att fÄ token
Ă
tkomst till API gör att du kan göra nÀstan vad som helst med dina repositories, sÄ jag rekommenderar att du skapar ett separat GitLab-konto, ger det minimiÄtkomster till dina repositories (till exempel Reporter) och fÄr en token för detta konto.
2. LĂ€gg till token i GitLab-variabler
Till exempel, pÄ det föregÄende steget fick vi token QmN2Y0NOUFlfeXhvd21ZS01aQzgK
Ăppna InstĂ€llningar â CI/CD â Variabler â LĂ€gg till variabel â GITLAB_TOKEN_FOR_CI

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

Detta kan göras antingen pÄ ett enskilt repository eller pÄ en grupp av repositories.
3. SÀtt ett förbud mot Merge om kollegors godkÀnnanden inte fÄr in efter genomfört code review.
I vÄrt fall kommer förbudet mot Merge att vara att byggkonveyorn returnerar ett fel vid otillrÀckligt antal röster.
GĂ„ till InstĂ€llningar â GrundlĂ€ggande â Merge-förfrĂ„gningar â Merge-kontroller och aktivera alternativet Bygglinjer mĂ„ste köras framgĂ„ngsrikt.

4. StÀll in pipelinen
Om du Ànnu inte har skapat en CI/CD konveyor för din applikation
Skapa en fil i roten av repositoryt .gitlab-ci.yml med enklast möjliga innehÄll:
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"
Ett separat repository för CI/CD-konfiguration
Jag skulle rekommendera att skapa ett separat repository dÀr du mÄste skapa en fil myapp.gitlab-ci.yml för att stÀlla in pipelinen. PÄ sÄ sÀtt kan du bÀttre kontrollera Ätkomsten för deltagarna som kan Àndra byggpipen och fÄ Ätkomsttoken.
Platsen för den nya pipelinfilen mĂ„ste anges genom att gĂ„ till repositoryt myapp â InstĂ€llningar â CI/CD â Bygglinjer â AnvĂ€ndarspecifik CI-konfigurationsvĂ€g â ange den nya filen, till exempel myapp.gitlab-ci.yml@gitlab-ce-mr-approvals/Ci
Tips: AnvÀnd en linter för att göra Àndringar i GitLab CI-filer.
Ăven om du arbetar ensam kan det vara en bra hjĂ€lp att arbeta genom MR, och köra alla dina filĂ€ndringar genom en linter. Om du gör ett misstag i YAML-filens syntax kommer det inte att bryta den fungerande pipelinen utan helt enkelt blockera Merge.
Exempel pÄ behÄllare med linters som du kan integrera i din pipeline:
Och ett exempel pÄ en verifieringssteg:
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;
Det ÄterstÄr att lÀgga till nÄgra parametrar i din pipeline sÄ att allt fungerar:
steg:
- test
variables:
NEED_VOTES: 1
include:
- remote: "https://gitlab.com/gitlab-ce-mr-approvals/ci/-/raw/master/check-approve.gitlab-ci.yml"
Variabeln NEED_VOTES definierar hur mÄnga "tumme upp" som mÄste finnas för MR för att Merge ska vara tillgÀngligt. Ett vÀrde av en betyder att du sjÀlv kan godkÀnna din MR genom att "gilla" den.
include kopplar teststeget som kontrollerar antalet "gilla".
Enkel pipeline med exemplet myapp.gitlab-ci.yml
steg:
- bygg
- 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
InnehÄll check-approve.gitlab-ci.yml
ci-mr:
steg: 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} Upp röst = 1, ner röst = -1, MR OK om röster >=${NEED_VOTES_REAL}"
- if [ "${MR_VOTES}" -ge "$(expr ${NEED_VOTES_REAL})" ];
then
echo "MR OK";
else
echo "MR FEL Behöver fler röster";
exit 1;
fi
bild: laptevss/gitlab-api-util
regler:
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ \/^release\/.*$\/'
Mer om vad som hÀnder vid granskning:
- ett villkor har satts sÄ att granskning endast sker vid skapande av MR till brancherna master eller release/*
- anvÀnder GitLab API för att hÀmta antal 'likes' och 'dislikes'
- berÀknar skillnaden mellan positiva och negativa röster
- om skillnaden Àr lÀgre Àn det vÀrde vi angivit i NEED_VOTES, blockeras möjligheten att göra sammanslagningar
5. Förbjuder commits i skyddade brancher
Definierar brancher för vilka vi mÄste genomföra code review och anger att arbete med dem endast Àr möjligt via MR.
För detta besöker vi InstĂ€llningar â Repository â Protected Branches:

6. Kontrollerar
SĂ€tter NEED_VOTES: 0
Gör en MR och sÀtter 'dislike'.

I byggloggarna:

Nu sÀtter vi 'like' och kör en ny kontroll:

KĂ€lla: habr.com
