Revisión de código en Gitlab CE: si no hay aprobaciones de solicitud de fusión, pero realmente quiero

Revisión de código en Gitlab CE: si no hay aprobaciones de solicitud de fusión, pero realmente quiero

Una de las características más necesarias que no está en la versión gratuita de GitLab es la capacidad de votar en contra de poner a cero el repositorio para controlar la solicitud de fusión (MR) mediante la revisión de código obligatoria.

Haremos la funcionalidad mínima nosotros mismos: desactivaremos Merge hasta que varios desarrolladores den un "pulgar hacia arriba" a MR.

¿Por qué es esto en absoluto?

Nuestra organización puede permitirse comprar una licencia de GitLab. Pero, dado que el desarrollo se lleva a cabo en un ciclo cerrado sin acceso a Internet y existe una planificación presupuestaria estricta, la compra de licencias autogestionadas con la funcionalidad necesaria puede llevar muchos meses y debe trabajar ahora.

Como resultado, usted tiene que:

  • o prohibir completamente Fusionar en ramas protegidas para algunos desarrolladores, pero luego los desarrolladores que tienen derecho a Fusionar reciben conflictos cuando fusionan los MR de otras personas como bonificación;
  • o permitirle realizar fusiones no controladas con su rama principal sin revisar el código, incluso si se trata de un Junior que acaba de instalarse ayer.

Lo primero que hice fue buscar en Google, creyendo que alguien ya había hecho algo similar (sin refinar el código), pero resultó que aún no existía tal implementación en la versión comunitaria.

esquema general de trabajo

Como ejemplo, configuremos las aprobaciones de solicitud de fusión en un repositorio de prueba miaplicacion:

  1. Creemos un token para acceder a la API de GitLab (a través de él recibiremos información sobre la cantidad de votos a favor y en contra)
  2. Agregar un token a las variables de GitLab
  3. Deshabilite Fusionar si hay errores en la canalización (si no hay suficientes votos "a favor")
  4. Configurar la validación de votos como parte de la canalización de CI/CD
  5. Prohibiremos hacer commits a ramas protegidas, hacemos todos los cambios solo a través de MR
  6. Veamos qué pasó al final.

1. Crea un token para acceder a la API

Vaya a Configuración de usuario → Tokens de acceso y anote el token:

Revisión de código en Gitlab CE: si no hay aprobaciones de solicitud de fusión, pero realmente quiero

Cuenta para recibir el token
El acceso a la API le permite hacer casi cualquier cosa con sus repositorios, por lo que le sugiero que cree una cuenta de Gitlab separada, le otorgue derechos mínimos a sus repositorios (como Reporter) y obtenga un token para esa cuenta.

2. Agregue el token a las variables de Gitlab

Por ejemplo, en el paso anterior, recibimos un token QmN2Y0NOUFlfeXhvd21ZS01aQzgK

Abra Configuración → CI/CD → Variables → Agregar variable → GITLAB_TOKEN_FOR_CI

Revisión de código en Gitlab CE: si no hay aprobaciones de solicitud de fusión, pero realmente quiero

Como resultado, obtenemos:

Revisión de código en Gitlab CE: si no hay aprobaciones de solicitud de fusión, pero realmente quiero

Esto se puede hacer tanto en un repositorio como en un grupo de repositorios.

3. Prohibimos fusionar si no se recibe la aprobación de los colegas después de la revisión del código

En nuestro caso, la prohibición de Merge será que la tubería de ensamblaje devuelva un error si no hay suficientes votos.

Vaya a Configuración → General → Solicitudes de fusión → Comprobaciones de fusión y habilite la opción Las líneas de ensamblaje deben ejecutarse correctamente.

Revisión de código en Gitlab CE: si no hay aprobaciones de solicitud de fusión, pero realmente quiero

4. Configurar la canalización

Si aún no ha creado una canalización de CI/CD para su aplicación
Crear un archivo en la raíz del repositorio. .gitlab-ci.yml con contenido sencillo:

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"

Repositorio separado para la configuración de CI/CD
Recomendaría crear un repositorio separado donde necesite crear un archivo myapp.gitlab-ci.yml para configurar la canalización. De esta manera, puede controlar mejor el acceso de los colaboradores que pueden cambiar la canalización de compilación y obtener un token de acceso.

La ubicación del nuevo archivo de canalización deberá especificarse yendo al repositorio myapp - Configuración - CI / CD - Líneas de ensamblaje - Ruta de configuración de CI personalizada - especifique un nuevo archivo, por ejemplo myapp.gitlab-ci.yml@gitlab-ce-mr-approvals/Ci

Sugerencia: use un linter para realizar cambios en los archivos GitLab CI
Incluso si trabaja solo, trabajar a través de MR será una buena ayuda, ya que ejecutará todos los cambios en los archivos de canalización a través del linter. Si comete un error en la sintaxis del archivo YAML, esto no le permitirá romper la tubería de trabajo, sino que simplemente bloqueará Merge.

Un ejemplo de contenedores con linters que puede incrustar en su canalización:

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

Y un ejemplo de la etapa de validación:

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;

Queda por agregar algunos parámetros a su tubería para que funcione:

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 determina cuántos "pulgares hacia arriba" debe tener MR para que Merge esté disponible. Un valor de uno significa que usted mismo puede aprobar su MR haciendo clic en "Me gusta".

include incluye la etapa de prueba, que verifica la cantidad de "me gusta".

La tubería más simple usando myapp.gitlab-ci.yml como ejemplo
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

Contenido 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/.*$/'

Obtenga más información sobre lo que sucede al verificar:

  • se establece la restricción de que la verificación será solo al crear un MR en las ramas master o release /*
  • utilizando la API de GitLab, obtenga el número de "me gusta" y "no me gusta"
  • calcular la diferencia entre respuestas positivas y negativas
  • si la diferencia es menor que el valor que establecemos en NECESIDAD_VOTOS, entonces bloqueamos la capacidad de fusionar

5. Deshabilitar compromisos con ramas protegidas

Determinamos las ramas para las que debemos realizar revisión de código e indicamos que solo se pueden trabajar a través de MR.

Para hacer esto, vaya a Configuración → Repositorio → Ramas protegidas:

Revisión de código en Gitlab CE: si no hay aprobaciones de solicitud de fusión, pero realmente quiero

6. Comprobación

Establecer NECESIDAD_VOTOS: 0

Hacemos MR y ponemos un "no me gusta".

Revisión de código en Gitlab CE: si no hay aprobaciones de solicitud de fusión, pero realmente quiero

En los registros de compilación:

Revisión de código en Gitlab CE: si no hay aprobaciones de solicitud de fusión, pero realmente quiero

Ahora pon "me gusta" y ejecuta una nueva verificación:

Revisión de código en Gitlab CE: si no hay aprobaciones de solicitud de fusión, pero realmente quiero

Fuente: habr.com

Añadir un comentario