mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2026-10-28 16:18:23 +08:00
Reverts https://github.com/ClickHouse/ClickHouse/pull/125587. The macOS fleet grew from 10 to 21 runners; 50 parallel copies started without waiting for a runner and left no orphaned processes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
348 lines
14 KiB
Python
348 lines
14 KiB
Python
from praktika import Workflow
|
|
|
|
from ci.defs.defs import (
|
|
BASE_BRANCH,
|
|
DOCKERS,
|
|
SECRETS,
|
|
ArtifactConfigs,
|
|
JobNames,
|
|
)
|
|
from ci.defs.job_configs import JobConfigs
|
|
from ci.jobs.scripts.workflow_hooks.filter_job import (
|
|
PR_SINGLE_ARCH_SKIPPED_BUILDS,
|
|
PR_SINGLE_ARCH_SKIPPED_JOBS,
|
|
should_skip_job,
|
|
)
|
|
from ci.jobs.scripts.workflow_hooks.trusted import can_be_tested
|
|
|
|
# PR sanitizer jobs repeat tests related to the change to find intermittent failures.
|
|
# Debug and plain binary jobs run the full suite. Master keeps the full suite in
|
|
# every configuration; coverage-based targeting is specific to pull requests.
|
|
FUNCTIONAL_TESTS_JOBS = JobConfigs.functional_tests_pr_jobs
|
|
|
|
ALL_FUNCTIONAL_TESTS = [job.name for job in FUNCTIONAL_TESTS_JOBS]
|
|
|
|
CORE_BLOCKING_JOB_NAMES = [
|
|
job.name
|
|
for job in FUNCTIONAL_TESTS_JOBS
|
|
if any(
|
|
substr in job.name
|
|
for substr in (
|
|
"_debug, parallel",
|
|
"_binary, parallel",
|
|
"_binary, sequential",
|
|
"_asan_ubsan, db disk, distributed plan, targeted",
|
|
)
|
|
)
|
|
] + [
|
|
job.name
|
|
for job in JobConfigs.integration_test_targeted_pr_jobs
|
|
if "_asan_ubsan, db disk, targeted" in job.name
|
|
] + [
|
|
job.name
|
|
for job in JobConfigs.unittest_jobs
|
|
]
|
|
|
|
STYLE_AND_FAST_TESTS = [
|
|
JobNames.STYLE_CHECK,
|
|
JobNames.FAST_TEST,
|
|
*[j.name for j in JobConfigs.tidy_build_arm_jobs],
|
|
]
|
|
|
|
CODE_REVIEW_BLOCKING_JOBS = [
|
|
JobNames.STYLE_CHECK,
|
|
JobNames.FAST_TEST,
|
|
]
|
|
|
|
REGULAR_BUILD_NAMES = [job.name for job in JobConfigs.build_jobs]
|
|
|
|
PLAIN_FUNCTIONAL_TEST_JOB = [
|
|
j for j in JobConfigs.functional_tests_jobs if "amd_debug, parallel" in j.name
|
|
][0]
|
|
|
|
# Pull requests run the integration tests only in targeted jobs (the changed tests, the
|
|
# tests covering the changed lines and the tests that failed in the PR before, each run
|
|
# once), except for the full `arm_binary` run below and, with the `ci-coverage` or
|
|
# `ci-llvm-coverage` label, the full LLVM coverage run and the tests excluded from it.
|
|
INTEGRATION_TARGETED_JOBS = JobConfigs.integration_test_targeted_pr_jobs
|
|
|
|
# The LLVM coverage jobs run in pull requests only with the `ci-coverage` or `ci-llvm-coverage`
|
|
# label (see `should_skip_job`); by default these `arm_binary` jobs run the same configurations instead.
|
|
# Master runs the coverage jobs on every commit.
|
|
FUNCTIONAL_COVERAGE_REPLACEMENT_JOBS = (
|
|
JobConfigs.functional_tests_arm_binary_coverage_replacement_pr_jobs
|
|
)
|
|
INTEGRATION_COVERAGE_REPLACEMENT_JOBS = (
|
|
JobConfigs.integration_test_arm_binary_coverage_replacement_pr_jobs
|
|
)
|
|
|
|
PLAIN_INTEGRATION_TEST_JOB = [
|
|
j for j in INTEGRATION_TARGETED_JOBS if "(amd_tsan, targeted)" in j.name
|
|
][0]
|
|
|
|
workflow = Workflow.Config(
|
|
name="PR",
|
|
event=Workflow.Event.PULL_REQUEST,
|
|
base_branches=[BASE_BRANCH],
|
|
engine=Workflow.Engine.GH_ACTIONS,
|
|
jobs=[
|
|
JobConfigs.style_check,
|
|
JobConfigs.code_review.set_run_after(CODE_REVIEW_BLOCKING_JOBS),
|
|
JobConfigs.docs_job_mintlify,
|
|
JobConfigs.fast_test,
|
|
*JobConfigs.darwin_fast_test_jobs,
|
|
*JobConfigs.tidy_build_arm_jobs,
|
|
*[job.set_run_after(STYLE_AND_FAST_TESTS) for job in JobConfigs.build_jobs],
|
|
*[
|
|
job.set_run_after(STYLE_AND_FAST_TESTS)
|
|
for job in JobConfigs.extra_validation_build_jobs
|
|
],
|
|
*[
|
|
job.set_run_after(REGULAR_BUILD_NAMES)
|
|
for job in JobConfigs.release_build_jobs_with_examples
|
|
],
|
|
*[
|
|
job.set_run_after(CORE_BLOCKING_JOB_NAMES)
|
|
for job in JobConfigs.special_build_jobs
|
|
],
|
|
# Gated like the regular builds rather than like the special ones: it is the only job
|
|
# that compiles the standalone parser at all, and it needs no build artifact, so there
|
|
# is nothing to gain by deferring it behind the functional tests.
|
|
*[
|
|
job.set_run_after(STYLE_AND_FAST_TESTS)
|
|
for job in JobConfigs.wasm_parser_build_jobs
|
|
],
|
|
*[
|
|
job.set_run_after(STYLE_AND_FAST_TESTS)
|
|
for job in JobConfigs.build_llvm_coverage_job
|
|
],
|
|
# TODO: stabilize new jobs and remove set_allow_failure
|
|
JobConfigs.lightweight_functional_tests_job,
|
|
*[j.set_allow_failure() for j in JobConfigs.stateless_tests_targeted_pr_jobs],
|
|
*[
|
|
job.set_run_after(
|
|
CORE_BLOCKING_JOB_NAMES if job.name not in CORE_BLOCKING_JOB_NAMES else []
|
|
)
|
|
for job in INTEGRATION_TARGETED_JOBS
|
|
],
|
|
*[
|
|
job.set_run_after(CORE_BLOCKING_JOB_NAMES)
|
|
for job in JobConfigs.integration_test_contrib_tsan_pr_jobs
|
|
],
|
|
JobConfigs.ast_fuzzer_targeted_pr_jobs[0].set_allow_failure(),
|
|
JobConfigs.ast_fuzzer_targeted_pr_jobs[1].set_allow_failure(),
|
|
*JobConfigs.stateless_tests_flaky_pr_jobs,
|
|
# The merge queue's non-sanitizer flaky check also runs here, so a test
|
|
# that is only too slow (or only flaky) without a sanitizer is reported
|
|
# in the PR rather than first bouncing it from the merge queue. Same job
|
|
# config as in `ci/workflows/merge_queue.py`.
|
|
*JobConfigs.stateless_tests_flaky_mq_jobs,
|
|
*JobConfigs.integration_test_asan_flaky_pr_jobs,
|
|
# Per-arch Bugfix Validation Checks (functional + integration tests on
|
|
# both amd64 and aarch64). Each per-arch variant has
|
|
# `allow_failure=True` so an individual FAIL doesn't block PR merge -
|
|
# the aggregate decision (validate iff at least one arch passed) lives
|
|
# in the `new_tests_check.py` workflow post-hook below.
|
|
*[
|
|
job.set_run_after(CORE_BLOCKING_JOB_NAMES)
|
|
for job in JobConfigs.bugfix_validation_ft_pr_jobs
|
|
],
|
|
*[
|
|
job.set_run_after(CORE_BLOCKING_JOB_NAMES)
|
|
for job in JobConfigs.bugfix_validation_it_jobs
|
|
],
|
|
# Unit-test (gtest) bugfix validation: a single AMD-only job (allow_failure)
|
|
# that builds a merge-base "before" binary and runs the touched suite against it.
|
|
# It is not part of the per-arch FT/IT aggregation; instead new_tests_check.py
|
|
# blocks the unit case iff this job reported a definitive FAIL (failed to
|
|
# reproduce) — a reproduction or an inconclusive ERROR does not block.
|
|
# Like the sibling FT/IT jobs, it is deferred behind the core blocking jobs.
|
|
JobConfigs.bugfix_validation_ut_job.set_run_after(CORE_BLOCKING_JOB_NAMES),
|
|
*[
|
|
j.set_run_after(
|
|
CORE_BLOCKING_JOB_NAMES if j.name not in CORE_BLOCKING_JOB_NAMES else []
|
|
)
|
|
for j in FUNCTIONAL_TESTS_JOBS
|
|
],
|
|
*[
|
|
job.set_run_after(CORE_BLOCKING_JOB_NAMES)
|
|
for job in JobConfigs.functional_tests_jobs_azure
|
|
],
|
|
*[
|
|
job.set_run_after(CORE_BLOCKING_JOB_NAMES)
|
|
for job in FUNCTIONAL_COVERAGE_REPLACEMENT_JOBS
|
|
],
|
|
*[
|
|
job.set_run_after(CORE_BLOCKING_JOB_NAMES)
|
|
for job in INTEGRATION_COVERAGE_REPLACEMENT_JOBS
|
|
],
|
|
*[
|
|
job.set_run_after(CORE_BLOCKING_JOB_NAMES)
|
|
for job in JobConfigs.functional_test_llvm_coverage_jobs
|
|
],
|
|
*[
|
|
job.set_run_after(CORE_BLOCKING_JOB_NAMES)
|
|
for job in JobConfigs.functional_test_excluded_from_llvm_job
|
|
],
|
|
*[
|
|
job.set_run_after(CORE_BLOCKING_JOB_NAMES)
|
|
for job in JobConfigs.integration_test_llvm_coverage_jobs
|
|
],
|
|
*[
|
|
job.set_run_after(CORE_BLOCKING_JOB_NAMES)
|
|
for job in JobConfigs.integration_test_excluded_from_llvm_job
|
|
],
|
|
*JobConfigs.unittest_jobs,
|
|
*[
|
|
job.set_run_after(CORE_BLOCKING_JOB_NAMES)
|
|
for job in JobConfigs.unittest_llvm_coverage_job
|
|
],
|
|
JobConfigs.docker_server.set_run_after(CORE_BLOCKING_JOB_NAMES),
|
|
JobConfigs.docker_keeper.set_run_after(CORE_BLOCKING_JOB_NAMES),
|
|
*[
|
|
job.set_run_after(CORE_BLOCKING_JOB_NAMES)
|
|
for job in JobConfigs.install_check_jobs
|
|
],
|
|
*[
|
|
job.set_run_after(CORE_BLOCKING_JOB_NAMES)
|
|
for job in JobConfigs.compatibility_test_jobs
|
|
],
|
|
*[
|
|
job.set_run_after(CORE_BLOCKING_JOB_NAMES)
|
|
for job in JobConfigs.stress_test_jobs
|
|
],
|
|
*[
|
|
job.set_run_after(CORE_BLOCKING_JOB_NAMES)
|
|
for job in JobConfigs.upgrade_test_jobs
|
|
],
|
|
*[
|
|
job.set_run_after(CORE_BLOCKING_JOB_NAMES)
|
|
for job in JobConfigs.ast_fuzzer_jobs
|
|
],
|
|
*[
|
|
job.set_run_after(CORE_BLOCKING_JOB_NAMES)
|
|
for job in JobConfigs.buzz_fuzzer_jobs
|
|
],
|
|
*[
|
|
job.set_run_after(CORE_BLOCKING_JOB_NAMES)
|
|
for job in JobConfigs.performance_comparison_with_master_head_jobs
|
|
],
|
|
JobConfigs.parser_memory_check_job,
|
|
JobConfigs.storage_memory_check_job,
|
|
# ClickBench runs on PRs only when files in its digest change
|
|
# (see `clickbench_jobs.digest_config`), so the cost is bounded.
|
|
*[
|
|
job.set_run_after(CORE_BLOCKING_JOB_NAMES)
|
|
for job in JobConfigs.clickbench_jobs
|
|
],
|
|
JobConfigs.llvm_coverage_job,
|
|
# Waits for the integration jobs of this workflow, which upload the compliance results.
|
|
# The full `arm_binary` run (or, with `ci-coverage`, the LLVM coverage run) is the one that
|
|
# always runs the compliance suite.
|
|
JobConfigs.promql_compliance_job.set_run_after(
|
|
INTEGRATION_TARGETED_JOBS
|
|
+ INTEGRATION_COVERAGE_REPLACEMENT_JOBS
|
|
+ JobConfigs.integration_test_llvm_coverage_jobs
|
|
+ JobConfigs.integration_test_excluded_from_llvm_job,
|
|
reset=True,
|
|
),
|
|
# TODO: stabilize and remove set_allow_failure
|
|
JobConfigs.build_profile_diff_job.set_allow_failure(),
|
|
JobConfigs.sqllogic_test_master_job.set_run_after(CORE_BLOCKING_JOB_NAMES),
|
|
JobConfigs.sqlstorm_test_job.set_run_after(CORE_BLOCKING_JOB_NAMES),
|
|
JobConfigs.docs_examples_job.set_run_after(CORE_BLOCKING_JOB_NAMES),
|
|
# Keeper stress (PR): 3 no-fault scenarios (prod-mix, read-multi, write-multi),
|
|
# default backend only, 15 min each. Runs when src/Coordination or stress test files change.
|
|
JobConfigs.keeper_stress_job.set_name("Keeper Stress Tests (PR)").set_timeout(
|
|
3 * 3600
|
|
),
|
|
*JobConfigs.toolchain_build_jobs,
|
|
],
|
|
artifacts=[
|
|
*ArtifactConfigs.unittests_binaries,
|
|
*ArtifactConfigs.clickhouse_binaries,
|
|
*ArtifactConfigs.clickhouse_darwin_plain_binaries,
|
|
*ArtifactConfigs.clickhouse_debians,
|
|
*ArtifactConfigs.clickhouse_rpms,
|
|
*ArtifactConfigs.clickhouse_tgzs,
|
|
ArtifactConfigs.clickhouse_wasm,
|
|
ArtifactConfigs.wasm_parser,
|
|
ArtifactConfigs.fuzzers,
|
|
ArtifactConfigs.fuzzers_corpus,
|
|
ArtifactConfigs.clickhouse_examples,
|
|
*ArtifactConfigs.llvm_profdata_file,
|
|
ArtifactConfigs.llvm_coverage_info_file,
|
|
ArtifactConfigs.toolchain_pgo_bolt_amd,
|
|
ArtifactConfigs.toolchain_pgo_bolt_arm,
|
|
],
|
|
dockers=DOCKERS,
|
|
enable_dockers_manifest_merge=True,
|
|
secrets=SECRETS,
|
|
enable_job_filtering_by_changes=True,
|
|
enable_cache=True,
|
|
enable_report=True,
|
|
enable_cidb=True,
|
|
enable_merge_ready_status=True,
|
|
enable_gh_summary_comment=True,
|
|
enable_commit_status_on_failure=False,
|
|
enable_open_issues_check=True,
|
|
enable_slack_feed=True,
|
|
pre_hooks=[
|
|
can_be_tested,
|
|
"python3 ./ci/jobs/scripts/workflow_hooks/ci_links.py",
|
|
"python3 ./ci/jobs/scripts/workflow_hooks/store_data.py",
|
|
"python3 ./ci/jobs/scripts/workflow_hooks/pr_labels_and_category.py",
|
|
"python3 ./ci/jobs/scripts/workflow_hooks/version_log.py",
|
|
"python3 ./ci/jobs/scripts/workflow_hooks/team_notifications.py",
|
|
],
|
|
workflow_filter_hooks=[should_skip_job],
|
|
post_hooks=[
|
|
"python3 ./ci/jobs/scripts/workflow_hooks/pr_body_check.py",
|
|
"python3 ./ci/jobs/scripts/workflow_hooks/feature_docs.py",
|
|
"python3 ./ci/jobs/scripts/workflow_hooks/new_tests_check.py",
|
|
"python3 ./ci/jobs/scripts/workflow_hooks/can_be_merged.py",
|
|
"python3 ./ci/jobs/scripts/workflow_hooks/check_report_messages.py",
|
|
],
|
|
job_aliases={
|
|
# plain integration test job, no dist plan; runs `--test` as a regular job locally
|
|
"integration": PLAIN_INTEGRATION_TEST_JOB.name,
|
|
"fast": "Fast test",
|
|
"functional": PLAIN_FUNCTIONAL_TEST_JOB.name,
|
|
"build_debug": "Build (amd_debug)",
|
|
"build": "Build (amd_binary)",
|
|
},
|
|
runs_on_label_prefix="pr-",
|
|
ai_orchestrator=Workflow.OrchestratorAI.Config(
|
|
enabled=False,
|
|
provider="bedrock",
|
|
model="global.anthropic.claude-sonnet-5",
|
|
),
|
|
)
|
|
|
|
# `should_skip_job` skips these builds together with the stress tests that use them, so
|
|
# no other job may require their binaries: it would find no artifact to download.
|
|
_SINGLE_ARCH_SKIPPED_ARTIFACTS = {
|
|
artifact
|
|
for job in workflow.jobs
|
|
if job.name in PR_SINGLE_ARCH_SKIPPED_BUILDS
|
|
for artifact in job.provides
|
|
}
|
|
assert len(_SINGLE_ARCH_SKIPPED_ARTIFACTS) == len(PR_SINGLE_ARCH_SKIPPED_BUILDS), (
|
|
"every build in PR_SINGLE_ARCH_SKIPPED_BUILDS must be in the PR workflow"
|
|
)
|
|
_SINGLE_ARCH_SKIPPED_ARTIFACT_USERS = [
|
|
job.name
|
|
for job in workflow.jobs
|
|
if job.name not in PR_SINGLE_ARCH_SKIPPED_JOBS
|
|
and _SINGLE_ARCH_SKIPPED_ARTIFACTS & set(job.requires or [])
|
|
]
|
|
assert not _SINGLE_ARCH_SKIPPED_ARTIFACT_USERS, (
|
|
f"jobs {_SINGLE_ARCH_SKIPPED_ARTIFACT_USERS} require binaries of "
|
|
f"{PR_SINGLE_ARCH_SKIPPED_BUILDS}, which pull requests skip: remove the build "
|
|
"from PR_SINGLE_ARCH_SKIPPED_BUILDS in ci/jobs/scripts/workflow_hooks/filter_job.py"
|
|
)
|
|
|
|
WORKFLOWS = [
|
|
workflow,
|
|
]
|