Skip to main content
Ambientes auto-hospedados estão em beta público em planos Team e Enterprise; Disponibilidade e limitações cobre o caminho de habilitação. Esta página é a receita de teste de CI; consulte o guia de início rápido para configuração e Implantar em produção para as receitas de frota.
Em um ambiente auto-hospedado, as sessões na nuvem do Claude Code são executadas em uma imagem de executor que você constrói e mantém. Antes de implantar uma nova imagem em seu ambiente de produção, execute uma sessão completa contra um ambiente de teste a partir de um script: crie uma sessão, leia a resposta do Claude, envie um acompanhamento e leia essa resposta também. Esta é a forma de um teste de fumaça de CI que verifica sua imagem de executor, acesso ao git e quaisquer ferramentas personalizadas antes de promover uma alteração. Esta receita assume que você já configurou um ambiente e um executor, e que seu trabalho de CI inicia o processo do executor no mesmo host que o script de teste, a configuração natural para testar uma nova imagem de executor. Um hook Stop que você instala no executor escreve a resposta final de cada turno em um arquivo local, e o script a lê de lá, portanto as únicas chamadas para a API Anthropic são os dois despachos em si. Se seus executores de teste estão em infraestrutura separada, consulte Executores de teste remotos.

Instale o hook de captura em seu runner de teste

A leitura funciona através de um hook Stop do Claude Code: quando Claude termina um turno, o hook recebe a mensagem final do assistente como last_assistant_message em seu JSON stdin e a anexa a $E2E_REPLY_DIR/<session_id>.txt. Instale-o da mesma forma que o hook Stop commit-nudge, no ~/.claude/ do host do runner, que o runner semeia em cada sessão.

Salve os arquivos do hook

Salve os dois arquivos abaixo no host do runner:
  • O bloco de configurações: mescle em ~/.claude/settings.json no host do runner
  • O script: salve como ~/.claude/hooks/e2e-stop-hook-capture.sh no host do runner e torne-o executável

Antes de iniciar o runner

Duas coisas das quais o hook depende:
  • Instale-o antes de iniciar o runner. O runner captura ~/.claude/ uma vez na inicialização, portanto um hook adicionado a um runner em execução entra em vigor apenas após uma reinicialização.
  • Exporte E2E_REPLY_DIR para o processo do runner. O hook é uma operação nula quando a variável não está definida ou o diretório não existe, portanto defina-a onde você inicia o runner, como a unidade systemd, especificação de pod ou etapa de CI. O script de teste abaixo também o requer.
Instale este hook apenas em runners que servem seu ambiente de teste. Ele escreve a resposta final de cada sessão em disco sempre que E2E_REPLY_DIR existe, o que é inofensivo em um runner de CI descartável, mas não algo para levar para uma imagem de runner de ambiente de produção onde a variável pode ser definida acidentalmente.

Execute o loop de teste

Os sinalizadores de dispatch --environment e --ref requerem Claude Code v2.1.224 ou posterior na máquina que executa o script, o mesmo piso que o próprio runner. Com o hook em vigor e um runner iniciado neste host, o script de teste:
  1. Cria uma sessão no ambiente de teste com claude -p "<prompt>" --environment <environment-id> --output-format json, executado a partir de um checkout de git para que a CLI possa detectar automaticamente o repositório a partir do remote origin. O --ref <branch> opcional baseia o checkout da sessão em uma ref nomeada em vez do HEAD local. O comando cria a sessão, imprime uma linha de JSON contendo session_id e sai sem aguardar a resposta do Claude.
  2. Aguarda a resposta aparecer em $E2E_REPLY_DIR/<session_id>.txt, escrita pelo hook Stop no runner assim que o turno é concluído.
  3. Envia um acompanhamento com claude -p "<message>" --cloud <session_id> --output-format json (consulte Enviar uma mensagem de acompanhamento para uma sessão em execução), que publica um evento de usuário na sessão existente e sai.
  4. Aguarda a resposta do acompanhamento da mesma forma que a etapa 2.

Comportamento de dispatch --environment

Claude Code cria a sessão, imprime o ID da sessão e um link para ela, e sai. O sinalizador tem precedência sobre a configuração remote.defaultEnvironmentId. Ele não suporta --output-format stream-json e não pode ser combinado com sinalizadores que retomam, anexam ou pré-configuram uma sessão, como --resume, --continue, --teleport, --session-id ou --init-only. --cloud é rejeitado com um ID de sessão ou URL, e em execuções não interativas quando carrega uma descrição. Um --cloud simples é tratado como ausente. A partir de um terminal, você pode passar a tarefa como a descrição --cloud em vez de um prompt posicional.

Script de exemplo

O script abaixo executa o loop completo contra $CLAUDE_TEST_ENVIRONMENT_ID, o ID ccpool_... do seu ambiente de teste, mostrado no diálogo de detalhes do ambiente na página de administração ou retornado pela chamada create-environment, e afirma uma frase sentinela em cada resposta. Execute-o a partir de um checkout de git do repositório no qual você deseja que a sessão funcione, após iniciar um runner neste host com o hook de captura instalado e E2E_REPLY_DIR exportado.
Substitua os prompts TURN1/TURN2 e as sentinelas EXPECT1/EXPECT2 por qualquer coisa que exercite sua configuração, como pedir ao Claude para executar uma de suas ferramentas MCP personalizadas e afirmar sua saída.

Runners de teste remotos

Se seus runners de teste estão em infraestrutura separada, como uma frota Kubernetes persistente com a qual seu trabalho de CI não pode compartilhar um sistema de arquivos, troque a escrita de arquivo no hook Stop por um POST para um endpoint que seu driver escuta:
No lado do driver, execute qualquer coisa que aceite o POST e mantenha a resposta até que o teste a solicite, como um pequeno listener HTTP dentro do trabalho de CI ou um receptor de webhook que você já executa. O hook é executado em sua infraestrutura, portanto o endpoint só precisa ser acessível a partir de seus runners.

Autentique a partir de CI

Tanto claude -p ... --environment quanto claude -p ... --cloud autenticam com um token OAuth claude.ai; chaves de API, como sk-ant-xxxxx, não são aceitas para nenhuma das duas chamadas. Duas abordagens disponibilizam um token em CI.

Host de CI de longa duração

Execute claude auth login uma vez interativamente na máquina que executa o script, usando uma conta de usuário dedicada para automação. Claude Code armazena o token no chaveiro do SO no macOS, ou em ~/.claude/.credentials.json no Linux e Windows. Em um host macOS cujo Keychain não pode ser escrito, como é típico em uma sessão SSH onde o Keychain de login permanece bloqueado, Claude Code armazena o token em ~/.claude/.credentials.json lá também. Consulte Gerenciamento de credenciais. A CLI atualiza o token de acesso de curta duração automaticamente em cada invocação, mas a concessão de token de atualização subjacente é limitada a 30 dias a partir do login inicial, portanto execute claude auth login interativamente nesse host a cada 30 dias.

Runners de CI efêmeros

Não há token de CI de longa duração para isso hoje. O escopo que concede controle de sessão remota, user:sessions:claude_code, é limitado no servidor a 30 dias, portanto claude setup-token, que cria um token somente de inferência de um ano, não o cobre. O segredo do ambiente também não é aceito, pois apenas autoriza um runner a se registrar no ambiente, não a criar sessões. Para provisionar um login armazenado em um runner efêmero, defina CLAUDE_CODE_OAUTH_REFRESH_TOKEN e CLAUDE_CODE_OAUTH_SCOPES para que claude auth login troque o token sem um navegador; o mesmo limite de 30 dias se aplica à concessão de atualização. Entre em contato com sua equipe de conta Anthropic se você precisar de um caminho de identidade de máquina que não esteja vinculado a uma conta humana.

Crie um ambiente de teste dedicado

Crie e exclua ambientes programaticamente para que cada execução de CI obtenha um limpo; o runner que seu trabalho de CI inicia se registra no ambiente novo. As chamadas de criação e exclusão abaixo são os mesmos endpoints que a página de administração Cloud environments em claude.ai usa, e requerem o cabeçalho anthropic-beta: ccr-byoc-2025-07-29.

Crie o token de administrador

$ADMIN_TOKEN é um token de acesso OAuth claude.ai para uma conta que possui uma função de Proprietário, criado da mesma forma que Autentique a partir de CI:
  • Crie-o: execute claude auth login com uma conta que possui uma função de Proprietário, depois leia o token de acesso atual de onde Host de CI de longa duração diz que Claude Code o armazenou.
  • Leia-o novo em cada execução: a CLI rotaciona o token de acesso, e o mesmo limite de concessão de atualização de 30 dias se aplica, portanto não armazene uma cópia.
  • Passe-o via stdin: como o exemplo faz, para que o token nunca chegue à lista de argumentos do curl ou seu log de compilação.

Crie o ambiente

Capture a resposta sem ecoá-la: pool_secret é uma credencial de longa duração que pode registrar runners no ambiente, portanto armazene-a como um segredo de CI mascarado e imprima apenas o ID do ambiente. O formulário -H @- que mantém o token fora da lista de processos requer curl 7.55 ou posterior; curl mais antigo trata @- como um cabeçalho literal e envia a solicitação sem autorização.
Até que um Proprietário ative Allow self-hosted environments para a organização, a chamada falha com um 403 permission_error lendo self-hosted runners are disabled by your organization's policy. Inicie um runner neste host com SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET=$ENVIRONMENT_SECRET, mais o hook de captura e E2E_REPLY_DIR por Instale o hook de captura, depois execute o script de teste.

Exclua o ambiente

Exclua o ambiente quando a execução terminar, para que cada execução de CI comece limpa: