Boîte à outils pour GitLab CI

Posté par  . Édité par Davy Defaud, palm123, ZeroHeure, Xavier Teyssier, Benoît Sibaud et elionne. Modéré par bubar🦥. Licence CC By‑SA.
Étiquettes :
38
21
jan.
2018
Gestion de versions

Le projet que je vais développer ici est une boîte à outils pour Gitlab CI publié sous licence GNU GPL v3, dont la fonction principale est d’exécuter les tâches GitLab manuellement, individuellement et simplement sur votre station de développement. J’ai commencé son développement début 2017 dans le cadre de ma mission chez ERCOM et, à ce jour, il a atteint un bon stade de maturité. Il est désormais utilisé par deux équipes sur au moins une dizaine de projets.
GitLab (Community Edition) est un logiciel libre, sous licence MIT. Il s’agit d’une forge logicielle équivalente à GitHub et la partie mentionnée, GitLab CI, est une fonctionnalité d’intégration continue équivalente au service Travis CI
logo GitLab

Sommaire

citbx4gitlab : boîte à outils pour GitLab CI

Cette boîte à outils apporte principalement :

  • fonction de base : exécuter les tâches GitLab manuellement et individuellement sur votre station de développement en dehors d’un exécuteur de tâches GitLab (outil gitlab-runner) sans avoir à valider un enregistrement et pousser une branche sur le serveur GitLab ce qui lancera un pipeline complet ;
  • fonction avancée : définir des scripts avancés qui peuvent être exécutés de la même manière sur l’exécuteur GitLab et la station de travail standard.

Le projet

Exemple d’intégration de la boîte à outils dans une arborescence de projet :

├── .gitlab-ci.yml
├── tools
│   └── gitlab-ci
│       ├── 3rdparty
│       │   └── bashopts.sh
│       ├── citbx.properties
│       ├── env-setup
│       │   ├── common.sh
│       │   ├── gentoo.sh
│       │   └── ubuntu.sh
│       ├── modules
│       │   ├── ccache.sh
│       │   ├── dockerimg.sh
│       │   └── example.sh
│       ├── run -> run.sh
│       ├── run.d
│       │   └── job-advanced.sh
│       └── run.sh

Liste des éléments essentiels :

  • .gitlab-ci.yml : définition du pipeline de tâches GitLab ;
  • run.sh: script de lancement de tâche GitLab CI exécuté indirectement via la commande ci-toolbox ;
  • bashopts.sh : dépendance externe nécessaire pour la boîte à outils.

Liste des éléments recommandés :

  • env-setup : dossier contenant les routines d’installation de l’environnement pour faire tourner la boîte à outils ;
  • citbx.properties : propriétés de la boîte à outils propre au projet cible.

Liste des éléments pour une utilisation avancée :

  • run.d : dossier contenant les fonctions spécifiques à certaines tâches ;
  • modules : dossier contenant les modules.

Cas d’utilisation : tâche de pipeline GitLab standard

Le schéma suivant décrit l’exécution d’une tâche standard appelée « J » dans un pipeline Gitlab CI :
Cas d’utilisation global

Dans ce cas, il serait intéressant d’exécuter une tâche spécifique comme J dans son environnement approprié sur votre poste de travail local, sans avoir à valider un enregistrement (git commit) ni avoir à pousser votre dépôt (git push).

Le but est d’avoir exactement le même environnement de construction sur l’exécuteur de tâche GitLab et votre poste de travail local.

Cas d’utilisation d’une tâche unique

Exécuter une tâche spécifique localement

Première solution : utiliser l’outil gitlab-runner

Pour utiliser cette solution, vous devrez :

  • installer l’outil gitlab-runner sur le poste de travail ;
  • et le lancer de la manière suivante : gitlab-runner exec <type d‘exécuteur> <nom de la tâche>.

Vous devrez :

  • valider tous les changements locaux dans des enregistrements Git ;
  • ajouter des options supplémentaires à gitlab-runner du type --docker-image avec le nom de l’image appropriée.

L'autre solution : la commande ci-toolbox

Cette boîte à outils est capable de le faire :

  • démarrer une tâche de type script ou docker avec les paramètres appropriés (image, etc.) ;
  • lancer une tâche du pipeline localement sans avoir à valider un enregistrement (git commit).

Fonctions additionnelles pour une utilisation avancée :

  • ajouter des paramètres et des actions spécifiques au poste de travail ;
  • ajouter la possibilité d’exécuter une invite de commande dans l’environnement Docker approprié ;
  • diviser les différentes tâches du pipeline de façon modulaire.

Utilisation :

  • ci-toolbox <commande> [arguments…], depuis n’importe quel endroit dans l’arborescence du projet ;
  • ou bien : chemin/du/run.sh <commande> [arguments…].

L’outil ci-toolbox est installé dans le système durant la phase de paramétrage path/to/run.sh setup et ajoute les fonctionnalités suivantes :

  • cet outil peut être exécuté n’importe où dans l’arborescence du projet contenant le script run.sh ;
  • cet outil est comme un raccourci pour trouver et exécuter le script run.sh sans avoir à spécifier le chemin absolu ou relatif ;
  • cet outil permet d’ajouter la prise en charge de l’auto‐complétion Bash sur le nom des tâches du pipeline GitLab et des options associées.

Les limites connues de la boîte à outils : elle n’est applicable uniquement que pour les types d’exécuteur de tâche GitLab docker et shell.

Écrire une tâche ou un module en utilisant la boîte à outils

En plus de pouvoir lancer une tâche du pipeline (comme la tâche job-minimal), vous pouvez utiliser la boîte à outils pour écrire les scripts de celle‐ci avec une structure modulaire, comme c’est le cas pour la tâche d’exemple job-advanced.
Ordre d’exécution des types de routines

Écrire une tâche

Les routines spécifiques à la tâche en question doivent être écrites dans un script qui porte le nom de cette dernière dans le dossier : run.d/<nom de la tâche>.sh.

Ce job peut faire appel à différents modules utilisant : citbx_use "<nom du module>".

Le job peut définir les routines suivantes — uniquement applicables à un poste de travail local :

  • job_define() : cette fonction peut être utilisée pour définir des options pour le cas d’utilisation sur un poste de travail ;
  • job_setup() : cette fonction peut être utilisée pour effectuer une action avant de configurer et démarrer l’environnement de la tâche (docker run).

La tâche peut définir les routines suivantes - applicables à tous les environnements :

  • job_main() : la fonction principale de la tâche qui contient la charge utile ;
  • job_after() : cette fonction peut être utilisée pour effectuer une action après l’exécution de la fonction job_main et est appelée dans tous les cas (succès ou erreur) ; elle est appelée avec le code de retour du processus comme premier argument (0 en cas de succès).

Exemple de script de tâche : tools/gitlab-ci/run.d/job-advanced.sh.

Écriture d’un module

Le module doit être défini dans modules/<nom de mon module>.sh.

Ce module peut utiliser d’autres modules à l’aide de citbx_use "<mon autre module>".

Le module peut définir les routines suivantes — uniquement applicables à un poste de travail local :

  • citbx_module_<nom de mon module>_define() : cette fonction peut être utilisée pour définir des options pour le cas d’utilisation sur un poste de travail ;
  • citbx_module_<nom de mon module>_setup() : cette fonction peut être utilisée pour effectuer une action avant de configurer et démarrer l’environnement de la tâche (docker run).

Le job peut définir les routines suivantes — applicables à tous les environnements :

  • citbx_module_<nom de mon module>_before() : cette fonction peut être utilisée pour effectuer une action avant l’exécution du job principal ;
  • citbx_module_<nom de mon module>_after() : cette fonction peut être utilisée pour effectuer une action après l’exécution du job principal et est appelée dans tous les cas (succès ou erreur) ; elle est appelée avec le code de retour du processus comme premier argument (0 en cas de succès).

Exemple de script de module : tools/gitlab-ci/modules/example.sh.

Liste des fonctions utiles

  • citbx_run_ext_job <nom de la tâche> : exécuter une autre tâche ;
  • citbx_job_list [prefix] : obtenir la liste des tâches (en option : avec le préfixe spécifié) ;
  • citbx_use <nom du module> : charger un module ;
  • print_critical <message> : affichage d’un message d’erreur et sortie (code de sortie : 1) ;
  • print_error <message> : affichage un message d’erreur ;
  • print_warning <message> : affichage un message d’avertissement .
  • print_note <message> : affichage un message de note ;
  • print_info <message> : affichage un message d’information.

Exemples de tâches

job-minimal

Exemple de tâche minimaliste.

Définition de la tâche :

image: ubuntu:16.04

job-minimal:
  stage: all-in-one
  script:
    - echo "Bonjour monde !"

after_script:
  - echo "job ${CI_JOB_NAME} end"

Exécution de la tâche :
Tâche minimaliste

job-with-before-after-script

Exemple de définition de tâche avec les propriétés before_script et after_script :

Définition de la tâche :

after_script:
  - echo "job ${CI_JOB_NAME} end"

job-with-before-after-script:
  stage: all-in-one
  before_script:
    - echo "exécuté avant"
  script:
    - echo "script"
      "sur plusieurs"
    - echo "lignes"
    - cat <<< $(echo 'salut !')
  after_script:
    - echo "exécuté après"

job-advanced

Exemple de définition d’un job (fichier tools/gitlab-ci/run.d/job-advanced.sh) avec options, arguments, traitements supplémentaires et utilisation de modules externes (fichier tools/gitlab-ci/modules/example.sh).

Définition de la tâche :

job-advanced:
  image: ubuntu:16.04
  stage: all-in-one
  variables:
    JOBADVAR: "${CI_JOB_NAME} JOBADVAR value"
  script:
    - echo ${GLOBALJOBVAR}
    - echo ${JOBADVAR}
    - tools/gitlab-ci/run.sh

after_script:
  - echo "job ${CI_JOB_NAME} end"

Exécution de la tâche :
Tâche avancée

job-test-services-mysql

Exemple de définition de tâche avec un service MySQL.

Définition de la tâche :

job-test-services-mysql:
  stage: build
  variables:
    MYSQL_DATABASE: test
    MYSQL_ROOT_PASSWORD: password
    CITBX_WAIT_FOR_SERVICE_START: 10
  image: mysql
  services:
    - mysql
  tags:
    - test
  script:
    - mysql -h mysql -u root -ppassword test -e 'SHOW VARIABLES LIKE "%version%";'

job-test-services-postgres

Exemple de définition de tâche avec un service PostgreSQL.

Définition de la tâche :

job-test-services-postgres:
  stage: build
  variables:
    CITBX_WAIT_FOR_SERVICE_START: 10
  image: postgres:9.4
  services:
    - name: postgres:9.4
      alias: db-postgres
      entrypoint: ["docker-entrypoint.sh"]
      command: ["postgres"]
  tags:
    - test
  script:
    - psql -h db-postgres -U postgres -c 'select version();'

Aller plus loin

  • # interessant

    Posté par  . Évalué à 7.

    Ca a l'air très interessant !
    Il est vrai que developper le .gitlab-ci.yml peut parfois être fastidieux, car il faut commiter et pusher pour avoir le résultat..

    Par contre je suis un peu dubitatif sur la forme de l'article. J'aurais bien aimé un petit mot sur le fonctionnement, les prerequis, et peut-être voir un exemple un peu plus concrêt?
    Du coup, le reste de l'article est totalement abscons pour quiconque n'a pas encore mis le nez reelement dans le projet…

    Mais si j'ai bien compris et que ça permet de tester en local son .gitlab-ci.yml avant de réellement l'envoyer dans Gitlab, ça me donne assez envie pour essayer !

    • [^] # Re: interessant

      Posté par  . Évalué à 1.

      • Pour le fonctionnement "interne" je me rapproche le plus possible de celui de gitlab-runner.
      • Pour ce qui est des exemples concrets, j'ai tout un tas d'exemples ici
      • Pour les prérequis il y a juste Linux (où tout autre système supportant docker) avec bash 4 sachant que tout le reste s'installe avec le procédure tools/gitlab-ci/run.sh setup (pour l'instant seuls le setup ubuntu et gentoo sont suppourtés, pour les autres il faudrait ajouter le script de setup dans tools/gitlab-ci/env-setup/<distro>.sh
    • [^] # Re: interessant

      Posté par  . Évalué à 1.

      Finalement ça ne va pas me convenir. Je pense que le script est trop orienté pour ton besoin personnel et pas assez "portable".

      Par exemple, il refait toute l'installation de Docker, il installe des script venant d'autres dépots, installe des certificats (!). De plus, tout est mélangé dans le même programme Bash, ce qui n'est pas très modulaire…

      Finalement, mon besoin est plus simple.

      Pour un job donné:
      - interpreter les variables
      - démarrer les services Docker
      - démarrer l'image Docker avec le mount au bon endroit et des variables d'environments d'un runner (du type CI_*)
      - executer les commandes

      • [^] # Re: interessant

        Posté par  . Évalué à 2.

        Vu la liste des besoins il réponds effectivement à tous ceux que vous citez

        • [^] # Re: interessant

          Posté par  . Évalué à 1.

          Il y a quand-même une chose contraignante qui n'a pas été mentionnée qui est le fait que le script run.sh doit être situé dans le projet et une évolution consisterait à avoir un cas d'utilisation où on utilise de manière totalement externe. Ce sera l'objet de la prochaine évolution.

      • [^] # Re: interessant

        Posté par  . Évalué à 1.

  • # Commentaire supprimé

    Posté par  . Évalué à 0. Dernière modification le 02 février 2018 à 15:12.

    Ce commentaire a été supprimé par l’équipe de modération.

    • [^] # Commentaire supprimé

      Posté par  . Évalué à 3.

      Commentaire supprimé pour spam.

      « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

  • # BPMN - logiciel ? schémas de flux - précision

    Posté par  . Évalué à 1.

    pourrais tu nous dire quelle est le logiciel que tu utilse pour générer tes schémas de flux ou bien est-ce que c'est générer par GitLab CI  ?

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.