From bff0e5364522ab50297b9b65bf9c4f3821707fc6 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 21 Nov 2025 01:15:32 +0100 Subject: [PATCH] CI build analysis: print log file errors The generated HTML from CI builds so far only shows the number of errors, but not the errors themselves. This is inconvenient, as this means that developers have to go to the logs. This commit modifies AnalyzeBuildLogs(), which already iterates the entire file, to store the lines containing "error:" (as it would be emitted by a compiler). The callers of AnalyzeBuildLogs() now also print the analysis outcome in a more concise manner. Also, change the return parameter of AnalyzeBuildLogs() to a tuple to make the variable handling easier, and remove the unused warnings list. --- ci-scripts/cls_cluster.py | 6 +++--- ci-scripts/cls_containerize.py | 20 +++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/ci-scripts/cls_cluster.py b/ci-scripts/cls_cluster.py index 4e13cdf7b3..8a9919c700 100644 --- a/ci-scripts/cls_cluster.py +++ b/ci-scripts/cls_cluster.py @@ -397,9 +397,9 @@ class Cluster: # Analyze the logs collectInfo = {} for image, lf in log_files: - ret = cls_containerize.AnalyzeBuildLogs(image, lf) - imgStatus = ret['status'] - msg = f"size {imageSize[image]}, analysis of {os.path.basename(lf)}: {ret['errors']} errors, {ret['warnings']} warnings" + imgStatus, errors = cls_containerize.AnalyzeBuildLogs(image, lf) + info = f"Analysis of {os.path.basename(lf)}: {imgStatus=}, size {imageSize[image]}, {len(errors)} errors" + msg = "\n".join([info] + errors) HTML.CreateHtmlTestRowQueue(image, 'OK' if imgStatus else 'KO', [msg]) status = status and imgStatus diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index cd07851319..71e437676c 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -86,9 +86,9 @@ def CreateTag(ranCommitID, ranBranch, ranAllowMerge): return tagToUse def AnalyzeBuildLogs(image, lf): - errorandwarnings = {} committed = False tagged = False + errors = [] with open(lf, mode='r') as inputfile: for line in inputfile: lineHasTag = re.search(f'Successfully tagged {image}:', str(line)) is not None @@ -97,11 +97,13 @@ def AnalyzeBuildLogs(image, lf): # the OpenShift Cluster builder prepends image registry URL lineHasCommit = re.search(r'COMMIT [a-zA-Z0-9\.:/\-]*' + image, str(line)) is not None committed = committed or lineHasCommit - errorandwarnings['errors'] = 0 if committed or tagged else 1 - errorandwarnings['warnings'] = 0 - errorandwarnings['status'] = committed or tagged - logging.info(f"Analyzing {image}, file {lf}: {errorandwarnings}") - return errorandwarnings + if re.search(r'error:|Errors|ERROR', line): + errors.append(f"=> {line.strip()}") + status = (committed or tagged) and len(errors) == 0 + logging.info(f"Analyzing {image}, file {lf}: {status=}, {len(errors)} errors") + for e in errors: + logging.info(e) + return status, errors def GetImageName(ssh, svcName, file): ret = ssh.run(f"docker compose -f {file} config --format json {svcName} | jq -r '.services.\"{svcName}\".image'", silent=True) @@ -460,9 +462,9 @@ class Containerize(): # Analyze the logs for name, lf in log_files: - ret = AnalyzeBuildLogs(name, lf) - imgStatus = ret['status'] - msg = f"size {allImagesSize[name]}, analysis of {os.path.basename(lf)}: {ret['errors']} errors, {ret['warnings']} warnings" + imgStatus, errors = AnalyzeBuildLogs(name, lf) + info = f"Analysis of {os.path.basename(lf)}: {imgStatus=}, size {allImagesSize[name]}, {len(errors)} errors" + msg = "\n".join([info] + errors) HTML.CreateHtmlTestRowQueue(name, 'OK' if imgStatus else 'KO', [msg]) status = status and imgStatus