Skip to content

Commit 6ca82ea

Browse files
authored
Merge branch 'antalya' into feature/write_to_merge
2 parents 0924687 + 041337b commit 6ca82ea

File tree

74 files changed

+1795
-387
lines changed

Some content is hidden

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

74 files changed

+1795
-387
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,19 @@ tests/ci/cancel_and_rerun_workflow_lambda/app.py
2222
...
2323

2424
### Documentation entry for user-facing changes
25+
...
2526

26-
27+
#### Exclude tests:
28+
- [ ] <!---ci_exclude_fast--> Fast test
29+
- [ ] <!---ci_exclude_integration--> Integration Tests
30+
- [ ] <!---ci_exclude_stateless--> Stateless tests
31+
- [ ] <!---ci_exclude_stateful--> Stateful tests
32+
- [ ] <!---ci_exclude_performance--> Performance tests
33+
- [ ] <!---ci_exclude_asan--> All with ASAN
34+
- [ ] <!---ci_exclude_tsan--> All with TSAN
35+
- [ ] <!---ci_exclude_msan--> All with MSAN
36+
- [ ] <!---ci_exclude_ubsan--> All with UBSAN
37+
- [ ] <!---ci_exclude_coverage--> All with Coverage
38+
- [ ] <!---ci_exclude_aarch64--> All with Aarch64
39+
- [ ] <!---ci_exclude_regression--> All Regression
40+
- [ ] <!---no_ci_cache--> Disable CI Cache

.github/actions/create_workflow_report/ci_run_report.html.jinja

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,10 @@
150150
<th class="hth no-sort">Commit</th>
151151
<td><a href="https://github.com/{{ github_repo }}/commit/{{ commit_sha }}">{{ commit_sha }}</a></td>
152152
</tr>
153+
<tr>
154+
<th class="hth no-sort">Build Report</th>
155+
<td><a href="https://s3.amazonaws.com/{{ s3_bucket }}/{{ pr_number }}/{{ commit_sha }}/builds/report.html">Build Report</a></td>
156+
</tr>
153157
<tr>
154158
<th class="hth no-sort">Date</th>
155159
<td> {{ date }}</td>
@@ -161,6 +165,7 @@
161165
{% endif %}
162166
<h2>Table of Contents</h2>
163167
<ul>
168+
{%- if pr_number != 0 %}<li><a href="#new-fails-pr">New Fails in PR</a> ({{ counts.pr_new_fails }})</li>{% endif %}
164169
<li><a href="#ci-jobs-status">CI Jobs Status</a> ({{ counts.jobs_status }})</li>
165170
<li><a href="#checks-errors">Checks Errors</a> ({{ counts.checks_errors }})</li>
166171
<li><a href="#checks-fails">Checks New Fails</a> ({{ counts.checks_new_fails }})</li>
@@ -169,6 +174,12 @@
169174
<li><a href="#checks-known-fails">Checks Known Fails</a> ({{ counts.checks_known_fails }})</li>
170175
</ul>
171176

177+
{%- if pr_number != 0 -%}
178+
<h2 id="new-fails-pr">New Fails in PR</h2>
179+
<p> Compared with base sha {{ base_sha }} </p>
180+
{{ new_fails_html }}
181+
{%- endif %}
182+
172183
<h2 id="ci-jobs-status">CI Jobs Status</h2>
173184
{{ ci_jobs_status_html }}
174185

@@ -185,6 +196,12 @@
185196
{{ docker_images_cves_html }}
186197

187198
<h2 id="checks-known-fails">Checks Known Fails</h2>
199+
<p>
200+
Fail reason conventions:<br/>
201+
KNOWN - Accepted fail and fix is not planned<br/>
202+
INVESTIGATE - We don't know why it fails<br/>
203+
NEEDSFIX - Investigation done and a fix is needed to make it pass<br/>
204+
</p>
188205
{{ checks_known_fails_html }}
189206

190207
<script>

.github/actions/create_workflow_report/create_workflow_report.py

Lines changed: 168 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from itertools import combinations
66
import json
77
from datetime import datetime
8+
from functools import lru_cache
89

910
import pandas as pd
1011
from jinja2 import Environment, FileSystemLoader
@@ -124,6 +125,7 @@ def get_pr_info_from_number(pr_number: str) -> dict:
124125
return response.json()
125126

126127

128+
@lru_cache
127129
def get_run_details(run_url: str) -> dict:
128130
"""
129131
Fetch run details for a given run URL.
@@ -151,28 +153,50 @@ def get_checks_fails(client: Client, job_url: str):
151153
Get tests that did not succeed for the given job URL.
152154
Exclude checks that have status 'error' as they are counted in get_checks_errors.
153155
"""
154-
columns = "check_status as job_status, check_name as job_name, test_status, test_name, report_url as results_link"
155-
query = f"""SELECT {columns} FROM `gh-data`.checks
156-
WHERE task_url LIKE '{job_url}%'
157-
AND test_status IN ('FAIL', 'ERROR')
158-
AND check_status!='error'
159-
ORDER BY check_name, test_name
160-
"""
156+
query = f"""SELECT job_status, job_name, status as test_status, test_name, results_link
157+
FROM (
158+
SELECT
159+
argMax(check_status, check_start_time) as job_status,
160+
check_name as job_name,
161+
argMax(test_status, check_start_time) as status,
162+
test_name,
163+
report_url as results_link,
164+
task_url
165+
FROM `gh-data`.checks
166+
GROUP BY check_name, test_name, report_url, task_url
167+
)
168+
WHERE task_url LIKE '{job_url}%'
169+
AND test_status IN ('FAIL', 'ERROR')
170+
AND job_status!='error'
171+
ORDER BY job_name, test_name
172+
"""
161173
return client.query_dataframe(query)
162174

163175

164176
def get_checks_known_fails(client: Client, job_url: str, known_fails: dict):
165177
"""
166178
Get tests that are known to fail for the given job URL.
167179
"""
168-
assert len(known_fails) > 0, "cannot query the database with empty known fails"
169-
columns = "check_status as job_status, check_name as job_name, test_status, test_name, report_url as results_link"
170-
query = f"""SELECT {columns} FROM `gh-data`.checks
171-
WHERE task_url LIKE '{job_url}%'
172-
AND test_status='BROKEN'
173-
AND test_name IN ({','.join(f"'{test}'" for test in known_fails.keys())})
174-
ORDER BY test_name, check_name
175-
"""
180+
if len(known_fails) == 0:
181+
return pd.DataFrame()
182+
183+
query = f"""SELECT job_status, job_name, status as test_status, test_name, results_link
184+
FROM (
185+
SELECT
186+
argMax(check_status, check_start_time) as job_status,
187+
check_name as job_name,
188+
argMax(test_status, check_start_time) as status,
189+
test_name,
190+
report_url as results_link,
191+
task_url
192+
FROM `gh-data`.checks
193+
GROUP BY check_name, test_name, report_url, task_url
194+
)
195+
WHERE task_url LIKE '{job_url}%'
196+
AND test_status='BROKEN'
197+
AND test_name IN ({','.join(f"'{test}'" for test in known_fails.keys())})
198+
ORDER BY job_name, test_name
199+
"""
176200

177201
df = client.query_dataframe(query)
178202

@@ -193,12 +217,22 @@ def get_checks_errors(client: Client, job_url: str):
193217
"""
194218
Get checks that have status 'error' for the given job URL.
195219
"""
196-
columns = "check_status as job_status, check_name as job_name, test_status, test_name, report_url as results_link"
197-
query = f"""SELECT {columns} FROM `gh-data`.checks
198-
WHERE task_url LIKE '{job_url}%'
199-
AND check_status=='error'
200-
ORDER BY check_name, test_name
201-
"""
220+
query = f"""SELECT job_status, job_name, status as test_status, test_name, results_link
221+
FROM (
222+
SELECT
223+
argMax(check_status, check_start_time) as job_status,
224+
check_name as job_name,
225+
argMax(test_status, check_start_time) as status,
226+
test_name,
227+
report_url as results_link,
228+
task_url
229+
FROM `gh-data`.checks
230+
GROUP BY check_name, test_name, report_url, task_url
231+
)
232+
WHERE task_url LIKE '{job_url}%'
233+
AND job_status=='error'
234+
ORDER BY job_name, test_name
235+
"""
202236
return client.query_dataframe(query)
203237

204238

@@ -231,14 +265,14 @@ def get_regression_fails(client: Client, job_url: str):
231265
architecture as arch,
232266
test_name,
233267
argMax(result, start_time) AS status,
234-
job_url,
235268
job_name,
236-
report_url as results_link
269+
report_url as results_link,
270+
job_url
237271
FROM `gh-data`.clickhouse_regression_results
238272
GROUP BY architecture, test_name, job_url, job_name, report_url
239273
ORDER BY length(test_name) DESC
240274
)
241-
WHERE job_url='{job_url}'
275+
WHERE job_url LIKE '{job_url}%'
242276
AND status IN ('Fail', 'Error')
243277
"""
244278
df = client.query_dataframe(query)
@@ -247,6 +281,99 @@ def get_regression_fails(client: Client, job_url: str):
247281
return df
248282

249283

284+
def get_new_fails_this_pr(
285+
client: Client,
286+
pr_info: dict,
287+
checks_fails: pd.DataFrame,
288+
regression_fails: pd.DataFrame,
289+
):
290+
"""
291+
Get tests that failed in the PR but passed in the base branch.
292+
Compares both checks and regression test results.
293+
"""
294+
base_sha = pr_info.get("base", {}).get("sha")
295+
if not base_sha:
296+
raise Exception("No base SHA found for PR")
297+
298+
# Modify tables to have the same columns
299+
if len(checks_fails) > 0:
300+
checks_fails = checks_fails.copy().drop(columns=["job_status"])
301+
if len(regression_fails) > 0:
302+
regression_fails = regression_fails.copy()
303+
regression_fails["job_name"] = regression_fails.apply(
304+
lambda row: f"{row['arch']} {row['job_name']}".strip(), axis=1
305+
)
306+
regression_fails["test_status"] = regression_fails["status"]
307+
308+
# Combine both types of fails and select only desired columns
309+
desired_columns = ["job_name", "test_name", "test_status", "results_link"]
310+
all_pr_fails = pd.concat([checks_fails, regression_fails], ignore_index=True)[
311+
desired_columns
312+
]
313+
if len(all_pr_fails) == 0:
314+
return pd.DataFrame()
315+
316+
# Get all checks from the base branch that didn't fail
317+
base_checks_query = f"""SELECT job_name, status as test_status, test_name, results_link
318+
FROM (
319+
SELECT
320+
check_name as job_name,
321+
argMax(test_status, check_start_time) as status,
322+
test_name,
323+
report_url as results_link,
324+
task_url
325+
FROM `gh-data`.checks
326+
WHERE commit_sha='{base_sha}'
327+
GROUP BY check_name, test_name, report_url, task_url
328+
)
329+
WHERE test_status NOT IN ('FAIL', 'ERROR')
330+
ORDER BY job_name, test_name
331+
"""
332+
base_checks = client.query_dataframe(base_checks_query)
333+
334+
# Get regression results from base branch that didn't fail
335+
base_regression_query = f"""SELECT arch, job_name, status, test_name, results_link
336+
FROM (
337+
SELECT
338+
architecture as arch,
339+
test_name,
340+
argMax(result, start_time) AS status,
341+
job_url,
342+
job_name,
343+
report_url as results_link
344+
FROM `gh-data`.clickhouse_regression_results
345+
WHERE results_link LIKE'%/{base_sha}/%'
346+
GROUP BY architecture, test_name, job_url, job_name, report_url
347+
ORDER BY length(test_name) DESC
348+
)
349+
WHERE status NOT IN ('Fail', 'Error')
350+
"""
351+
base_regression = client.query_dataframe(base_regression_query)
352+
if len(base_regression) > 0:
353+
base_regression["job_name"] = base_regression.apply(
354+
lambda row: f"{row['arch']} {row['job_name']}".strip(), axis=1
355+
)
356+
base_regression["test_status"] = base_regression["status"]
357+
base_regression = base_regression.drop(columns=["arch", "status"])
358+
359+
# Combine base results
360+
base_results = pd.concat([base_checks, base_regression], ignore_index=True)
361+
362+
# Find tests that failed in PR but passed in base
363+
pr_failed_tests = set(zip(all_pr_fails["job_name"], all_pr_fails["test_name"]))
364+
base_passed_tests = set(zip(base_results["job_name"], base_results["test_name"]))
365+
366+
new_fails = pr_failed_tests.intersection(base_passed_tests)
367+
368+
# Filter PR results to only include new fails
369+
mask = all_pr_fails.apply(
370+
lambda row: (row["job_name"], row["test_name"]) in new_fails, axis=1
371+
)
372+
new_fails_df = all_pr_fails[mask]
373+
374+
return new_fails_df
375+
376+
250377
def get_cves(pr_number, commit_sha):
251378
"""
252379
Fetch Grype results from S3.
@@ -304,15 +431,15 @@ def get_cves(pr_number, commit_sha):
304431
def url_to_html_link(url: str) -> str:
305432
if not url:
306433
return ""
307-
text = url.split("/")[-1]
434+
text = url.split("/")[-1].replace("__", "_")
308435
if not text:
309436
text = "results"
310437
return f'<a href="{url}">{text}</a>'
311438

312439

313440
def format_test_name_for_linewrap(text: str) -> str:
314441
"""Tweak the test name to improve line wrapping."""
315-
return text.replace(".py::", "/")
442+
return f'<span style="line-break: anywhere;">{text}</span>'
316443

317444

318445
def format_test_status(text: str) -> str:
@@ -400,6 +527,7 @@ def main():
400527
"job_statuses": get_commit_statuses(args.commit_sha),
401528
"checks_fails": get_checks_fails(db_client, args.actions_run_url),
402529
"checks_known_fails": [],
530+
"pr_new_fails": [],
403531
"checks_errors": get_checks_errors(db_client, args.actions_run_url),
404532
"regression_fails": get_regression_fails(db_client, args.actions_run_url),
405533
"docker_images_cves": (
@@ -427,13 +555,21 @@ def main():
427555
)
428556

429557
if args.pr_number == 0:
430-
pr_info_html = "Release"
558+
run_details = get_run_details(args.actions_run_url)
559+
branch_name = run_details.get("head_branch", "unknown branch")
560+
pr_info_html = f"Release ({branch_name})"
431561
else:
432562
try:
433563
pr_info = get_pr_info_from_number(args.pr_number)
434564
pr_info_html = f"""<a href="https://github.com/{GITHUB_REPO}/pull/{pr_info["number"]}">
435565
#{pr_info.get("number")} ({pr_info.get("base", {}).get('ref')} <- {pr_info.get("head", {}).get('ref')}) {pr_info.get("title")}
436566
</a>"""
567+
fail_results["pr_new_fails"] = get_new_fails_this_pr(
568+
db_client,
569+
pr_info,
570+
fail_results["checks_fails"],
571+
fail_results["regression_fails"],
572+
)
437573
except Exception as e:
438574
pr_info_html = e
439575

@@ -450,9 +586,12 @@ def main():
450586
context = {
451587
"title": "ClickHouse® CI Workflow Run Report",
452588
"github_repo": GITHUB_REPO,
589+
"s3_bucket": S3_BUCKET,
453590
"pr_info_html": pr_info_html,
591+
"pr_number": args.pr_number,
454592
"workflow_id": args.actions_run_url.split("/")[-1],
455593
"commit_sha": args.commit_sha,
594+
"base_sha": "" if args.pr_number == 0 else pr_info.get("base", {}).get("sha"),
456595
"date": f"{datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')} UTC",
457596
"is_preview": args.mark_preview,
458597
"counts": {
@@ -466,6 +605,7 @@ def main():
466605
if not args.known_fails
467606
else len(fail_results["checks_known_fails"])
468607
),
608+
"pr_new_fails": len(fail_results["pr_new_fails"]),
469609
},
470610
"ci_jobs_status_html": format_results_as_html_table(
471611
fail_results["job_statuses"]
@@ -487,6 +627,7 @@ def main():
487627
if not args.known_fails
488628
else format_results_as_html_table(fail_results["checks_known_fails"])
489629
),
630+
"new_fails_html": format_results_as_html_table(fail_results["pr_new_fails"]),
490631
}
491632

492633
# Render the template with the context

.github/workflows/README.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ Results for **the latest** release_workflow scheduled runs.
44

55
| Branch | Status |
66
| ------------ | - |
7-
| **`antalya`** | [![antalya](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml/badge.svg?branch=antalya&event=workflow_dispatch)](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml?query=branch%3Aantalya) |
8-
| **`project-antalya-24.12.2`** | [![project-antalya-24.12.2](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml/badge.svg?branch=project-antalya-24.12.2&event=workflow_dispatch)](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml?query=branch%3Aproject-antalya-24.12.2) |
9-
| **`customizations/22.8.21`** | [![customizations/22.8.21](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml/badge.svg?branch=customizations/22.8.21&event=workflow_dispatch)](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml?query=branch%3Acustomizations/22.8.21) |
10-
| **`customizations/23.3.19`** | [![customizations/23.3.19](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml/badge.svg?branch=customizations/23.3.19&event=workflow_dispatch)](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml?query=branch%3Acustomizations/23.3.19) |
11-
| **`customizations/23.8.16`** | [![customizations/23.8.16](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml/badge.svg?branch=customizations/23.8.16&event=workflow_dispatch)](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml?query=branch%3Acustomizations/23.8.16) |
12-
| **`customizations/24.3.14`** | [![customizations/24.3.14](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml/badge.svg?branch=customizations/24.3.14&event=workflow_dispatch)](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml?query=branch%3Acustomizations/24.3.14) |
13-
| **`customizations/24.8.11`** | [![customizations/24.8.11](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml/badge.svg?branch=customizations/24.8.11&event=workflow_dispatch)](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml?query=branch%3Acustomizations/24.8.11) |
7+
| **`antalya`** | [![antalya](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml/badge.svg?branch=antalya&event=workflow_dispatch)](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml?query=branch%3Aantalya+actor%3Aaltinity-robot) |
8+
| **`customizations/22.8.21`** | [![customizations/22.8.21](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml/badge.svg?branch=customizations/22.8.21&event=workflow_dispatch)](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml?query=branch%3Acustomizations/22.8.21+actor%3Aaltinity-robot) |
9+
| **`customizations/23.3.19`** | [![customizations/23.3.19](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml/badge.svg?branch=customizations/23.3.19&event=workflow_dispatch)](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml?query=branch%3Acustomizations/23.3.19+actor%3Aaltinity-robot) |
10+
| **`customizations/23.8.16`** | [![customizations/23.8.16](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml/badge.svg?branch=customizations/23.8.16&event=workflow_dispatch)](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml?query=branch%3Acustomizations/23.8.16+actor%3Aaltinity-robot) |
11+
| **`customizations/24.3.14`** | [![customizations/24.3.14](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml/badge.svg?branch=customizations/24.3.14&event=workflow_dispatch)](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml?query=branch%3Acustomizations/24.3.14+actor%3Aaltinity-robot) |
12+
| **`customizations/24.8.11`** | [![customizations/24.8.11](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml/badge.svg?branch=customizations/24.8.11&event=workflow_dispatch)](https://github.com/Altinity/ClickHouse/actions/workflows/release_branches.yml?query=branch%3Acustomizations/24.8.11+actor%3Aaltinity-robot) |

0 commit comments

Comments
 (0)