Les environnements auto-hébergés sont en bêta publique sur les plans Team et Enterprise ; Disponibilité et limitations couvre le chemin d’activation. Cette page est la recette de test CI ; consultez le guide de démarrage rapide pour la configuration et Déployer en production pour les recettes de flotte.
Installer le hook de capture sur votre runner de test
La relecture fonctionne via un hook Stop de Claude Code : quand Claude termine un tour, le hook reçoit le message assistant final en tant quelast_assistant_message dans son JSON stdin et l’ajoute à $E2E_REPLY_DIR/<session_id>.txt. Installez-le de la même manière que le hook Stop commit-nudge, sur le ~/.claude/ de l’hôte du runner, que le runner amorce dans chaque session.
Enregistrer les fichiers du hook
Enregistrez les deux fichiers ci-dessous sur l’hôte du runner :- Le bloc de paramètres : fusionnez dans
~/.claude/settings.jsonsur l’hôte du runner - Le script : enregistrez comme
~/.claude/hooks/e2e-stop-hook-capture.shsur l’hôte du runner et rendez-le exécutable
Avant de démarrer le runner
Deux choses sur lesquelles le hook dépend :- Installez-le avant de démarrer le runner. Le runner prend un instantané de
~/.claude/une fois au démarrage, donc un hook ajouté à un runner en cours d’exécution ne prend effet qu’après un redémarrage. - Exportez
E2E_REPLY_DIRau processus du runner. Le hook est un no-op quand la variable n’est pas définie ou que le répertoire n’existe pas, donc définissez-la partout où vous démarrez le runner, comme l’unité systemd, la spécification du pod, ou l’étape CI. Le script de test ci-dessous le nécessite aussi.
E2E_REPLY_DIR existe, ce qui est inoffensif sur un runner CI jetable mais pas quelque chose à porter dans une image de runner d’environnement de production où la variable pourrait être définie accidentellement.
Exécuter la boucle de test
Les drapeaux de dispatch--environment et --ref nécessitent Claude Code v2.1.224 ou ultérieur sur la machine qui exécute le script, le même plancher que le runner lui-même. Avec le hook en place et un runner démarré sur cet hôte, le script de test :
- Crée une session sur l’environnement de test avec
claude -p "<prompt>" --environment <environment-id> --output-format json, exécuté à partir d’une extraction git pour que la CLI puisse détecter automatiquement le référentiel à partir de la télécommandeorigin. Le--ref <branch>optionnel base l’extraction de la session sur une ref nommée au lieu du HEAD local. La commande crée la session, imprime une ligne de JSON contenantsession_id, et se termine sans attendre la réponse de Claude. - Attend que la réponse apparaisse dans
$E2E_REPLY_DIR/<session_id>.txt, écrite par le hook Stop sur le runner une fois le tour terminé. - Envoie un suivi avec
claude -p "<message>" --cloud <session_id> --output-format json(voir Envoyer un message de suivi à une session en cours d’exécution), qui publie un événement utilisateur à la session existante et se termine. - Attend la réponse du suivi de la même manière qu’à l’étape 2.
Comportement du dispatch --environment
Claude Code crée la session, imprime l’ID de session et un lien vers celle-ci, et se termine.
Le drapeau prend la priorité sur le paramètre remote.defaultEnvironmentId. Il ne supporte pas --output-format stream-json, et ne peut pas être combiné avec des drapeaux qui reprennent, s’attachent à, ou préconfigent une session, comme --resume, --continue, --teleport, --session-id, ou --init-only. --cloud est rejeté avec un ID de session ou une URL, et dans les exécutions non-interactives quand il porte une description. Un --cloud nu est traité comme absent. À partir d’un terminal, vous pouvez passer la tâche comme description --cloud au lieu d’une invite positionnelle.
Exemple de script
Le script ci-dessous exécute la boucle complète contre$CLAUDE_TEST_ENVIRONMENT_ID, l’ID ccpool_... de votre environnement de test, affiché dans la boîte de dialogue de détail de l’environnement sur la page d’administration ou retourné par l’appel create-environment, et affirme sur une phrase sentinelle dans chaque réponse. Exécutez-le à partir d’une extraction git du référentiel dans lequel vous voulez que la session fonctionne, après avoir démarré un runner sur cet hôte avec le hook de capture installé et E2E_REPLY_DIR exporté.
TURN1/TURN2 et les sentinelles EXPECT1/EXPECT2 par tout ce qui exerce votre configuration, comme demander à Claude d’exécuter l’un de vos outils MCP personnalisés et affirmer sur sa sortie.
Runners de test distants
Si vos runners de test sont sur une infrastructure séparée, comme une flotte Kubernetes persistante avec laquelle votre travail CI ne peut pas partager un système de fichiers, remplacez l’écriture de fichier dans le hook Stop par un POST à un point de terminaison que votre driver écoute :S’authentifier à partir de CI
À la foisclaude -p ... --environment et claude -p ... --cloud s’authentifient avec un jeton OAuth claude.ai ; les clés API, comme sk-ant-xxxxx, ne sont pas acceptées pour l’un ou l’autre appel. Deux approches rendent un jeton disponible dans CI.
Hôte CI de longue durée
Exécutezclaude auth login une fois de manière interactive sur la machine qui exécute le script, en utilisant un compte utilisateur dédié pour l’automatisation. Claude Code stocke le jeton dans le trousseau du système d’exploitation sur macOS, ou dans ~/.claude/.credentials.json sur Linux et Windows. Sur un hôte macOS dont le Keychain ne peut pas être écrit, comme c’est typique dans une session SSH où le Keychain de connexion reste verrouillé, Claude Code stocke le jeton dans ~/.claude/.credentials.json là aussi. Voir Gestion des identifiants.
La CLI actualise automatiquement le jeton d’accès de courte durée à chaque invocation, mais la subvention de jeton d’actualisation sous-jacente est plafonnée à 30 jours à partir de la connexion initiale, donc réexécutez claude auth login de manière interactive sur cet hôte tous les 30 jours.
Runners CI éphémères
Il n’y a pas de jeton CI de longue durée pour cela aujourd’hui. La portée qui accorde le contrôle de session distante,user:sessions:claude_code, est plafonnée côté serveur à 30 jours, donc claude setup-token, qui frappe un jeton d’inférence uniquement d’un an, ne le couvre pas. Le secret d’environnement n’est pas accepté non plus, car il n’autorise qu’un runner à s’enregistrer auprès de l’environnement, pas à créer des sessions.
Pour provisionner une connexion stockée sur un runner éphémère, définissez CLAUDE_CODE_OAUTH_REFRESH_TOKEN et CLAUDE_CODE_OAUTH_SCOPES pour que claude auth login échange le jeton sans navigateur ; le même plafond de 30 jours s’applique à la subvention d’actualisation. Contactez votre équipe de compte Anthropic si vous avez besoin d’un chemin d’identité machine qui n’est pas lié à un compte humain.
Créer un environnement de test dédié
Créez et supprimez les environnements par programmation pour que chaque exécution CI en obtienne un propre ; le runner que votre travail CI démarre s’enregistre dans l’environnement frais. Les appels de création et de suppression ci-dessous sont les mêmes points de terminaison que la page d’administration Cloud environments sur claude.ai utilise, et ils nécessitent l’en-têteanthropic-beta: ccr-byoc-2025-07-29.
Frapper le jeton d’administrateur
$ADMIN_TOKEN est un jeton d’accès OAuth claude.ai pour un compte qui détient un rôle Propriétaire, frappé de la même manière que S’authentifier à partir de CI :
- Le frapper : exécutez
claude auth loginavec un compte qui détient un rôle Propriétaire, puis lisez le jeton d’accès actuel à partir de partout où Hôte CI de longue durée dit que Claude Code l’a stocké. - Le lire frais à chaque exécution : la CLI fait tourner le jeton d’accès, et le même plafond de subvention d’actualisation de 30 jours s’applique, donc ne stockez pas une copie.
- Le passer via stdin : comme l’exemple le fait, pour que le jeton ne se retrouve jamais dans la liste d’arguments de curl ou votre journal de construction.
Créer l’environnement
Capturez la réponse sans l’afficher :pool_secret est une identifiante de longue durée qui peut enregistrer des runners dans l’environnement, donc stockez-la comme un secret CI masqué et imprimez uniquement l’ID d’environnement. La forme -H @- qui garde le jeton hors de la liste de processus nécessite curl 7.55 ou ultérieur ; les anciennes versions de curl traitent @- comme un en-tête littéral et envoient la demande sans autorisation.
403 permission_error lisant self-hosted runners are disabled by your organization's policy.
Démarrez un runner sur cet hôte avec SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET=$ENVIRONMENT_SECRET, plus le hook de capture et E2E_REPLY_DIR par Installer le hook de capture, puis exécutez le script de test.