Skip to main content
Lorsque vous soumettez une pull request, certaines vérifications automatisées sont exécutées sur votre code par le système d’intégration continue (CI) de ClickHouse. Cela se produit après qu’un mainteneur du dépôt (quelqu’un de l’équipe ClickHouse) a passé votre code en revue et ajouté le label can be tested à votre pull request. Les résultats des vérifications sont affichés sur la page GitHub de la pull request, comme décrit dans la documentation GitHub sur les vérifications. Si une vérification échoue, il peut vous être demandé de la corriger. Cette page présente un aperçu des vérifications que vous pouvez rencontrer et de ce que vous pouvez faire pour les corriger. S’il semble que l’échec de la vérification ne soit pas lié à vos modifications, il peut s’agir d’une défaillance temporaire ou d’un problème d’infrastructure. Poussez un commit vide sur la pull request pour redémarrer les vérifications CI :
Si vous ne savez pas quoi faire, demandez de l’aide à l’un des mainteneurs du projet.

Fusion avec master

Vérifie que la PR peut être fusionnée avec master. Sinon, la vérification échoue avec le message Cannot fetch mergecommit. Pour que cette vérification réussisse, résolvez le conflit comme indiqué dans la documentation GitHub, ou fusionnez la branche master dans la branche de votre pull request à l’aide de git.

Vérification de la documentation (Mintlify)

Valide la documentation Mintlify, les liens et ancres internes, les redirections, les importations d’extraits et les changelogs. Les défaillances des liens externes sont signalées comme des avertissements. Rejette également les modifications directes des zones générées et des copies de documentation en lecture seule. Mettez plutôt à jour la documentation structurée dans l’enregistrement source ; les mises à jour générées intentionnellement doivent porter le label pr-autogenerated-docs. Si la vérification échoue après une modification de la documentation, ouvrez son rapport et recherchez les messages ERROR et WARNING.

Vérification de la description

Vérifiez que la description de votre pull request respecte le modèle PULL_REQUEST_TEMPLATE.md. Vous devez indiquer une catégorie de changelog pour votre modification (par exemple, Bug Fix) et rédiger un message clair pour l’utilisateur décrivant la modification pour CHANGELOG.md

Image Docker

Compile les images Docker du serveur ClickHouse et de Keeper afin de vérifier qu’elles se compilent correctement.

Tests officiels de la bibliothèque Docker

Exécute les tests de la bibliothèque officielle Docker pour vérifier que l’image Docker clickhouse/clickhouse-server fonctionne correctement. Pour ajouter de nouveaux tests, créez un répertoire ci/jobs/scripts/docker_server/tests/$test_name et ajoutez-y le script run.sh. Des informations complémentaires sur ces tests sont disponibles dans la documentation des scripts des jobs CI.

Vérification « Marker »

Cette vérification indique que le système de CI a commencé à traiter la pull request. Lorsqu’elle est au statut ‘pending’, cela signifie que toutes les vérifications n’ont pas encore été lancées. Une fois toutes les vérifications lancées, son statut passe à ‘success’.

Style check

Exécute différentes vérifications de style sur le code source. Chaque sous-vérification ci-dessous correspond à un testname dans ci/jobs/check_style.py et peut être exécutée individuellement avec --test <name> (voir ci-dessous).
cpp
Vérifications du style C++ basées sur des Regex via check_cpp.sh. En cas d’échec, corrigez les problèmes en suivant le guide de style du code.
whitespace_check
Signale les doubles espaces après les virgules en C++ qui ne relèvent pas de l’alignement des colonnes.
catch_all
Interdit catch (...) en dehors des destructeurs, de main et des points d’entrée du fuzzer, où il est dangereux d’intercepter et d’ignorer une exception inconnue.
yamllint
Vérifie la conformité des fichiers de workflow YAML dans .github/ à l’aide de .yamllint.
xmllint
Valide les fichiers XML situés dans tests/ et programs/.
functional_tests_check
Vérifie les tests sans état : les requêtes avec un filter sur event_date doivent utiliser >= yesterday() plutôt que today() (pour éviter toute instabilité autour de minuit), et les noms des fichiers de test ne doivent pas contenir fail.
test_numbers_check
Détecte d’importantes lacunes dans la numérotation des tests sans état (tests/queries/0_stateless/<NNNNN>_*). Détecte les liens symboliques cassés dans le dépôt.
divers
Vérifications diverses du dépôt via various_checks.sh : les requêtes sur system.query_log / system.parts / etc. doivent filtrer sur currentDatabase, les chemins ZooKeeper de Replicated*MergeTree doivent inclure un préfixe propre à chaque test, les répertoires de tests d’intégration doivent contenir __init__.py, pas de BOM UTF, pas de bits d’exécution sur les fichiers source ou de données, pas de tags :latest sur les images tierces dans docker-compose, et plus encore.

Exécuter le job Style Check en local

L’intégralité du job Style Check peut être exécutée en local dans un conteneur Docker avec :
Pour exécuter une vérification spécifique (par exemple, la vérification cpp) :
Ces commandes récupèrent l’image Docker clickhouse/style-test et exécutent le job dans un environnement conteneurisé. Aucune dépendance n’est requise en dehors de Python 3 et de Docker.

Exécuter les tests sans état

Une instance de ClickHouse installée localement avec les paramètres par défaut peut convenir à certains cas de test, mais ne permet pas d’exécuter correctement toutes les requêtes de test. En CI, chaque job installe une configuration ClickHouse spécifique (par ex., stockage S3, répliques parallèles), ce qui peut être fastidieux à reproduire manuellement. Pour éviter cela, vous pouvez reproduire n’importe quel job CI en local en utilisant la même orchestration que la CI — aucune configuration manuelle n’est nécessaire.

Prérequis

  • Python 3 (bibliothèque standard uniquement)
  • Docker
Installez Docker sur Ubuntu si nécessaire, puis reconnectez-vous :

Exécuter un job de CI en local

Choisissez le nom d’un job dans un rapport de CI et exécutez-le en local :
  • Indiquez toujours le nom du job exactement tel qu’il apparaît dans le rapport CI (il peut contenir des espaces et des virgules), par ex. : "Stateless tests (amd_debug, parallel)". Cela applique la même configuration ClickHouse et exécute les mêmes tests qu’en CI.
  • L’architecture et le type de build dans le nom du job (par ex. amd_debug) sont des libellés propres à la CI. Lors d’une exécution en local, ils n’ont aucun effet : le job utilisera le binaire que vous fournissez, sur l’architecture sur laquelle vous l’exécutez. Le nom du job détermine uniquement la configuration ClickHouse et l’ensemble de tests (sauf substitution via --test).
  • En CI, les tests fonctionnels sont répartis en lots pour optimiser l’utilisation des ressources. Par exemple, "Stateless tests (amd_debug, parallel)" et "Stateless tests (amd_debug, sequential)" couvrent ensemble l’intégralité du périmètre : les tests compatibles avec une exécution en parallèle s’exécutent concurremment, et les autres s’exécutent de façon séquentielle. Cette répartition réduit le temps total d’exécution en CI en maximisant le parallélisme lorsque c’est possible. Pour reproduire localement l’ensemble du périmètre de test, exécutez les deux lots.
  • Il existe également un job CI "Fast test" qui exécute un sous-ensemble limité de tests fonctionnels afin de vérifier les fonctionnalités de base de ClickHouse. Il utilise un build sans tous les modules optionnels et constitue le moyen le plus rapide de détecter les régressions. Vous pouvez l’exécuter localement de la même manière. Placez votre binaire ClickHouse dans l’un des chemins de recherche par défaut (./ci/tmp/clickhouse, ./build/programs/clickhouse ou ./clickhouse) ; sinon, le job tentera d’abord de compiler ClickHouse :

Exécuter des tests spécifiques dans un job CI

Avec --test, le job prépare un environnement ClickHouse identique à celui utilisé en CI, mais n’exécute que les tests sélectionnés :
  • Vous pouvez indiquer plusieurs noms de tests :
  • Conseil : si n’importe quelle configuration ClickHouse vous convient et que vous avez simplement besoin d’exécuter des tests spécifiques, utilisez l’alias functional au lieu du nom complet du job :

Options de personnalisation supplémentaires

  • --path PATH — chemin personnalisé vers le binaire ClickHouse. Par défaut, le runner recherche, dans l’ordre : ./ci/tmp/clickhouse, ./build/programs/clickhouse, ./clickhouse.
  • --count N — répéter chaque test N fois.
  • --workers N — remplace le calcul automatique du nombre de workers parallèles en fonction de la capacité de la machine.

Vérification de compilation

Compile ClickHouse dans différentes configurations pour les étapes suivantes.

Exécuter des builds en local

Les builds peuvent être exécutés en local dans un environnement similaire à la CI avec :
Aucune dépendance autre que Python 3 et Docker n’est nécessaire.

Jobs de build disponibles

Les noms des jobs de build sont exactement ceux qui apparaissent dans le rapport CI : Builds AMD64 :
  • Build (amd_debug) - Compilation de débogage avec symboles
  • Build (amd_release) - Compilation optimisée de release
  • Build (amd_asan) - Compilation avec Address Sanitizer
  • Build (amd_tsan) - Compilation avec Thread Sanitizer
  • Build (amd_msan) - Compilation avec Memory Sanitizer
  • Build (amd_ubsan) - Compilation avec Undefined Behavior Sanitizer
  • Build (amd_binary) - Compilation de release rapide sans Thin LTO
  • Build (amd_compat) - Compilation de compatibilité pour les anciens systèmes
  • Build (amd_musl) - Compilation avec musl libc
  • Build (amd_darwin) - Compilation macOS
  • Build (amd_freebsd) - Compilation FreeBSD
Builds ARM64 :
  • Build (arm_release) - Compilation de release optimisée ARM64
  • Build (arm_asan) - Compilation ARM64 avec Address Sanitizer
  • Build (arm_coverage) - Compilation ARM64 avec instrumentation de couverture
  • Build (arm_binary) - Compilation de release rapide ARM64 sans Thin LTO
  • Build (arm_darwin) - Compilation macOS ARM64
  • Build (arm_v80compat) - Compilation de compatibilité ARMv8.0
Autres architectures :
  • Build (ppc64le) - PowerPC 64 bits Little Endian
  • Build (riscv64) - RISC-V 64 bits
  • Build (s390x) - IBM System/390 64 bits
  • Build (loongarch64) - LoongArch 64 bits
  • Build (wasm64) - WebAssembly 64 bits, via Emscripten. Expérimental : compile le binaire clickhouse et vérifie que clickhouse local exécute des requêtes sous Node.js ≥ 24 (le module s’exécute également dans les navigateurs, mais CI ne le vérifie pas encore)
Si le job réussit, les résultats de la compilation seront disponibles dans le répertoire <repo_root>/ci/tmp/build. Remarque : Pour les builds qui ne relèvent pas de la catégorie « Autres architectures » (qui utilisent la compilation croisée), l’architecture de votre machine locale doit correspondre au type de build afin de produire la compilation demandée par BUILD_JOB_NAME.

Exemple

Pour exécuter un build local de débogage :
Si l’approche ci-dessus ne fonctionne pas dans votre cas, utilisez les options CMake du journal de compilation et suivez la procédure générale de compilation.

Tests fonctionnels sans état

Exécute les tests fonctionnels sans état pour les binaires ClickHouse compilés avec différentes configurations — release, debug, avec sanitizers, etc. Consultez le rapport pour voir quels tests échouent, puis reproduisez l’échec en local comme décrit ici. Notez que vous devez utiliser la configuration de build appropriée pour reproduire le problème — un test peut échouer avec AddressSanitizer, mais réussir en Débogage. Téléchargez le binaire depuis la page des vérifications de build de la CI, ou compilez-le localement. Dans les pull requests, la plupart des jobs de sanitizer dont le nom se termine par selected tests n’exécutent pas toute la suite de tests. Ils exécutent uniquement les tests sélectionnés pour la modification : les tests que la pull request ajoute ou modifie, les tests qui ont déjà échoué dans cette pull request et les tests qui couvrent les lignes modifiées selon la base de données de couverture. Les jobs MSan/WasmEdge continuent d’exécuter toute la suite, car les tests UDF Wasm existants ne sont pas compatibles avec MSan. Toute la suite est également exécutée dans les configurations de binaires debug et simples, les builds avec sanitizers sont testés via le test de stress, et la branche master exécute toute la suite dans chaque configuration.

Tests d’intégration

Exécuter les tests d’intégration.

Validation des correctifs de bugs

Vérifie qu’il y a soit un nouveau test (fonctionnel ou d’intégration), soit des tests modifiés qui échouent avec le binaire compilé sur la branche master. Cette vérification est déclenchée lorsque la pull request porte le label “pr-bugfix”.

Test de stress

Exécute des tests fonctionnels sans état en parallèle à partir de plusieurs clients afin de détecter les erreurs liées à la concurrence. En cas d’échec :
  • Corrigez d’abord tous les autres échecs de test ;
    • Consultez le rapport pour trouver les logs du serveur et les vérifier afin d’identifier les causes possibles de l’erreur.

Vérification de compatibilité

Vérifie que le binaire clickhouse fonctionne sur des distributions utilisant d’anciennes versions de libc. En cas d’échec, demandez de l’aide à un mainteneur.

AST fuzzer

Exécute des requêtes générées aléatoirement pour détecter les erreurs du programme. S’il échoue, demandez de l’aide à un mainteneur.

Tests de performance

Mesurez les changements de performance des requêtes. C’est la vérification la plus longue et son exécution prend un peu moins de 6 heures. Le rapport du test de performance est décrit en détail ici.

Annuler les régressions d’intégration continue

Il ne s’agit pas d’une vérification de votre pull request : elle s’exécute sur master toutes les heures et peut annuler une pull request déjà fusionnée. Le job récupère les tests en échec enregistrés par la base de données d’intégration continue pour master au cours des dernières 24 heures et les regroupe par nom de test, toutes vérifications confondues. L’échec d’un même test dans la build de débogage et dans la build tsan correspond à un seul échec, avec une seule cause à rechercher ; les vérifications dans lesquelles il est apparu sont versées à l’investigation comme éléments de preuve : une modification qui casse un test le casse généralement dans plusieurs builds simultanément. Les échecs qui ne sont attribués à aucun test, comme un échec de build ou une tâche ayant dépassé le délai imparti, sont exclus : la question « pourquoi cette vérification échoue-t-elle ? » n’a pas de réponse unique à annuler. Les lignes que le harnais de test écrit à propos de l’ensemble du script sous un nom ressemblant à celui d’un test, comme Test script failed ou Server died, sont exclues de la même manière. Un test ayant échoué sur plus d’un commit de master est confié à un agent d’IA, qui reçoit le dépôt avec l’historique complet de master et un accès en lecture seule à la base de données d’intégration continue, et doit répondre à une seule question : cet échec a-t-il été introduit par une pull request récemment fusionnée, et laquelle ? L’agent ne dispose d’aucun identifiant GitHub ni d’aucun moyen d’en obtenir un — il s’exécute sous son propre utilisateur non privilégié, dans un environnement vide, avec les endpoints d’identifiants cloud bloqués par un firewall pour cet utilisateur — et travaille dans un clone jetable du dépôt plutôt que dans le checkout du job. Ainsi, aucune de ses conclusions — ni rien de ce qu’il pourrait y laisser — ne peut atteindre GitHub autrement que par les vérifications ci-dessous. Le seuil compte les commits plutôt que les lignes en échec : un mauvais commit qui échoue dans trois builds ne représente toujours qu’une seule occurrence et ne déclenche aucune action. Il les compte également par mode d’échec : les sorties enregistrées sont soumises à une empreinte dont les parties volatiles (adresses, timestamps, noms de bases de données aléatoires) sont normalisées, et un test dont le nom recouvre deux causes différentes — une régression sur un commit et un flaky sans lien sur un autre — n’est pas considéré comme un échec répété. Rien n’est donc investigué tant qu’une même cause ne se répète pas. Seule une réponse sans ambiguïté mène à une action. Lorsque l’agent signale une régression avec un niveau de confiance élevé et que la pull request identifiée passe les vérifications de sécurité (fusionnée dans master au cours des trois derniers jours, n’étant pas elle-même une annulation, n’ayant pas déjà été annulée et dont l’annulation s’applique proprement), le job l’annule, fusionne immédiatement l’annulation sans attendre les vérifications et ouvre une pull request en brouillon intitulée Reapply \"...\" qui réintroduit la modification. Un verdict de régression doit indiquer à la fois la pull request et le commit master par lequel elle a été introduite, et les deux doivent correspondre : le job compare le numéro à l’enregistrement GitHub du commit de fusion produit par cette pull request et n’agit sur aucun des deux s’ils ne correspondent pas. Rien n’est annulé une fois l’échec disparu : un échec reste dans la fenêtre d’observation pendant une journée entière après avoir cessé, donc, juste avant l’annulation, le job interroge à nouveau la base de données d’intégration continue. Un échec absent des commits master les plus récents sur lesquels chaque vérification affectée s’est exécutée est enregistré comme déjà corrigé et laissé tel quel. Les commits les plus récents sont déterminés d’après l’historique de la branche elle-même, et non selon le moment où leurs vérifications se sont exécutées — un ancien commit dont la vérification a démarré tardivement ne doit pas être interprété comme une preuve récente de succès. L’absence plutôt qu’une réussite, car la plupart des éléments investigués par ce job ne possèdent aucune ligne de réussite à trouver : une erreur logique ou une vérification bloquée est enregistrée sous le texte de l’échec lui-même, et uniquement lorsqu’elle se produit. Une vérification n’est considérée comme ayant testé un commit que lorsqu’une de ses exécutions a terminé ses tests : une exécution interrompue en cours de route — enregistrée par le harnais sous Test script failed ou Server died à côté des lignes de test qu’elle a effectivement produites — a exécuté certains tests, pas nécessairement celui-ci, et son silence concernant l’échec ne constitue pas une preuve. En revanche, une réexécution de la même vérification terminée sur le même commit en constitue une. L’importance de l’absence dépend de la fréquence des échecs — quelques commits sans échec ne signifient rien pour un problème qui échoue une fois sur cent ; l’exigence est donc supérieure à la plus longue période de silence enregistrée entre ses propres occurrences. Lorsque la question ne peut recevoir aucune réponse — une vérification dans laquelle l’échec a été observé ne remonte plus sous ce nom, ou l’historique des commits depuis le début de l’échec est plus long que ce que renvoie la requête — cela est également enregistré et rien n’est annulé. Au plus deux pull requests sont annulées par exécution. Si votre pull request a été annulée :
  • La pull request d’annulation explique ce qui échoue et pourquoi la modification a été mise en cause. Si l’attribution est erronée, indiquez-le dans cette pull request et réintroduisez la modification.
  • La pull request en brouillon Reapply \"...\" conserve votre modification inchangée. Corrigez l’échec sur cette branche, marquez-la comme prête pour révision et laissez-la suivre le processus normal d’intégration continue.
Chaque investigation est enregistrée dans la table checks_investigated de la base de données d’intégration continue, y compris celles qui n’aboutissent à aucune annulation. Les valeurs sont reprises de checks telles qu’elles y ont été enregistrées. Les deux tables peuvent donc être jointes entre elles : directement sur test_name, avec has(check_names, check_name) et has(commit_shas, commit_sha) pour les colonnes qui regroupent plusieurs lignes de checks dans un tableau, et avec offending_pull_request_number = pull_request_number pour la pull request incriminée. L’historique des éléments examinés par le job, de ses conclusions et des actions qu’il a effectuées peut être interrogé sur play.clickhouse.com :
Le job est implémenté dans ci/jobs/revert_ci_regressions.py et s’exécute dans le cadre du workflow Hourly. L’exécuter avec --dry-run examine et évalue chaque garde-fou, sans rien modifier : ni table, ni lignes, ni branche, ni pull request, ni fusion ; les lignes qui auraient été écrites sont affichées à la place. Un workflow distinct, .github/workflows/revert_broken_prs.yml, annule les fusions intégrées alors que leur propre intégration continue était en échec ; tous deux utilisent le même nom de branche revert-<pull request number>, de sorte qu’une pull request n’est jamais annulée deux fois. Une annulation lancée manuellement est également prise en compte : le job s’abstient si l’annulation est déjà sur master, si une branche nommée revert-<pull request number> ou revert-<pull request number>-<branch> (ce que crée le bouton Revert sur GitHub) existe, ou si une pull request provenant d’une telle branche est ouverte ou fusionnée.
Dernière modification le 18 août 2026