Mettre en place l'intégration continue (CI) pour ton parcours est très important, car cela aide à repérer les erreurs.
Les dépôts Exercism (y compris les dépôts de parcours) utilisent GitHub Actions pour exécuter leur CI. GitHub Actions repose sur des workflows, qui définissent des scripts à exécuter automatiquement dès qu'un événement précis se produit (par exemple lorsqu'un commit est poussé). Pour plus d'informations sur les workflows GitHub Actions, consulte la documentation sur les workflows.
Les parcours sont livrés avec un certain nombre de workflows préinstallés, dont la plupart ne doivent pas être modifiés (qu'on appelle les workflows partagés).
Il y a toutefois un workflow que tu dois modifier : le workflow test.yml.
Le but du workflow test.yml est de vérifier que les exercices du parcours sont en bon état.
Le workflow est configuré pour s'exécuter automatiquement (dans la terminologie de GitHub Actions : il est déclenché) lors d'un push vers la branche main ou vers la branche d'une pull request.
Le workflow lui-même ne doit pas faire grand-chose, à part :
Comme mentionné, les exercices sont vérifiés par un script, à savoir le script bin/verify-exercises (bash).
Ce script est presque terminé, et fait ce qui suit :
unskip_tests, dans laquelle tu peux réactiver les tests ignorés dans tes fichiers de test (facultatif)run_tests, dans laquelle tu dois exécuter les tests (obligatoire)Les fonctions run_tests et unskip_tests sont les seules choses que tu dois implémenter.
Si ton parcours permet d'ignorer des tests, on doit s'assurer qu'aucun test n'est ignoré lors de la vérification de la solution d'exemple (exemplar) d'un exercice. En général, il existe deux façons pour un parcours de gérer la réactivation des tests :
test.skip par test.SKIP_TESTS=false.Si l'ignorance des tests se fait au niveau des fichiers (la première option mentionnée ci-dessus), modifie la fonction unskip_tests pour modifier les fichiers de test (le code existant gère déjà le parcours des fichiers de test).
La fonction unskip_test s'exécute sur une copie du répertoire d'un exercice, donc n'hésite pas à modifier les fichiers comme bon te semble.
Le fichier bin/verify-exercises du parcours Arturo utilise sed pour réactiver les tests dans les fichiers de test :
unskip_tests() {
jq -r '.files.test[]' .meta/config.json | while read -r test_file; do
sed -i 's/test.skip/test/g' "${test_file}"
done
}
Si la réactivation des tests nécessite qu'une variable d'environnement soit définie, assure-toi qu'elle est bien définie dans la fonction run_tests.
La fonction run_tests est chargée d'exécuter les tests d'un exercice.
Quand la fonction est appelée, les fichiers d'exemple (exemplar) ont déjà été copiés dans les fichiers de solution (stub), donc tu n'as plus qu'à appeler la bonne commande pour exécuter les tests.
La fonction doit renvoyer zéro comme code de sortie si tous les tests réussissent, sinon elle doit renvoyer un code de sortie différent de zéro.
La fonction run_tests s'exécute sur une copie du répertoire d'un exercice, donc n'hésite pas à modifier les fichiers comme bon te semble.
L'option par défaut pour le script de vérification des exercices est d'utiliser l'outillage du langage (SDK, binaire, etc.), ce que font la plupart des parcours. Chaque parcours a sa propre façon d'exécuter les tests, mais il s'agit généralement d'une seule commande.
Le fichier bin/verify-exercises du parcours Arturo modifie la fonction run_tests pour simplement appeler la commande arturo sur le fichier de test :
run_tests() {
arturo tester.art
}
La deuxième option consiste à vérifier les exercices en exécutant l'exécuteur de tests du parcours. Cela dépend bien sûr du fait que le parcours dispose d'un exécuteur de tests fonctionnel.
Si ton parcours n'a pas encore d'exécuteur de tests, tu peux soit :
Les modifications suivantes doivent être apportées au script bin/verify-exercises file par défaut :
docker est disponibledocker run pour exécuter l'image Docker de l'exécuteur de tests sur chaque exercicejq pour vérifier que le fichier results.json renvoyé par le conteneur Docker indique que tous les tests ont réussiunskip_test et l'appel à cette fonctionLe principal avantage de cette approche est qu'elle reproduit au mieux la façon dont les tests sont exécutés en production (sur le site web). Avec cette approche, il est moins probable que des choses qui passaient en CI échouent en production. L'inconvénient de cette approche est qu'elle est généralement plus lente, à cause du téléchargement de l'image Docker et de la surcharge qu'implique Docker.
Le fichier bin/verify-exercises file du parcours Unison ajoute la vérification que la commande docker est bien installée :
required_tool docker
Ensuite, il récupère l'image de l'exécuteur de tests du parcours :
docker pull exercism/unison-test-runner
Il modifie ensuite la fonction run_tests pour utiliser docker run afin d'exécuter l'exécuteur de tests sur l'exercice courant (qui se trouve dans le répertoire de travail), suivi d'une commande jq pour vérifier que le statut est le bon :
run_tests() {
local slug
slug="${1}"
docker run \
--rm \
--network none \
--mount type=bind,src="${PWD}",dst=/solution \
--mount type=bind,src="${PWD}",dst=/output \
--tmpfs /tmp:rw \
exercism/unison-test-runner "${slug}" "/solution" "/output"
jq -e '.status == "pass"' "${PWD}/results.json" >/dev/null 2>&1
}
Enfin, on doit modifier l'appel à la commande run_tests, car elle nécessite désormais le slug :
run_tests "${slug}"
Maintenant que le script verify-exercises est terminé, il est temps de finaliser le workflow test.yml.
La façon de procéder dépend de l'option choisie pour l'implémentation du script verify-exercises.
Si le script verify-exercises utilise directement l'outillage du langage, le workflow de test devra installer :
Une fois cela fait, verify-exercises devrait fonctionner comme prévu, et tu as mis en place ta CI avec succès !
Pour un exemple, consulte le workflow test.yml du parcours Arturo :
name: Test
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
jobs:
ci:
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install libgtk-3-dev libwebkit2gtk-4.0-dev libmpfr-dev
- name: Install Arturo
run: bin/install-arturo
env:
GH_TOKEN: ${{ github.token }}
- name: Verify all exercises
run: bin/verify-exercises
La deuxième option consiste à vérifier les exercices en exécutant l'exécuteur de tests du parcours. Cette option nécessite que deux conditions soient remplies :
verify-exercises utilise l'image Docker de l'exécuteur de tests pour exécuter les tests d'un exerciceSi ton parcours n'a pas encore d'exécuteur de tests, tu peux soit :
Cette approche présente quelques avantages :
Le principal inconvénient est qu'elle est probablement plus lente, à cause du téléchargement de l'image Docker et de la surcharge qu'implique Docker.
Il existe plusieurs façons de récupérer l'image Docker de l'exécuteur de tests :
verify-exercises.
C'est l'approche adoptée par le parcours Unison.Alors, quelle approche choisir ?
On recommande au moins d'implémenter l'option 1, pour que le script verify-exercises soit autonome.
Si ton image est particulièrement volumineuse, il peut être utile d'implémenter aussi l'option 3, qui stockera l'image Docker construite dans le cache de GitHub Actions.
Les exécutions suivantes pourront alors simplement lire l'image Docker depuis le cache, au lieu de la télécharger, ce qui peut être meilleur pour les performances (à mesurer pour en être sûr).
Une troisième option, alternative, est un hybride des deux précédentes.
Ici, on utilise aussi l'image Docker de l'exécuteur de tests, sauf que cette fois on exécute le script verify-exercises à l'intérieur de cette image Docker.
Pour activer cette option, on doit définir le conteneur du workflow sur l'exécuteur de tests :
container:
image: exercism/vimscript-test-runner
On peut alors sauter les étapes d'installation des dépendances et de l'outillage (puisqu'elles auront été effectuées dans l'image Docker de l'exécuteur de tests) et passer à l'exécution du script bin/verify-exercises file.
Le workflow test.yml du parcours vimscript utilise cette option :
name: Verify Exercises
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
jobs:
ci:
runs-on: ubuntu-24.04
container:
image: exercism/vimscript-test-runner
steps:
- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
- name: Verify all exercises
run: bin/verify-exercises