-
Notifications
You must be signed in to change notification settings - Fork 2.5k
feat(ci): Add public log URLs to build failure reports #14154
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 24 commits
d40c92f
83de133
2449f3c
04b5b46
4e97b32
0809195
3d9eabb
09bd2c2
82fdb6d
42c456f
a1af255
04dad19
8bd3e3d
614f62a
3ba8379
21152aa
eb6d199
7696bc8
02d49bd
605c7e3
26a982e
36f2912
2cea774
aba1f11
54f117f
0953c7d
712cfcc
0fe1384
582bef4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -362,14 +362,15 @@ def _do_test_builds(args, test_image_suffix, end_time, version_tag): | |
| for project, project_builds in sorted(build_ids.items()): | ||
| logging.info(' - %s:', project) | ||
| for build_id, build_type in project_builds: | ||
| logging.info(' - Build ID: %s', build_id) | ||
| logging.info(' - Build Type: %s', build_type) | ||
| logging.info(' GCB URL: %s', | ||
| build_lib.get_gcb_url(build_id, build_lib.IMAGE_PROJECT)) | ||
| for line in build_lib.get_build_info_lines(build_id, | ||
| build_lib.IMAGE_PROJECT): | ||
| logging.info(' %s', line) | ||
| logging.info('-----------------------') | ||
|
|
||
| wait_result = wait_on_builds(build_ids, credentials, build_lib.IMAGE_PROJECT, | ||
| end_time, skipped_projects, version_tag) | ||
| wait_result = wait_on_builds(args, build_ids, credentials, | ||
| build_lib.IMAGE_PROJECT, end_time, | ||
| skipped_projects, version_tag) | ||
|
|
||
| if failed_to_start_builds: | ||
| logging.error( | ||
|
|
@@ -483,7 +484,7 @@ def check_finished(build_id, cloudbuild_api, cloud_project, retries_map): | |
| return build_status | ||
|
|
||
|
|
||
| def wait_on_builds(build_ids, credentials, cloud_project, end_time, | ||
| def wait_on_builds(args, build_ids, credentials, cloud_project, end_time, | ||
| skipped_projects, version_tag): # pylint: disable=too-many-locals | ||
| """Waits on |builds|. Returns True if all builds succeed.""" | ||
| cloudbuild = cloud_build('cloudbuild', | ||
|
|
@@ -544,22 +545,29 @@ def wait_on_builds(build_ids, credentials, cloud_project, end_time, | |
| if status == 'SUCCESS': | ||
| successful_builds[project].append(build_id) | ||
| else: | ||
| logs_url = build_lib.get_gcb_url(build_id, cloud_project) | ||
| failed_builds[project].append((status, logs_url, build_type)) | ||
| gcb_url = build_lib.get_gcb_url(build_id, cloud_project) | ||
| log_url = (f'https://oss-fuzz-gcb-logs.storage.googleapis.com/' | ||
| f'log-{build_id}.txt') | ||
| failed_builds[project].append( | ||
| (status, gcb_url, build_type, log_url)) | ||
|
|
||
| wait_builds[project].remove((build_id, build_type)) | ||
| if not wait_builds[project]: | ||
| del wait_builds[project] | ||
|
|
||
| elif retries_map.get(build_id, 0) >= MAX_RETRIES: | ||
| # Max retries reached, mark as failed. | ||
| logging.error('HttpError for build %s. Max retries reached.', | ||
| build_id) | ||
| if build_id in next_retry_time: | ||
| del next_retry_time[build_id] | ||
|
|
||
| finished_builds_count += 1 | ||
| status = 'UNKNOWN (too many HttpErrors)' | ||
| logs_url = build_lib.get_gcb_url(build_id, cloud_project) | ||
| failed_builds[project].append((status, logs_url, build_type)) | ||
| gcb_url = build_lib.get_gcb_url(build_id, cloud_project) | ||
| log_url = (f'https://oss-fuzz-gcb-logs.storage.googleapis.com/' | ||
|
||
| f'log-{build_id}.txt') | ||
| failed_builds[project].append((status, gcb_url, build_type, log_url)) | ||
| wait_builds[project].remove((build_id, build_type)) | ||
| if not wait_builds[project]: | ||
| del wait_builds[project] | ||
|
|
@@ -570,8 +578,6 @@ def wait_on_builds(build_ids, credentials, cloud_project, end_time, | |
| random.uniform(0, 1)) | ||
| next_retry_time[build_id] = (datetime.datetime.now() + | ||
| datetime.timedelta(seconds=backoff_time)) | ||
| logging.warning('HttpError for build %s. Retrying in %.2f seconds.', | ||
| build_id, backoff_time) | ||
|
|
||
| if not processed_a_build_in_iteration and wait_builds: | ||
| # All remaining builds are in backoff, sleep to prevent busy-waiting. | ||
|
|
@@ -584,9 +590,11 @@ def wait_on_builds(build_ids, credentials, cloud_project, end_time, | |
| if wait_builds: | ||
| for project, project_builds in list(wait_builds.items()): | ||
| for build_id, build_type in project_builds: | ||
| logs_url = build_lib.get_gcb_url(build_id, cloud_project) | ||
| gcb_url = build_lib.get_gcb_url(build_id, cloud_project) | ||
| log_url = (f'https://oss-fuzz-gcb-logs.storage.googleapis.com/' | ||
|
||
| f'log-{build_id}.txt') | ||
| failed_builds[project].append( | ||
| ('TIMEOUT (Coordinator)', logs_url, build_type)) | ||
| ('TIMEOUT (Coordinator)', gcb_url, build_type, log_url)) | ||
|
|
||
| # Final Report | ||
| successful_builds_count = sum( | ||
|
|
@@ -634,17 +642,19 @@ def wait_on_builds(build_ids, credentials, cloud_project, end_time, | |
| logging.error('--- FAILED BUILDS ---') | ||
| for project, failures in sorted(failed_builds.items()): | ||
| logging.error(' - %s:', project) | ||
| for status, gcb_url, build_type in failures: | ||
| for status, gcb_url, build_type, log_url in failures: | ||
| build_id = gcb_url.split('/')[-1].split('?')[0] | ||
| logging.error(' - Build ID: %s', build_id) | ||
| logging.error(' - Build Type: %s', build_type) | ||
| logging.error(' - Status: %s', status) | ||
| logging.error(' - GCB URL: %s', gcb_url) | ||
| for line in build_lib.get_build_info_lines(build_id, cloud_project): | ||
| logging.error(' - %s', line) | ||
| logging.info('-----------------------') | ||
| return False | ||
|
|
||
| if not finished_builds_count and not skipped_builds_count: | ||
| logging.warning('No builds were run.') | ||
| if args.skip_build_images: | ||
| return True | ||
| return False | ||
|
|
||
| logging.info('\nAll builds passed successfully!') | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what sets
_COMMENT_BODY?I cannot find a reference to it anywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My mistake, I thought this was a valid substitution variable. I've refactored the logic to use a simple flag instead, which is more robust and works.