Remarque perev. : L'article original a Ă©tĂ© Ă©crit par MiĆosz SmĂłĆka, l'un des fondateurs de la petite entreprise polonaise Three Dots Labs , spĂ©cialisĂ©e dans les «solutions avancĂ©es de backend». L'auteur s'appuie sur son expĂ©rience dans l'utilisation active de GitLab CI et partage les conseils accumulĂ©s pour les autres utilisateurs de ce produit Open Source. AprĂšs les avoir lus, nous avons rĂ©alisĂ© Ă quel point les problĂšmes dĂ©crits par lui Ă©taient proches de nous, nous avons donc dĂ©cidĂ© de partager les solutions proposĂ©es avec un public plus large.
Cette fois, je couvrirai des sujets plus avancĂ©s dans GitLab CI. Une tĂąche courante consiste Ă implĂ©menter des fonctionnalitĂ©s non standard dans le pipeline. La plupart des conseils sont spĂ©cifiques Ă GitLab, bien que certains d'entre eux puissent ĂȘtre appliquĂ©s Ă d'autres systĂšmes CI.
Exécutez des tests d'intégration
En rÚgle générale, la vérification du code à l'aide de
tests unitaires est facile Ă connecter Ă n'importe quel systĂšme CI. Habituellement, cela n'est pas plus compliquĂ© que d'exĂ©cuter l'une des commandes intĂ©grĂ©es Ă l'ensemble standard d'utilitaires dans un langage de programmation. Dans de tels tests, vous ĂȘtes susceptible d'utiliser divers moki et stubs pour masquer les dĂ©tails d'implĂ©mentation et vous concentrer sur le test d'une logique spĂ©cifique. Par exemple, vous pouvez utiliser la base de donnĂ©es en mĂ©moire comme stockage ou Ă©crire des talons pour les clients HTTP qui renverront toujours des rĂ©ponses dĂ©jĂ prĂ©parĂ©es.
Cependant, tĂŽt ou tard, vous aurez besoin de
tests d'intégration pour couvrir des situations plus inhabituelles avec des tests. Je n'entrerai pas dans la discussion sur tous les types de tests possibles et je dirai simplement que par
intégration, je veux dire les tests qui utilisent une sorte de ressources externes. Il peut s'agir d'un véritable serveur de base de données, d'un service HTTP, d'un stockage connecté, etc.
Dans GitLab, il est facile d'exĂ©cuter des ressources enfichables en tant que conteneurs Docker associĂ©s au conteneur dans lequel les scripts s'exĂ©cutent. Ces dĂ©pendances peuvent ĂȘtre dĂ©finies Ă l'aide de
services
. Ils sont disponibles par le nom de l'image ou par le nom de votre choix, si vous le spécifiez dans le champ
alias
.
Voici un exemple simple d'utilisation d'un conteneur enfichable avec MySQL:
integration_tests: stage: tests services: - name: mysql:8 alias: db script: - ./run_tests.sh db:3306
Dans ce cas, dans les scripts de test, vous devrez vous connecter Ă l'hĂŽte
db
. L'utilisation d'un alias est généralement une bonne idée, car elle vous permet de remplacer des images sans avoir à modifier le code de test. Par exemple, vous pouvez remplacer l'image
mysql
par
mariadb
, et le script fonctionnera toujours correctement.
En attente de conteneurs
Ătant donnĂ© que les conteneurs de plug-ins prennent du temps Ă charger, vous devrez peut-ĂȘtre attendre avant d'envoyer des demandes. Un moyen simple est d'
attendre le script
wait-for-it.sh avec un timeout défini.
Utilisation de Docker Compose
Dans la plupart des cas, les
services
devraient ĂȘtre suffisants. Cependant, une interaction avec des services externes peut parfois ĂȘtre nĂ©cessaire. Par exemple, dans le cas du lancement de Kafka et ZooKeeper dans deux conteneurs distincts (c'est ainsi que les images officielles sont collectĂ©es). Un autre exemple est l'exĂ©cution de tests avec un nombre dynamique de nĆuds, tels que Selenium. La meilleure solution pour exĂ©cuter ces services serait
Docker Compose :
version: '3' services: zookeeper: image: confluentinc/cp-zookeeper environment: ZOOKEEPER_CLIENT_PORT: 2181 kafka: image: confluentinc/cp-kafka environment: KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092 ports: - 9092:9092
Si vous utilisez votre installation avec des
exécuteurs GitLab sur des serveurs fiables, vous pouvez exécuter Docker Composer via l'
exécuteur Shell . Une autre option possible est le
dind
Docker in Docker (
dind
). Mais dans ce cas, lisez d'abord
cet article .
Une façon d'utiliser Compose est de configurer votre environnement, d'exécuter des tests, puis de tout détruire. Un simple script bash ressemblerait à ceci:
docker-compose up -d ./run_tests.sh localhost:9092 docker-compose down
Tant que vous exécutez des tests dans un environnement minimal, tout ira bien. Bien qu'une situation puisse survenir dans laquelle vous devez installer certaines dépendances ... Il existe une autre façon d'exécuter des tests dans Docker Compose - elle vous permet de créer votre propre image Docker avec un environnement de test. Dans l'un des conteneurs, vous exécutez des tests et quittez avec le code retour correspondant:
version: '3' services: zookeeper: image: confluentinc/cp-zookeeper environment: ZOOKEEPER_CLIENT_PORT: 2181 kafka: image: confluentinc/cp-kafka environment: KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092 tests: image: registry.example.com/some-image command: ./run_tests.sh kafka:9092
Notez que nous avons éliminé la nécessité de mapper les ports. Dans cet exemple, les tests peuvent interagir directement avec tous les services.
Et leur lancement s'effectue par une seule commande:
docker-compose up --exit-code-from tests
L'
--abort-on-container-exit
--exit-code-from
implique
--abort-on-container-exit
, ce qui signifie: tout l'environnement initié par
docker-compose up
sera arrĂȘtĂ© aprĂšs la fin de l'un des conteneurs. Le code d'achĂšvement de cette commande sera Ă©quivalent au code de sortie du service sĂ©lectionnĂ© (c'est-Ă -dire qu'il s'agit de
tests
dans l'exemple ci-dessus). Si la commande qui démarre les tests se termine avec un code différent de zéro, la commande
docker-compose up
entiĂšre se termine avec elle.
Utilisation d'étiquettes comme balises CI
Attention : c'est une idée plutÎt inhabituelle, mais elle m'a paru trÚs utile et flexible.
Comme vous le savez peut-ĂȘtre, GitLab dispose d'une fonctionnalitĂ© d'Ă©tiquettes disponible au niveau du projet et du groupe. Des Ă©tiquettes peuvent ĂȘtre dĂ©finies sur les tickets et les demandes de fusion. Cependant, ils n'ont aucun lien avec les pipelines.

Un petit raffinement vous permettra d'accéder aux libellés de la demande de fusion dans les scripts de jobs. Dans GitLab 11.6, tout est devenu encore plus facile, car la variable d'environnement
CI_MERGE_REQUEST_IID
est apparue (oui, c'est avec l'
IID
, pas l'
ID
) si le pipeline utilise
only: merge_requests
.
Si
only: merge_requests
pas utilisĂ© ou si vous travaillez avec une ancienne version de GitLab, MR peut toujours ĂȘtre obtenu - en utilisant l'appel API:
curl "$CI_API_V4_URL/projects/$CI_PROJECT_ID/repository/commits/$CI_COMMIT_SHA/merge_requests?private_token=$GITLAB_TOKEN"
Le domaine dont nous avons besoin est
iid
. Cependant, n'oubliez pas que de nombreux MR peuvent revenir pour un commit donné.
Lorsque le MR IID est reçu, il ne reste plus qu'à se tourner vers l'
API Merge Requests et Ă utiliser le champ des
labels
de la réponse:
curl "$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID?private_token=$GITLAB_TOKEN"
Se connecter
Malheureusement, pour le moment,
il n'est pas possible d'utiliser
$CI_JOB_TOKEN
pour accéder à l'API du projet (au moins si le projet n'est pas public). Si le projet a un accÚs limité (interne ou privé), pour l'autorisation dans l'API GitLab, vous devrez générer un jeton d'API personnel.

Cependant, ce n'est pas la solution la plus sûre, alors soyez prudent. Si le jeton tombe entre de mauvaises mains, l'accÚs en écriture à tous vos projets peut apparaßtre avec lui. Une façon de réduire les risques consiste à créer un compte distinct avec le droit de lire le référentiel et de générer un jeton personnel pour ce compte.
Vos variables sont-elles sûres?
Il y a quelques versions, la section
Variables s'appelait
Variables secrÚtes , ce qui semble avoir été créé pour stocker de maniÚre fiable les informations d'identification et autres informations critiques. En fait, les variables sont simplement cachées aux utilisateurs qui ne disposent pas des privilÚges du responsable. Ils ne sont pas chiffrés sur le disque et leur fuite peut facilement se produire via des variables d'environnement dans les scripts.
Gardez cela à l'esprit lorsque vous ajoutez des variables et envisagez de garder des secrets dans des solutions plus sécurisées (par exemple,
Vault de HashiCorp ).
Cas d'utilisation
Que faire des listes d'étiquettes dépend de vous. Voici quelques idées:
- Utilisez-les pour segmenter les tests.
- Utilisez la sémantique des valeurs-clés avec deux points comme séparateur (par exemple, des étiquettes comme
tests:auth
, tests:user
) - Inclure certaines fonctionnalités pour les travaux.
- Autorisez le débogage de travaux spécifiques si l'étiquette existe.
Appel d'API externes
Bien que GitLab soit livrĂ© avec une gamme de fonctionnalitĂ©s dĂ©jĂ disponibles, il est trĂšs probable que vous souhaitiez utiliser d'autres utilitaires pouvant ĂȘtre intĂ©grĂ©s aux pipelines. La façon la plus simple de l'implĂ©menter est, bien sĂ»r, d'appeler la bonne vieille
curl
.
Si vous créez vos propres outils, vous pouvez leur apprendre à écouter les
Webhooks GitLab (voir l'onglet
Intégrations dans les paramÚtres du projet). Cependant, si vous avez l'intention de les utiliser avec des systÚmes critiques, assurez-vous qu'ils répondent aux exigences de haute disponibilité.
Exemple: annotations Grafana
Si vous travaillez avec
Grafana , les
annotations sont un excellent moyen de marquer des Ă©vĂ©nements qui se sont produits au fil du temps sur des graphiques. Ils peuvent ĂȘtre ajoutĂ©s non seulement manuellement en cliquant dans l'interface graphique, mais Ă©galement en appelant l'
API REST Grafana :

Pour accéder à l'API, vous devrez générer une clé API. Envisagez de créer un utilisateur distinct avec un accÚs limité:

Définissez deux variables dans les paramÚtres du projet:
GRAFANA_URL
- URL de l'installation de Grafana (par exemple, https://grafana.example.com
);GRAFANA_APIKEY
- clé générée pour l'API.
Pour pouvoir le réutiliser, placez le script dans le
référentiel avec des scripts communs :
Vous pouvez maintenant ajouter son appel à la configuration CI avec les paramÚtres nécessaires:
deploy: stage: deploy script: - $SCRIPTS_DIR/deploy.sh production - $SCRIPTS_DIR/grafana-annotation.sh "$VERSION deployed to production" deploy-production
Ces appels peuvent ĂȘtre placĂ©s dans le script
deploy.sh
pour simplifier la configuration CI.
Bonus: conseils rapides
GitLab a une
excellente documentation sur tous les mots clĂ©s possibles qui peuvent ĂȘtre utilisĂ©s pour configurer CI. Je ne veux pas dupliquer son contenu ici, mais je soulignerai quelques cas utiles. Cliquez sur les titres pour voir la documentation associĂ©e.
En définissant des modÚles pour les variables CI, vous pouvez définir des assemblages personnalisés pour certaines branches. Cela peut aider, par exemple, à identifier les correctifs push pour les correctifs urgents, mais n'en abusez pas:
only: refs: - branches variables: - $CI_COMMIT_REF_NAME =~ /^hotfix/
GitLab a de nombreuses
variables prédéfinies dans chaque travail CI - utilisez-les.
Utilisez-les pour éviter les doublons.
à partir de la version 11.3, vous pouvez également utiliser le
mot clé extend :
.common_before_script: &common_before_script before_script: - ... - ... deploy: <<: *common_before_script
Par défaut, tous les artefacts collectés dans le pipeline seront transférés vers tous les travaux suivants. Si vous répertoriez explicitement les artefacts dont dépendent les travaux, vous pouvez économiser du temps et de l'espace disque:
dependencies: - build
Ou - au contraire - sautez complĂštement tout si aucun n'est requis:
dependencies: []
Ignorer le clonage du référentiel si le travail n'utilise pas ces fichiers:
variables: GIT_STRATEGY: none
Câest tout!
Merci d'avoir lu! Pour des commentaires et des questions, contactez-moi sur
Twitter ou
Reddit .
Plus de conseils GitLab peuvent ĂȘtre trouvĂ©s dans les articles prĂ©cĂ©dents:
PS du traducteur
Lisez aussi dans notre blog: