Quando você envia um pull request, algumas verificações automatizadas são executadas no seu código pelo sistema de integração contínua (CI) do ClickHouse.
Isso acontece depois que um mantenedor do repositório (alguém da equipe do ClickHouse) analisa seu código e adiciona o rótulo can be tested ao seu pull request.
Os resultados das verificações são exibidos na página do pull request no GitHub, como descrito na documentação sobre verificações do GitHub.
Se uma verificação falhar, talvez seja necessário corrigi-la.
Esta página apresenta uma visão geral das verificações que você pode encontrar e do que pode fazer para corrigi-las.
Se parecer que a falha na verificação não está relacionada às suas alterações, pode ser uma falha transitória ou um problema de infraestrutura.
Envie um commit vazio para o pull request para reiniciar as verificações de CI:
Se não souber o que fazer, peça ajuda a um mantenedor.
Verifica se o PR pode ser mesclado na branch master.
Caso contrário, a verificação falhará com a mensagem Cannot fetch mergecommit.
Para corrigir essa verificação, resolva o conflito conforme descrito na documentação do GitHub ou faça o merge da branch master na branch do seu pull request usando git.
Verificação da documentação (Mintlify)
Valida a documentação do Mintlify, links e âncoras internos, redirecionamentos, importações de snippets e changelogs. Falhas em links externos são relatadas como avisos.
Também rejeita edições diretas em regiões geradas e cópias da documentação somente leitura. Em vez disso, atualize a documentação estruturada no registro de origem; atualizações geradas intencionalmente devem ter o rótulo pr-autogenerated-docs.
Se a verificação falhar após uma alteração na documentação, abra o relatório e procure mensagens ERROR e WARNING.
Verifique se a descrição do seu pull request está em conformidade com o modelo PULL_REQUEST_TEMPLATE.md.
Você precisa especificar uma categoria de changelog para a sua alteração (por exemplo, correção de bug) e escrever uma mensagem compreensível para o usuário descrevendo a alteração em CHANGELOG.md
Compila as imagens Docker do servidor ClickHouse e do Keeper para verificar se foram compiladas corretamente.
Testes oficiais da biblioteca do Docker
Executa os testes da biblioteca oficial do Docker para verificar se a imagem Docker clickhouse/clickhouse-server funciona corretamente.
Para adicionar novos testes, crie um diretório ci/jobs/scripts/docker_server/tests/$test_name e o script run.sh nele.
Mais detalhes sobre os testes podem ser encontrados na documentação dos scripts de jobs de CI.
Esta verificação indica que o sistema de CI começou a processar o pull request.
Quando ela está com status ‘pending’, isso significa que ainda nem todas as verificações foram iniciadas.
Depois que todas as verificações forem iniciadas, o status muda para ‘success’.
Executa várias verificações de estilo na base de código. Cada subverificação abaixo corresponde a um testname em ci/jobs/check_style.py e pode ser executada individualmente com --test <name> (veja abaixo).
cpp
Verificações de estilo de C++ baseadas em regex via check_cpp.sh. Se falhar, corrija os problemas de acordo com o guia de estilo de código.
whitespace_check
Sinaliza espaços duplos após vírgulas em C++ que não fazem parte do alinhamento de colunas.
catch_all
Proíbe catch (...) fora de destrutores, de main e de pontos de entrada de fuzzer, em contextos nos quais ignorar uma exceção desconhecida não é seguro.
yamllint
Valida os arquivos de workflow em YAML em .github/ usando .yamllint.
xmllint
Valida arquivos XML nos diretórios tests/ e programs/.
functional_tests_check
Verifica testes sem estado: consultas com filtro em event_date devem usar >= yesterday() em vez de today() (para evitar instabilidade perto da meia-noite), e os nomes dos arquivos de teste não devem conter fail.
test_numbers_check
Sinaliza lacunas grandes na numeração de testes sem estado (tests/queries/0_stateless/<NNNNN>_*).
links simbólicos
Detecta links simbólicos inválidos no repositório.
diversos
Verificações diversas do repositório via various_checks.sh: consultas em system.query_log / system.parts / etc. devem filtrar por currentDatabase, os caminhos do ZooKeeper de Replicated*MergeTree devem incluir um prefixo específico por teste, os diretórios de testes de integração devem ter __init__.py, não pode haver BOMs UTF, nem bits de execução em arquivos de origem/dados, nem tags :latest em imagens de terceiros no docker-compose, entre outras verificações.
Executando localmente o job Style Verificação
Todo o job Style Verificação pode ser executado localmente em um contêiner Docker com:
Para executar uma verificação específica (por exemplo, a verificação de cpp):
Esses comandos baixam a imagem Docker clickhouse/style-test e executam o job em um ambiente em contêiner.
Não são necessárias dependências além de Python 3 e Docker.
Executando testes sem estado
Uma instalação local do ClickHouse com as configurações padrão pode funcionar para casos de teste específicos, mas não consegue executar corretamente todas as consultas de teste. Na CI, cada job instala uma configuração específica do ClickHouse (por exemplo, armazenamento S3, réplicas paralelas), o que pode ser trabalhoso reproduzir manualmente. Para evitar isso, você pode reproduzir localmente qualquer job da CI usando a mesma orquestração da CI — sem precisar de configuração manual.
- Python 3 (apenas a biblioteca padrão)
- Docker
Instale o Docker no Ubuntu, se necessário, e faça login novamente:
Execute um job de CI localmente
Escolha o nome de qualquer job em um relatório de CI e execute-o localmente:
- Sempre coloque o nome do job entre aspas exatamente como ele aparece no relatório de CI (ele pode conter espaços e vírgulas), por exemplo:
"Stateless tests (amd_debug, parallel)". Isso define a mesma configuração do ClickHouse e executa os mesmos testes da CI.
- A arquitetura e o tipo de build no nome do job (por exemplo,
amd_debug) são rótulos específicos da CI. Ao executar localmente, eles não têm efeito — o job usará o binário que você fornecer, na arquitetura em que estiver rodando. O nome do job determina apenas a configuração do ClickHouse e o conjunto de testes (a menos que isso seja sobrescrito com --test).
- Na CI, os testes funcionais são divididos em lotes para melhor aproveitamento de recursos. Por exemplo,
"Stateless tests (amd_debug, parallel)" e "Stateless tests (amd_debug, sequential)" juntos cobrem todo o escopo: os testes seguros para paralelismo são executados de forma concorrente, e o restante é executado de forma sequencial. Essa divisão reduz o tempo total da CI ao maximizar o paralelismo sempre que possível. Para reproduzir localmente todo o escopo de testes, execute ambos os lotes.
- Também existe um job de CI,
"Fast test", que executa um escopo limitado de testes funcionais para verificar a funcionalidade básica do ClickHouse — ele usa uma build sem todos os módulos opcionais e é a forma mais rápida de detectar regressões. Você pode executá-lo localmente da mesma forma. Coloque o binário do ClickHouse em um dos caminhos de busca padrão (./ci/tmp/clickhouse, ./build/programs/clickhouse ou ./clickhouse) — caso contrário, o job tentará compilar o ClickHouse primeiro:
Executar testes específicos em um job de CI
Com --test, o job prepara um ambiente do ClickHouse idêntico ao usado na CI, mas executa apenas os testes selecionados:
- Você pode informar vários nomes de teste:
- Dica: Se qualquer configuração do ClickHouse servir e você só precisar executar testes específicos, use o alias
functional em vez do nome completo do job:
Opções adicionais de personalização
--path PATH — caminho personalizado para o binário do ClickHouse. Por padrão, o runner procura nesta ordem: ./ci/tmp/clickhouse, ./build/programs/clickhouse, ./clickhouse.
--count N — repete cada teste N vezes.
--workers N — substitui o cálculo automático do número de workers paralelos com base na capacidade da máquina.
Compila o ClickHouse em diferentes configurações para uso nas etapas seguintes.
Executando builds localmente
A build pode ser executada localmente em um ambiente semelhante ao de CI com:
Nenhuma dependência além de Python 3 e Docker é necessária.
Jobs de compilação disponíveis
Os nomes dos jobs de compilação são exatamente os mesmos exibidos no relatório de CI:
Builds AMD64:
Build (amd_debug) - Build de depuração com símbolos
Build (amd_release) - Build de release otimizada
Build (amd_asan) - Build com Address Sanitizer
Build (amd_tsan) - Build com Thread Sanitizer
Build (amd_msan) - Build com Memory Sanitizer
Build (amd_ubsan) - Build com Undefined Behavior Sanitizer
Build (amd_binary) - Build de release rápida sem Thin LTO
Build (amd_compat) - Build de compatibilidade para sistemas mais antigos
Build (amd_musl) - Build com musl libc
Build (amd_darwin) - Build para macOS
Build (amd_freebsd) - Build para FreeBSD
Builds ARM64:
Build (arm_release) - Build de release otimizada para ARM64
Build (arm_asan) - Build ARM64 com Address Sanitizer
Build (arm_coverage) - Build ARM64 com instrumentação de cobertura
Build (arm_binary) - Build de release rápida para ARM64 sem Thin LTO
Build (arm_darwin) - Build ARM64 para macOS
Build (arm_v80compat) - Build de compatibilidade para ARMv8.0
Outras arquiteturas:
Build (ppc64le) - PowerPC de 64 bits Little Endian
Build (riscv64) - RISC-V de 64 bits
Build (s390x) - IBM System/390 de 64 bits
Build (loongarch64) - LoongArch de 64 bits
Build (wasm64) - WebAssembly de 64 bits, por meio do Emscripten. Experimental: compila o binário clickhouse e verifica se clickhouse local executa consultas no Node.js ≥ 24 (o módulo também é executado em navegadores, mas a CI ainda não verifica isso)
Se o job for concluído com sucesso, os resultados da compilação estarão disponíveis no diretório <repo_root>/ci/tmp/build.
Observação: Para builds que não estejam na categoria “Outras arquiteturas” (que usam compilação cruzada), a arquitetura da sua máquina local deve corresponder ao tipo de build para gerar a compilação solicitada por BUILD_JOB_NAME.
Para executar uma build local de depuração:
Se a abordagem acima não funcionar para você, use as opções do cmake presentes no log de compilação e siga o processo geral de compilação.
Testes funcionais sem estado
Executa testes funcionais sem estado para binários do ClickHouse compilados em várias configurações — release, debug, com sanitizers etc.
Consulte o relatório para ver quais testes falham e, em seguida, reproduza a falha localmente, conforme descrito aqui.
Observe que é preciso usar a configuração de build correta para reproduzir — um teste pode falhar com o AddressSanitizer, mas passar em Debug.
Baixe o binário na página de verificações de build do CI ou compile-o localmente.
Executa os testes de integração.
Verificação de validação de correção de bug
Verifica se há um novo teste (funcional ou de integração) ou testes alterados que falham com o binário compilado na branch master.
Esta verificação é acionada quando o pull request tem o rótulo “pr-bugfix”.
Executa testes funcionais sem estado em paralelo a partir de vários clientes para detectar erros relacionados à concorrência. Se falhar:
- Corrija primeiro todas as outras falhas de teste;
- Consulte o relatório para localizar os logs do servidor e verifique-os em busca de possíveis causas
do erro.
Verificação de compatibilidade
Verifica se o binário clickhouse roda em distribuições com versões antigas da libc.
Se falhar, peça ajuda a um mantenedor.
Executa consultas geradas aleatoriamente para identificar erros no programa.
Se falhar, peça ajuda a um mantenedor.
Meça as mudanças no desempenho das consultas.
Esta é a verificação mais demorada e leva pouco menos de 6 horas para ser executada.
O relatório do teste de desempenho é descrito em detalhes aqui.
Reverter regressões na CI
Esta não é uma verificação do seu pull request: ela é executada em master a cada hora e pode reverter um pull request já mesclado.
O job coleta os testes que falharam e foram registrados pelo banco de dados da CI para master nas últimas 24 horas e os agrupa por nome de teste, considerando todas as verificações em que o teste falhou.
O mesmo teste falhar nas compilações de depuração e tsan representa uma única falha, com uma única causa a investigar, e as verificações em que ele apareceu entram na investigação como evidência: uma alteração que quebra um teste geralmente o quebra em várias compilações de uma vez.
Falhas que não são atribuídas a nenhum teste, como uma falha de compilação ou um job que excedeu o tempo limite, são deixadas de fora: “por que esta verificação falha” não tem uma resposta única que possa ser revertida.
Linhas que o ambiente de testes grava sobre o script inteiro sob um nome semelhante ao de um teste, como Test script failed ou Server died, são rejeitadas da mesma forma.
Um teste que falhou em mais de um commit de master é encaminhado a um agente de IA, que recebe o repositório com o histórico completo de master e acesso somente leitura ao banco de dados da CI, e responde a uma única pergunta: essa falha foi introduzida por um pull request mesclado recentemente e, em caso afirmativo, qual?
O agente não tem credenciais do GitHub nem como criar uma — ele é executado como um usuário sem privilégios, com ambiente vazio e os endpoints de credenciais de nuvem bloqueados por firewall para esse usuário — e trabalha em um clone descartável do repositório, em vez do checkout do próprio job; portanto, nada do que ele conclua — nem nada que possa deixar para trás — pode chegar ao GitHub, exceto por meio das verificações abaixo.
O limite conta commits, não linhas com falha; portanto, um commit ruim que falha em três compilações ainda conta como uma única ocorrência e não gera nenhuma ação.
Também há contagem por modo de falha: as saídas registradas recebem uma impressão digital, com as partes voláteis (endereços, timestamps, nomes aleatórios de bancos de dados) normalizadas, e um teste cujo nome abrange duas causas diferentes — uma regressão em um commit e uma falha intermitente não relacionada em outro — não é considerado uma falha repetida; assim, nada é investigado até que uma causa se repita por si só.
Somente uma resposta inequívoca leva a uma ação.
Quando o agente relata uma regressão com alta confiança e o pull request identificado passa pelas verificações de segurança (foi mesclado em master nos últimos três dias, não é uma reversão, ainda não foi revertido e a reversão pode ser aplicada sem conflitos), o job o reverte, mescla a reversão imediatamente sem esperar pelas verificações e abre um pull request em rascunho intitulado Reapply "...", que reintroduz a alteração.
Um veredito de regressão precisa identificar tanto o pull request quanto o commit de master em que ele foi incluído, e ambos devem corresponder: o job compara o número ao registro do GitHub que indica qual commit de merge esse pull request gerou e não toma nenhuma ação se houver divergência.
Nada é revertido depois que a falha desaparece: uma falha permanece na janela de observação por um dia inteiro após deixar de ocorrer; portanto, imediatamente antes de reverter, o job consulta novamente o banco de dados da CI, e uma falha ausente dos commits mais recentes de master executados por todas as verificações afetadas é registrada como já corrigida e deixada de lado.
Os commits mais recentes são determinados pelo histórico da própria branch, e não pelo momento em que suas verificações foram executadas — um commit antigo cuja verificação começou tarde não deve ser interpretado como evidência recente de sucesso.
Ausência, e não aprovação, porque a maior parte do que este job investiga não tem uma linha de aprovação para encontrar: um erro lógico ou uma verificação travada é registrado sob o próprio texto da falha e somente quando ocorre.
Uma verificação só conta como tendo exercitado um commit quando uma execução dela concluiu os testes: uma execução interrompida no meio — registrada pelo ambiente como Test script failed ou Server died ao lado das linhas de teste que de fato produziu — executou alguns testes, não necessariamente este, e a ausência da falha não é evidência; já uma nova execução da mesma verificação que foi concluída no mesmo commit é.
A quantidade de ausências necessária depende da frequência da falha — alguns commits sem falha não significam nada para algo que falha em uma execução a cada cem; portanto, o requisito é maior que o período mais longo em que a falha ficou sem ocorrer entre suas próprias ocorrências.
Quando a pergunta não pode ser respondida — por exemplo, porque uma verificação em que a falha foi observada deixou de reportar sob esse nome ou porque o histórico de commits desde o início da falha é maior do que o retornado pela consulta — isso também é registrado, e nada é revertido.
No máximo dois pull requests são revertidos por execução.
Se o seu pull request foi revertido:
- O pull request de reversão explica o que falha e por que a alteração foi responsabilizada. Se a atribuição estiver errada, informe isso lá e restaure a alteração.
- O pull request em rascunho
Reapply "..." mantém sua alteração inalterada. Corrija a falha nessa branch, marque-o como pronto para revisão e deixe-o passar pela CI normal.
Todas as investigações são registradas na tabela checks_investigated do banco de dados de CI, inclusive aquelas que não revertem nada.
Os valores são transferidos de checks conforme foram registrados nela, de modo que as duas tabelas podem ser associadas novamente — diretamente por test_name, usando has(check_names, check_name) e has(commit_shas, commit_sha) para as colunas que reúnem várias linhas de checks em um array, e offending_pull_request_number = pull_request_number para o pull request considerado responsável —, e o histórico do que o job analisou, concluiu e fez pode ser consultado em play.clickhouse.com:
O job é implementado em ci/jobs/revert_ci_regressions.py e é executado como parte do workflow Hourly.
Executá-lo com --dry-run verifica e avalia cada condição de proteção, mas não altera nada: nenhuma tabela, nenhuma linha, nenhuma branch, nenhum pull request, nenhum merge; em vez disso, imprime as linhas que teria gravado.
Um workflow separado, .github/workflows/revert_broken_prs.yml, reverte merges que foram incluídos enquanto sua própria CI estava com falha; ambos usam o mesmo nome de branch revert-<pull request number>, de modo que um pull request nunca é revertido duas vezes.
Uma reversão iniciada manualmente também é considerada: o job não atua quando a reversão já está em master, quando existe uma branch chamada revert-<pull request number> ou revert-<pull request number>-<branch> (que é o que o botão Revert no GitHub cria), ou quando há um pull request de uma dessas branches aberto ou mesclado. Última modificação em 14 de agosto de 2026