Exécutez vos tests depuis CI/CD
L'écran CI/CD du Studio génère le fichier de pipeline pour GitHub Actions ou GitLab CI. Ce guide explique ce que ce fichier exécute, les trois emplacements où le job peut s'exécuter, les secrets, le XML JUnit et les preuves qu'il produit, ainsi que les erreurs rencontrées par une machine CI.
Le fichier de pipeline
Sur l'écran CI/CD, sélectionnez GitHub Actions ou GitLab CI, les navigateurs, les vérifications et l'emplacement d'exécution du job, puis générez. Le Studio valide le fichier localement en premier, et peut le committer et le pousser depuis le même écran. Depuis un terminal, nexus init --ci github ou nexus init --ci gitlab génère le même fichier.
| Partie | GitHub Actions | GitLab CI |
|---|---|---|
| Fichier | .github/workflows/nexus-ci.yml | .gitlab-ci.yml |
| Déclencheurs | Les pull requests, les pushs vers main ou master, et une exécution manuelle (workflow_dispatch) avec une entrée tc_ids. Avec la régression nocturne activée, un cron schedule en UTC, par défaut 0 6 * * *. | Les règles de pipeline de votre projet. Le fichier ne contient pas de planification : pour une exécution nocturne, ajoutez un Pipeline Schedule dans GitLab. |
| Runner | runs-on: ubuntu-latest pour un runner hébergé dans le cloud, runs-on: [self-hosted] pour le vôtre | L'image mcr.microsoft.com/playwright:v1.62.1-noble ; tags: [self-hosted] pour votre propre runner |
| Étapes | actions/checkout@v4 ; actions/setup-node@v4 avec Node.js 22, sauf sur la cible Docker ; npm ci ; npx playwright install --with-deps ; node bin/nexus.js ci --all, ou les identifiants de tests que vous avez sélectionnés | npm ci ; node bin/nexus.js ci avec la variable TC_IDS, ou --all. L'image contient déjà les navigateurs. |
| Artefacts | actions/upload-artifact@v4, if: always(), nom nexus-evidence, chemin evidence/ | artifacts: when: always, reports: junit: evidence/ci/junit.xml, paths: evidence/ |
Avec plusieurs navigateurs, GitHub exécute un job par navigateur, avec fail-fast: false, et chacun ajoute --project=<browser>. Les vérifications que vous sélectionnez ajoutent --visual, --a11y, --chaos=, --loop= ou --no-retry.
Codes de sortie et JUnit XML
nexus ci exécute les tests que vous nommez (TC1,TC2) ou --all, et se termine avec le code 0 en cas de succès, 1 en cas d'échec et 2 lorsqu'aucun test n'a été exécuté ou si la commande est incorrecte. Il écrit le XML JUnit dans evidence/ci/junit.xml ; --junit=<path> permet de l'écrire ailleurs.
Emplacement d'exécution du job : trois options
Chaque option nécessite une machine disposant d'une activation : le moteur n'exécute pas de suites sur une machine qui n'en possède pas, et chaque machine activée est comptabilisée dans votre abonnement (abonnements et machines). Un runner hébergé dans le cloud, runs-on: ubuntu-latest, démarre une nouvelle machine virtuelle pour chaque job et n'en conserve donc jamais aucune ; utilisez un runner persistant qui vous appartient.
Option A : un runner auto-hébergé sur la machine du Studio
- Sur le PC Windows 11 ou le mini PC où Nexus Studio est installé et activé, enregistrez un runner : sur GitHub, dans les Paramètres du dépôt, sous Actions, Runners, Nouveau runner auto-hébergé ; sur GitLab, dans Paramètres, CI/CD, Runners.
- Sur l'écran CI/CD, choisissez Ma machine. Le fichier contient alors
runs-on: [self-hosted]sur GitHub outags: [self-hosted]sur GitLab. - Exécutez le runner en tant qu'utilisateur Windows ayant activé le Studio. Le moteur lit l'activation depuis le profil de cet utilisateur, dans
.sentinel-studio\license.json; un service de runner fonctionnant sous un autre compte n'en trouvera aucune.
Le job utilise l'activation de cette machine : une activation par machine, déjà comptabilisée dans votre abonnement, et aucune clé dans le pipeline. N'utilisez un runner auto-hébergé qu'avec un dépôt privé, comme le Studio vous en avertit : sur un dépôt public, toute personne ouvrant une pull request peut exécuter du code sur votre machine.
Option B : un runner sur un VPS, dans un conteneur
Un VPS sous Ubuntu 24.04 LTS x86_64, avec Docker Engine et Compose v2, accessible par authentification par clé SSH. Il est comptabilisé comme une machine de votre abonnement.
- Sur l'écran CI/CD, choisissez My machine + Docker. En plus du fichier de pipeline, le Studio écrit
docker-compose.sentinel-runner.yml,Dockerfile.runneret les deux scripts d'entrée du runner dans l'espace de travail.Dockerfile.runnerpart demcr.microsoft.com/playwright:v1.62.1-noble. - L'écran affiche les commandes à coller dans une session SSH sur le VPS, et non dans le terminal du Studio. Pour GitHub, il récupère un jeton d'enregistrement, valable 1 heure, et définit
REPO_URL,RUNNER_TOKENetRUNNER_NAME; pour GitLab,GITLAB_URLetGITLAB_RUNNER_TOKEN. Ensuite :
docker compose -f docker-compose.sentinel-runner.yml up -d --build sentinel-runner
docker compose -f docker-compose.sentinel-runner.yml up -d sentinel-runner-gitlab
La première ligne est pour GitHub, la seconde pour GitLab. Dans un conteneur Linux, la licence identifie la machine par /etc/machine-id : montez celui de l'hôte en lecture seule, /etc/machine-id:/etc/machine-id:ro, et conservez le dossier .sentinel-studio du répertoire personnel du runner sur un volume, afin que l'activation survive à une reconstruction. Activez une seule fois, manuellement, avec nexus license activate et votre clé, jamais depuis le fichier de pipeline.
Aujourd'hui, l'image du runner est construite sur le VPS à partir de Dockerfile.runner. Le dépôt ne dispose pas encore de registre de conteneurs : une image publiée sur GitHub Container Registry, celle qu'utilise le runtime VPS du Studio, sera livrée avec la prochaine version.
Option C : le job CI démarre une exécution sur un hôte via SSH
Le job reste léger, sur n'importe quel runner, et les suites s'exécutent sur un hôte qui vous appartient, avec l'espace de travail et le moteur à un chemin défini, tel que le runtime SSH du Studio l'attend. L'écran CI/CD ne génère pas ce job ; voici les options qu'utilise le runtime SSH du Studio :
ssh -o BatchMode=yes -o StrictHostKeyChecking=yes -o ConnectTimeout=8 <user>@<host> "cd <path> && node bin/nexus.js ci --all"
scp -r -o BatchMode=yes -o StrictHostKeyChecking=yes <user>@<host>:<path>/evidence ./evidence
- Authentification par clé uniquement.
BatchMode=yesne demande jamais de mot de passe. Écrivez la clé privée depuis un secret CI dans un fichier accessible uniquement par le job, et supprimez-la à la fin du job. StrictHostKeyChecking=yes. La clé de l'hôte doit déjà être présente dans le fichierknown_hostsdu runner : conservez la ligne de clé publique de l'hôte dans une variable CI et écrivez-la avant le premier appel àssh. Ne la définissez jamais àno.- Le code de sortie est retourné.
sshse termine avec le code de la commande distante, de sorte que l'étape échoue lorsque la suite échoue, etscprapatrie les éléments de preuve, y compris le XML JUnit, pour l'étape d'artefact. - L'hôte vérifie sa propre licence et compte comme une seule machine de votre abonnement.
Secrets
- Stockez les jetons, les URL de webhook et les clés privées SSH en tant que secrets CI : sur GitHub dans Settings, Secrets and variables, Actions, ou avec
gh secret set <KEY>; sur GitLab en tant que variables masquées dans Settings, CI/CD, Variables. Jamais dans le dépôt, le fichier de pipeline ou un journal. - Le workflow GitHub généré ne lit que les clés d'intégration, depuis
secrets.<KEY>, et uniquement lors des étapes Nexus :TELEGRAM_*,SLACK_ENABLED,SLACK_WEBHOOK_URL,JIRA_*et les interrupteurs de notification. L'écran CI/CD liste une commandegh secret setpour chacune ;ghdemande la valeur, et rien n'est affiché. - La clé de licence n'a pas sa place dans le CI. Activez un runner persistant une seule fois, manuellement : la clé est envoyée une fois et n'est pas conservée. Si votre processus exige néanmoins la clé dans le système CI, stockez-la uniquement en tant que secret masqué ; rien dans le pipeline généré ne la lit.
- N'affichez jamais un secret dans une étape. Le moteur expurge les secrets du texte qu'il consigne comme preuve, tel que les messages d'échec JUnit et les journaux ; il n'expurge pas la sortie console propre au job, et le service CI masque uniquement les valeurs stockées en tant que secrets.
JUnit XML et preuves en tant qu'artefacts
- GitHub téléverse
evidence/en tant quenexus-evidence, unnexus-evidence-<browser>par navigateur avec une matrice, que l'exécution ait réussi ou échoué. Le JUnit XML se trouve à l'intérieur, àevidence/ci/junit.xml. - GitLab conserve
evidence/et signaleevidence/ci/junit.xmlen tant que rapport JUnit, de sorte que les tests échoués apparaissent dans la merge request. - Depuis Studio, l'écran CI/CD peut démarrer une exécution de workflow GitHub et télécharger ses preuves dans
evidence/ci-remote/run-<id>dans l'espace de travail. - Où réside la copie. Un artefact est une copie des preuves, captures d'écran et journaux inclus, sur le stockage de votre service CI ; sur un service hébergé, il s'agit du matériel d'un tiers. Définissez la rétention des artefacts selon ce que votre politique autorise, ou conservez les preuves sur votre runner et téléversez uniquement
evidence/ci/junit.xml.
Dépannage
SEAT_LIMIT sur un runner hébergé dans le cloud ou éphémère
Chaque nouvelle machine virtuelle est une nouvelle machine pour la licence, de sorte qu'un runner éphémère nécessiterait une activation à chaque tâche. Une fois que toutes les machines de votre abonnement sont actives, l'activation est refusée avec SEAT_LIMIT : « Toutes les machines de votre abonnement sont utilisées. Désactivez-en une dans votre compte. » Utilisez un runner auto-hébergé persistant (option A ou B), et désactivez les machines que vous n'utilisez plus sous License & machines dans votre compte (plus d'informations sur SEAT_LIMIT).
Le runner était hors ligne depuis plusieurs jours
La licence d'une machine doit être validée au moins tous les 7 jours. Passé ce délai, elle bénéficie de 4 jours supplémentaires avec un avertissement, puis passe en lecture seule : les suites ne s'exécutent plus jusqu'à ce qu'une vérification réussisse, et les preuves restent lisibles. Sur un runner de nouveau en ligne, nexus license renew effectue une nouvelle vérification (utilisation hors ligne).
« no /etc/machine-id » dans un conteneur
Le conteneur ne dispose d'aucun identifiant de machine que la licence puisse lire. Montez celui de l'hôte : -v /etc/machine-id:/etc/machine-id:ro, ou la même ligne sous volumes: dans le fichier compose.
La tâche se termine avec le code 2
Rien ne s'est exécuté : aucun test ne correspond aux identifiants, ou la commande était incorrecte. Vérifiez les identifiants transmis à nexus ci, dans tc_ids sur GitHub ou TC_IDS sur GitLab.
Échec de la vérification de la clé hôte
StrictHostKeyChecking=yes a refusé un hôte absent de known_hosts ou dont la clé a changé. Ajoutez la clé de l'hôte depuis une source de confiance, après avoir vérifié son empreinte directement sur l'hôte. Ne désactivez pas cette vérification.