Skip to content

Commit d42ee9c

Browse files
committed
Merge branch 'master' into vdimir/client-context-race
2 parents a03b4a5 + 3e6b62f commit d42ee9c

File tree

247 files changed

+3372
-1399
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

247 files changed

+3372
-1399
lines changed

ci/docker/fasttest/Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ RUN apt-get update \
3333
# moreutils - provides ts fo FT
3434
# expect, bzip2 - requried by FT
3535
# bsdmainutils - provides hexdump for FT
36+
# nasm - nasm copiler for one of submodules, required from normal build
37+
# yasm - asssembler for libhdfs3, required from normal build
3638

3739
RUN apt-get update \
3840
&& apt-get install \
@@ -53,6 +55,8 @@ RUN apt-get update \
5355
pv \
5456
jq \
5557
bzip2 \
58+
nasm \
59+
yasm \
5660
--yes --no-install-recommends \
5761
&& apt-get clean \
5862
&& rm -rf /var/lib/apt/lists/* /var/cache/debconf /tmp/*

ci/jobs/build_clickhouse.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import argparse
2+
3+
from praktika.result import Result
4+
from praktika.settings import Settings
5+
from praktika.utils import MetaClasses, Shell, Utils
6+
7+
8+
class JobStages(metaclass=MetaClasses.WithIter):
9+
CHECKOUT_SUBMODULES = "checkout"
10+
CMAKE = "cmake"
11+
BUILD = "build"
12+
13+
14+
def parse_args():
15+
parser = argparse.ArgumentParser(description="ClickHouse Build Job")
16+
parser.add_argument("BUILD_TYPE", help="Type: <amd|arm_debug|release_sanitizer>")
17+
parser.add_argument("--param", help="Optional custom job start stage", default=None)
18+
return parser.parse_args()
19+
20+
21+
def main():
22+
23+
args = parse_args()
24+
25+
stop_watch = Utils.Stopwatch()
26+
27+
stages = list(JobStages)
28+
stage = args.param or JobStages.CHECKOUT_SUBMODULES
29+
if stage:
30+
assert stage in JobStages, f"--param must be one of [{list(JobStages)}]"
31+
print(f"Job will start from stage [{stage}]")
32+
while stage in stages:
33+
stages.pop(0)
34+
stages.insert(0, stage)
35+
36+
cmake_build_type = "Release"
37+
sanitizer = ""
38+
39+
if "debug" in args.BUILD_TYPE.lower():
40+
print("Build type set: debug")
41+
cmake_build_type = "Debug"
42+
43+
if "asan" in args.BUILD_TYPE.lower():
44+
print("Sanitizer set: address")
45+
sanitizer = "address"
46+
47+
# if Environment.is_local_run():
48+
# build_cache_type = "disabled"
49+
# else:
50+
build_cache_type = "sccache"
51+
52+
current_directory = Utils.cwd()
53+
build_dir = f"{Settings.TEMP_DIR}/build"
54+
55+
res = True
56+
results = []
57+
58+
if res and JobStages.CHECKOUT_SUBMODULES in stages:
59+
Shell.check(f"rm -rf {build_dir} && mkdir -p {build_dir}")
60+
results.append(
61+
Result.create_from_command_execution(
62+
name="Checkout Submodules",
63+
command=f"git submodule sync --recursive && git submodule init && git submodule update --depth 1 --recursive --jobs {min([Utils.cpu_count(), 20])}",
64+
)
65+
)
66+
res = results[-1].is_ok()
67+
68+
if res and JobStages.CMAKE in stages:
69+
results.append(
70+
Result.create_from_command_execution(
71+
name="Cmake configuration",
72+
command=f"cmake --debug-trycompile -DCMAKE_VERBOSE_MAKEFILE=1 -LA -DCMAKE_BUILD_TYPE={cmake_build_type} \
73+
-DSANITIZE={sanitizer} -DENABLE_CHECK_HEAVY_BUILDS=1 -DENABLE_CLICKHOUSE_SELF_EXTRACTING=1 -DENABLE_TESTS=0 \
74+
-DENABLE_UTILS=0 -DCMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY=ON -DCMAKE_INSTALL_PREFIX=/usr \
75+
-DCMAKE_INSTALL_SYSCONFDIR=/etc -DCMAKE_INSTALL_LOCALSTATEDIR=/var -DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=ON \
76+
-DCMAKE_C_COMPILER=clang-18 -DCMAKE_CXX_COMPILER=clang++-18 -DCOMPILER_CACHE={build_cache_type} -DENABLE_TESTS=1 \
77+
-DENABLE_BUILD_PROFILING=1 {current_directory}",
78+
workdir=build_dir,
79+
with_log=True,
80+
)
81+
)
82+
res = results[-1].is_ok()
83+
84+
if res and JobStages.BUILD in stages:
85+
Shell.check("sccache --show-stats")
86+
results.append(
87+
Result.create_from_command_execution(
88+
name="Build ClickHouse",
89+
command="ninja clickhouse-bundle clickhouse-odbc-bridge clickhouse-library-bridge",
90+
workdir=build_dir,
91+
with_log=True,
92+
)
93+
)
94+
Shell.check("sccache --show-stats")
95+
Shell.check(f"ls -l {build_dir}/programs/")
96+
res = results[-1].is_ok()
97+
98+
Result.create_from(results=results, stopwatch=stop_watch).finish_job_accordingly()
99+
100+
101+
if __name__ == "__main__":
102+
main()

ci/jobs/check_style.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def check_duplicate_includes(file_path):
6868
def check_whitespaces(file_paths):
6969
for file in file_paths:
7070
exit_code, out, err = Shell.get_res_stdout_stderr(
71-
f'./ci_v2/jobs/scripts/check_style/double_whitespaces.pl "{file}"',
71+
f'./ci/jobs/scripts/check_style/double_whitespaces.pl "{file}"',
7272
verbose=False,
7373
)
7474
if out or err:
@@ -174,7 +174,7 @@ def check_broken_links(path, exclude_paths):
174174

175175
def check_cpp_code():
176176
res, out, err = Shell.get_res_stdout_stderr(
177-
"./ci_v2/jobs/scripts/check_style/check_cpp.sh"
177+
"./ci/jobs/scripts/check_style/check_cpp.sh"
178178
)
179179
if err:
180180
out += err
@@ -183,7 +183,7 @@ def check_cpp_code():
183183

184184
def check_repo_submodules():
185185
res, out, err = Shell.get_res_stdout_stderr(
186-
"./ci_v2/jobs/scripts/check_style/check_submodules.sh"
186+
"./ci/jobs/scripts/check_style/check_submodules.sh"
187187
)
188188
if err:
189189
out += err
@@ -192,7 +192,7 @@ def check_repo_submodules():
192192

193193
def check_other():
194194
res, out, err = Shell.get_res_stdout_stderr(
195-
"./ci_v2/jobs/scripts/check_style/checks_to_refactor.sh"
195+
"./ci/jobs/scripts/check_style/checks_to_refactor.sh"
196196
)
197197
if err:
198198
out += err
@@ -201,7 +201,7 @@ def check_other():
201201

202202
def check_codespell():
203203
res, out, err = Shell.get_res_stdout_stderr(
204-
"./ci_v2/jobs/scripts/check_style/check_typos.sh"
204+
"./ci/jobs/scripts/check_style/check_typos.sh"
205205
)
206206
if err:
207207
out += err
@@ -210,7 +210,7 @@ def check_codespell():
210210

211211
def check_aspell():
212212
res, out, err = Shell.get_res_stdout_stderr(
213-
"./ci_v2/jobs/scripts/check_style/check_aspell.sh"
213+
"./ci/jobs/scripts/check_style/check_aspell.sh"
214214
)
215215
if err:
216216
out += err
@@ -219,7 +219,7 @@ def check_aspell():
219219

220220
def check_mypy():
221221
res, out, err = Shell.get_res_stdout_stderr(
222-
"./ci_v2/jobs/scripts/check_style/check-mypy"
222+
"./ci/jobs/scripts/check_style/check-mypy"
223223
)
224224
if err:
225225
out += err
@@ -228,7 +228,7 @@ def check_mypy():
228228

229229
def check_pylint():
230230
res, out, err = Shell.get_res_stdout_stderr(
231-
"./ci_v2/jobs/scripts/check_style/check-pylint"
231+
"./ci/jobs/scripts/check_style/check-pylint"
232232
)
233233
if err:
234234
out += err

ci/jobs/fast_test.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1+
import argparse
12
import threading
23
from pathlib import Path
34

4-
from ci_v2.jobs.scripts.functional_tests_results import FTResultsProcessor
5-
from praktika.environment import Environment
65
from praktika.result import Result
76
from praktika.settings import Settings
87
from praktika.utils import MetaClasses, Shell, Utils
98

9+
from ci.jobs.scripts.functional_tests_results import FTResultsProcessor
10+
1011

1112
class ClickHouseProc:
1213
def __init__(self):
@@ -208,11 +209,18 @@ class JobStages(metaclass=MetaClasses.WithIter):
208209
TEST = "test"
209210

210211

212+
def parse_args():
213+
parser = argparse.ArgumentParser(description="ClickHouse Fast Test Job")
214+
parser.add_argument("--param", help="Optional custom job start stage", default=None)
215+
return parser.parse_args()
216+
217+
211218
def main():
219+
args = parse_args()
212220
stop_watch = Utils.Stopwatch()
213221

214222
stages = list(JobStages)
215-
stage = Environment.LOCAL_RUN_PARAM or JobStages.CHECKOUT_SUBMODULES
223+
stage = args.param or JobStages.CHECKOUT_SUBMODULES
216224
if stage:
217225
assert stage in JobStages, f"--param must be one of [{list(JobStages)}]"
218226
print(f"Job will start from stage [{stage}]")

ci/jobs/scripts/check_style/check_cpp.sh

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -52,26 +52,6 @@ find $ROOT_PATH/{src,base,programs,utils} -name '*.h' -or -name '*.cpp' 2>/dev/n
5252
# Broken symlinks
5353
find -L $ROOT_PATH -type l 2>/dev/null | grep -v contrib && echo "^ Broken symlinks found"
5454

55-
# Duplicated or incorrect setting declarations
56-
SETTINGS_FILE=$(mktemp)
57-
ALL_DECLARATION_FILES="
58-
$ROOT_PATH/src/Core/Settings.cpp
59-
$ROOT_PATH/src/Storages/MergeTree/MergeTreeSettings.cpp
60-
$ROOT_PATH/src/Core/FormatFactorySettingsDeclaration.h"
61-
62-
cat $ROOT_PATH/src/Core/Settings.cpp $ROOT_PATH/src/Core/FormatFactorySettingsDeclaration.h | grep "M(" | awk '{print substr($2, 0, length($2) - 1) " Settings" substr($1, 3, length($1) - 3) " SettingsDeclaration" }' | sort | uniq > ${SETTINGS_FILE}
63-
cat $ROOT_PATH/src/Storages/MergeTree/MergeTreeSettings.cpp | grep "M(" | awk '{print substr($2, 0, length($2) - 1) " MergeTreeSettings" substr($1, 3, length($1) - 3) " SettingsDeclaration" }' | sort | uniq >> ${SETTINGS_FILE}
64-
65-
# Check that if there are duplicated settings (declared in different objects) they all have the same type (it's simpler to validate style with that assert)
66-
for setting in $(awk '{print $1 " " $2}' ${SETTINGS_FILE} | sed -e 's/MergeTreeSettings//g' -e 's/Settings//g' | sort | uniq | awk '{ print $1 }' | uniq -d);
67-
do
68-
echo "# Found multiple definitions of setting ${setting} with different types: "
69-
grep --line-number " ${setting}," ${ALL_DECLARATION_FILES} | awk '{print " > " $0 }'
70-
done
71-
72-
# We append all uses of extern found in implementation files to validate them in a single pass and avoid reading the same files over and over
73-
find $ROOT_PATH/{src,base,programs,utils} -name '*.h' -or -name '*.cpp' | xargs grep -e "^\s*extern const Settings" -e "^\s**extern const MergeTreeSettings" -T | awk '{print substr($5, 0, length($5) -1) " " $4 " " substr($1, 0, length($1) - 1)}' >> ${SETTINGS_FILE}
74-
7555
# Duplicated or incorrect setting declarations
7656
bash $ROOT_PATH/utils/check-style/check-settings-style
7757

ci/praktika/_environment.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ class _Environment(MetaClasses.Serializable):
2929
INSTANCE_TYPE: str
3030
INSTANCE_ID: str
3131
INSTANCE_LIFE_CYCLE: str
32+
LOCAL_RUN: bool = False
3233
PARAMETER: Any = None
3334
REPORT_INFO: List[str] = dataclasses.field(default_factory=list)
34-
LOCAL_RUN_PARAM: str = ""
3535
name = "environment"
3636

3737
@classmethod
@@ -185,6 +185,9 @@ def get_report_url(self):
185185
REPORT_URL = f"https://{path}/{Path(Settings.HTML_PAGE_FILE).name}?PR={self.PR_NUMBER}&sha={self.SHA}&name_0={urllib.parse.quote(self.WORKFLOW_NAME, safe='')}&name_1={urllib.parse.quote(self.JOB_NAME, safe='')}"
186186
return REPORT_URL
187187

188+
def is_local_run(self):
189+
return self.LOCAL_RUN
190+
188191

189192
def _to_object(data):
190193
if isinstance(data, dict):

ci/praktika/_settings.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,7 @@ class _Settings:
88
######################################
99
# Pipeline generation settings #
1010
######################################
11-
if Path("./ci_v2").is_dir():
12-
# TODO: hack for CH, remove
13-
CI_PATH = "./ci_v2"
14-
else:
15-
CI_PATH = "./ci"
11+
CI_PATH = "./ci"
1612
WORKFLOW_PATH_PREFIX: str = "./.github/workflows"
1713
WORKFLOWS_DIRECTORY: str = f"{CI_PATH}/workflows"
1814
SETTINGS_DIRECTORY: str = f"{CI_PATH}/settings"

ci/praktika/digest.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import dataclasses
22
import hashlib
3+
import os
34
from hashlib import md5
5+
from pathlib import Path
46
from typing import List
57

68
from praktika import Job
@@ -37,7 +39,9 @@ def calc_job_digest(self, job_config: Job.Config):
3739
sorted=True,
3840
)
3941

40-
print(f"calc digest: hash_key [{cache_key}], include [{included_files}] files")
42+
print(
43+
f"calc digest for job [{job_config.name}]: hash_key [{cache_key}], include [{len(included_files)}] files"
44+
)
4145
# Sort files to ensure consistent hash calculation
4246
included_files.sort()
4347

@@ -91,10 +95,18 @@ def calc_docker_digest(
9195

9296
@staticmethod
9397
def _calc_file_digest(file_path, hash_md5):
94-
# Calculate MD5 hash
95-
with open(file_path, "rb") as f:
98+
# Resolve file path if it's a symbolic link
99+
resolved_path = file_path
100+
if Path(file_path).is_symlink():
101+
resolved_path = os.path.realpath(file_path)
102+
if not Path(resolved_path).is_file():
103+
print(
104+
f"WARNING: No valid file resolved by link {file_path} -> {resolved_path} - skipping digest calculation"
105+
)
106+
return hash_md5.hexdigest()[: Settings.CACHE_DIGEST_LEN]
107+
108+
with open(resolved_path, "rb") as f:
96109
for chunk in iter(lambda: f.read(4096), b""):
97110
hash_md5.update(chunk)
98111

99-
res = hash_md5.hexdigest()[: Settings.CACHE_DIGEST_LEN]
100-
return res
112+
return hash_md5.hexdigest()[: Settings.CACHE_DIGEST_LEN]

0 commit comments

Comments
 (0)