Code review in GitLab CE: se non ci sono approvazioni per la Merge request, ma lo si desidera fortemente.

Code review in GitLab CE: se non ci sono approvazioni per la Merge request, ma lo si desidera fortemente.

Una delle funzionalità più necessarie che non è presente nella versione gratuita di GitLab è la possibilità di votare contro la cancellazione del repository, controllando la Merge request (MR) utilizzando una revisione del codice obbligatoria.

Creeremo il minimo necessario da soli: impediremo il Merge finché diversi sviluppatori non daranno il loro consenso sulla MR.

Perché è così importante?

La nostra organizzazione può permettersi di acquistare una licenza GitLab. Tuttavia, poiché lo sviluppo avviene in un ambiente chiuso senza accesso a Internet ed è previsto un rigoroso budget, l'acquisto di licenze self-managed con le funzionalità necessarie potrebbe richiedere mesi, e abbiamo bisogno di lavorare subito.

Di conseguenza, ci troviamo a dover:

  • o vietare completamente il Merge nelle branche protette per alcuni sviluppatori, ma in questo caso gli sviluppatori che hanno il permesso di eseguire il Merge ricevono conflitti quando cercano di unire le MR altrui come un bonus;
  • o consentire fusioni senza controllo con il vostro branch principale senza revisione del codice, anche se si tratta di un Junior assunto solo ieri.

Per prima cosa, ho iniziato a cercare, supponendo che sicuramente qualcuno avesse già creato qualcosa di simile (senza modificare il codice), ma si è scoperto che una simile implementazione non era ancora presente nella versione community.

Schema generale di funzionamento

Prendiamo come esempio l'impostazione delle approvazioni delle Merge request su un repository di test. myapp:

  1. Creeremo un token per accedere all'API GitLab (attraverso il quale raccoglieremo informazioni sul numero di voti "a favore" e "contro").
  2. Aggiungeremo il token nelle variabili di GitLab.
  3. Impediremo il Merge in caso di errori nel pipeline (se i voti "a favore" non sono sufficienti).
  4. Imposteremo il controllo dei voti come parte del pipeline CI/CD.
  5. Impediremo di fare commit nelle branche protette, tutte le modifiche saranno fatte esclusivamente tramite MR.
  6. Verificheremo il risultato finale.

1. Creiamo un token per accedere all'API.

Accediamo a Impostazioni utente → Token di accesso e annotiamo il token:

Code review in GitLab CE: se non ci sono approvazioni per la Merge request, ma lo si desidera fortemente.

Account per ottenere il token.
L'accesso all'API consente di fare praticamente tutto con i vostri repository, quindi consiglio di creare un account GitLab separato, dargli diritti minimi sui vostri repository (ad esempio, Reporter) e ottenere un token per questo account.

2. Aggiungiamo il token nelle variabili di GitLab.

Ad esempio, nel passo precedente abbiamo ottenuto il token. QmN2Y0NOUFlfeXhvd21ZS01aQzgK

Apriamo Impostazioni → CI/CD → Variabili → Aggiungi variabile → GITLAB_TOKEN_FOR_CI

Code review in GitLab CE: se non ci sono approvazioni per la Merge request, ma lo si desidera fortemente.

In conclusione otterremo:

Code review in GitLab CE: se non ci sono approvazioni per la Merge request, ma lo si desidera fortemente.

Questo può essere fatto sia su un singolo repository che su un gruppo di repository.

3. Impediamo il Merge se non si ricevono approvazioni dai colleghi dopo una revisione del codice.

Nel nostro caso, il divieto di Merge sarà quello che il pipeline compilerà un errore in caso di insufficienza di voti.

Accediamo a Impostazioni → Generali → Richieste di fusione → Controlli di fusione e attiviamo l'opzione Le pipeline devono completarsi con successo.

Code review in GitLab CE: se non ci sono approvazioni per la Merge request, ma lo si desidera fortemente.

4. Configuriamo il pipeline.

Se non avete ancora creato un pipeline CI/CD per la vostra applicazione,
creiamo nella radice del repository un file .gitlab-ci.yml con il seguente contenuto:

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"

Un repository separato per la configurazione CI/CD.
Consiglio di creare un repository separato in cui è necessario generare un file myapp.gitlab-ci.yml per configurare il pipeline. In questo modo, potrete meglio controllare l'accesso dei partecipanti che possono modificare il pipeline di compilazione e ottenere un token di accesso.

La posizione del nuovo file del pipeline dovrà essere indicata accedendo al repository myapp — Impostazioni — CI/CD — Pipeline — Percorso di configurazione CI personalizzato — specificare il nuovo file, ad esempio myapp.gitlab-ci.yml@gitlab-ce-mr-approvals/Ci

Consiglio: utilizzate un linter per apportare modifiche ai file GitLab CI.
Anche se lavorate da soli, un buon alleato è prestare attenzione a passare attraverso MR, facendo passare tutte le vostre modifiche ai file del pipeline attraverso il linter. Se commettete un errore di sintassi nel file YAML, questo non romperà il vostro pipeline di lavoro, ma semplicemente bloccherà il Merge.

Ecco esempi di container con linters che potete integrare nel vostro pipeline:

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

E un esempio di fase di verifica:

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;

Ora è rimasto da aggiungere nel vostro pipeline alcuni parametri affinché tutto funzioni:

fasi:
- prova

variables:
NEED_VOTES: 1

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

La variabile NEED_VOTES determina quanti "pollici su" devono essere presenti sulla MR affinché il Merge sia possibile. Un valore di uno significa che potete approvare la vostra stessa MR, "mettendo un like".

L'inclusione aggiunge la fase di test che verifica il numero di "like".

Un pipeline semplice usando myapp.gitlab-ci.yml.
fasi:
- costruire
- prova

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

Contenuto check-approve.gitlab-ci.yml
ci-mr:
stadio: 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} Voto favorevole = 1, voto contrario = -1, MR OK se voti >=${NEED_VOTES_REAL}"
- if [ "${MR_VOTES}" -ge "$(expr ${NEED_VOTES_REAL})" ];
then
echo "MR OK";
else
echo "MR ERROR Necessitano più voti";
exit 1;
fi
immagine: laptevss/gitlab-api-util
regole:
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^release/.*$/'

Ulteriori informazioni su cosa accade durante la verifica:

  • è stata impostata una limitazione che la verifica avverrà solo quando si crea una MR nei rami master o release/*
  • utilizzando l'API di GitLab, otteniamo il numero di "like" e "dislike"
  • calcoliamo la differenza tra i feedback positivi e negativi
  • se la differenza è inferiore al valore da noi definito in NEED_VOTES, blocchiamo la possibilità di fare merge

5. Vietiamo i commit nei rami protetti

Identifichiamo i rami per i quali dobbiamo effettuare la review del codice e indichiamo che si può lavorare solo tramite MR.

Per fare ciò, andiamo su Impostazioni → Repository → Rami protetti:

Code review in GitLab CE: se non ci sono approvazioni per la Merge request, ma lo si desidera fortemente.

6. Verifichiamo

Impostiamo NEED_VOTES: 0

Facciamo MR e mettiamo "dislike".

Code review in GitLab CE: se non ci sono approvazioni per la Merge request, ma lo si desidera fortemente.

Nei log della build:

Code review in GitLab CE: se non ci sono approvazioni per la Merge request, ma lo si desidera fortemente.

Ora mettiamo "like" e avviamo una nuova verifica:

Code review in GitLab CE: se non ci sono approvazioni per la Merge request, ma lo si desidera fortemente.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS 🔥 Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS | ProHoster