Utilisation de GitHub CI pour les projets Elixir

En octobre, Github lancĂ© des actions qui vous permettent d'exĂ©cuter CI sans quitter la caisse dans laquelle ce code est stockĂ©. C'est vraiment trĂšs pratique. DĂšs que quelqu'un envoie une demande de tirage , ou simplement tĂ©lĂ©charge de nouvelles modifications sur le serveur, ou quelque chose de spĂ©cial (une liste des Ă©vĂ©nements auxquels les actions peuvent ĂȘtre attachĂ©es peut ĂȘtre trouvĂ©e dans la documentation officielle ), l'assemblage dĂ©marre. Les tĂąches rĂ©currentes planifiĂ©es ( basĂ©es sur cron ) sont Ă©galement prises en charge.


Vous pouvez créer des pipelines d'action appelés workflows . Et tout cela est beau et ressemble à un brillant avenir - à l'exception de la documentation.


Il m'a fallu plus d'une heure pour comprendre comment créer un conteneur avec des services tiers pour tester l'application. Voici ce que j'ai réussi à découvrir. Veuillez noter que la documentation officielle est franchement maladroite, incomplÚte et souvent simplement erronée.


L' action CI standard utilise des fichiers de configuration avec une syntaxe trĂšs similaire Ă  celle utilisĂ©e par CircleCI . Ce n'est que le bon vieux YAML , qui vous permet de configurer le systĂšme d'exploitation cible, l'environnement, les commandes Ă  exĂ©cuter, etc. Les actions elles-mĂȘmes reçoivent des noms uniques , ce qui vous permet de vous rĂ©fĂ©rer Ă  d'autres actions et de dĂ©pendre d'elles.


De plus, la configuration vous permet de spĂ©cifier des services . Les services doivent ĂȘtre exĂ©cutĂ©s quelque part dans le cloud et GH mappera les ports de conteneur aux ports exposĂ©s par ces services, selon la configuration. Cette partie est mal couverte dans la documentation officielle, et mĂȘme ce qui est dĂ©crit contient des erreurs.


Voici un exemple de configuration de travail pour un projet Elixir qui nécessite des services RabbitMQ et Redis pour tester.


 name: Tests for My Project on: [push, pull_request] jobs: build: runs-on: ubuntu-latest container: image: elixir:1.9.1-slim services: rabbitmq: image: rabbitmq ports: - 5672:5672 env: RABBITMQ_USER: guest RABBITMQ_PASSWORD: guest RABBITMQ_VHOST: "/" redis: image: redis ports: - 6379:6379 steps: - uses: actions/checkout@v1 - name: Install Dependencies run: | MIX_ENV=ci mix local.rebar --force MIX_ENV=ci mix local.hex --force MIX_ENV=ci mix deps.get - name: Run All Tests run: | MIX_ENV=ci mix test env: RABBITMQ_HOST: rabbitmq RABBITMQ_PORT: ${{ job.services.rabbitmq.ports[5672] }} REDIS_HOST: redis REDIS_PORT: ${{ job.services.redis.ports[6379] }} 

Comme vous pouvez le voir, les tests s'exécuteront sur Ubuntu en utilisant Elixir v1.9.1. Les services sont décrits sous les services clés et commence ici une pure histoire de détective. Le port physique auquel le port de service sera lié est sélectionné au hasard par le moteur de conteneur au moment de l'exécution et stocké dans une variable de shell interne nommée job.services.rabbitmq.ports[5672] . rabbitmq est le nom du service, comme indiqué dans ce fichier dans la section services , et 5672 est le port source. La variable interne a la syntaxe $ {{foo}} et est passée à la variable d'environnement RABBITMQ_PORT (le dernier bloc de paramétrage, sous la clé env ). Dans RABBITMQ_HOST - vous devez mettre le nom du service, tout comme sous la clé des services . Maintenant, l'application peut lire les variables d'environnement comme d'habitude et les ports défileront correctement.


C'est ainsi que nous lirons ces variables d'environnement Ă  partir de l'environnement (c'est une configuration pour Elixir , pour d'autres langages il y aura quelque chose de trĂšs similaire).


 import Config config :my_app, rabbitmq: [ host: System.get_env("RABBITMQ_HOST"), password: "guest", port: String.to_integer(System.get_env("RABBITMQ_PORT", "5672")), username: "guest", virtual_host: "/", x_message_ttl: "4000" ] 

Dans le fichier projet, je crĂ©e un environnement spĂ©cial :ci , pour distinguer la configuration des tests qui s'exĂ©cutent dans l'environnement local et des mĂȘmes tests qui s'exĂ©cutent quelque part dans le cloud.


De plus, dans le pipeline CI , dialyzer le dialyzer sur mes sources. Puisqu'elle s'exécute dans le conteneur, la tùche prend un certain temps, car vous devez à chaque fois reconstruire les plts partir de zéro. C'est pourquoi je le fais une fois par jour en utilisant l'option de configuration de schedule .


 name: Dialyzer for My Project on: schedule: - cron: "0 1 * * *" jobs: build: runs-on: ubuntu-latest container: image: elixir:1.9.1-slim steps: - uses: actions/checkout@v1 - name: Install Dependencies run: | MIX_ENV=ci mix local.rebar --force MIX_ENV=ci mix local.hex --force MIX_ENV=ci mix deps.get - name: Run All Tests run: | MIX_ENV=ci mix code_quality 

ici code_quality est un alias de tùche déclaré dans mix.exs


 defp aliases do [ code_quality: ["format", "credo --strict", "dialyzer"] ] end 

Ici, en général, c'est tout ce dont nous avons besoin pour tester de maniÚre satisfaisante un projet avec des dépendances externes dans le nouveau flux de travail Github .


Intégration continue réussie!

Source: https://habr.com/ru/post/fr481846/


All Articles