-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[ci] Include a log download link when test report is truncated #117985
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
Conversation
3933eac
to
64481c6
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
Now "Download" will be a link to the file so people don't have to know to open the build tab and find the download button. This is a URL from a real build: https://buildkite.com/organizations/llvm-project/pipelines/github-pull-requests/builds/123979/jobs/01937132-0fc3-4c95-a884-2fc0048cb9a7/download.txt And this is how we can build it: https://buildkite.com/organizations/{BUILDKITE_ORGANIZATION_SLUG}/pipelines/{BUILDKITE_PIPELINE_SLUG}/builds/{BUILDKITE_BUILD_NUMBER}/jobs/{BUILDKITE_JOB_ID}/download.txt Given these env vars that were set in that job: BUILDKITE_ORGANIZATION_SLUG="llvm-project" BUILDKITE_PIPELINE_SLUG="github-pull-requests" BUILDKITE_BUILD_NUMBER="123979" BUILDKITE_JOB_ID="01937132-0fc3-4c95-a884-2fc0048cb9a7" In theory these will always be available but: 1. Rather safe than sorry with this script, I don't want to make a passing build a failure because this script failed. 2. It would get very annoying if you had to set all these to test the script locally.
c9dd2cf
to
7e9e3f5
Compare
Example build with the link: https://buildkite.com/llvm-project/github-pull-requests/builds/124082 |
@llvm/pr-subscribers-github-workflow Author: David Spickett (DavidSpickett) ChangesNow "Download" will be a link to the file so people don't have to know This is a URL from a real build: Given these env vars that were set in that job: In theory these will always be available but:
Full diff: https://github.com/llvm/llvm-project/pull/117985.diff 1 Files Affected:
diff --git a/.ci/generate_test_report.py b/.ci/generate_test_report.py
index c44936b19dab98..ff601a0cde1063 100644
--- a/.ci/generate_test_report.py
+++ b/.ci/generate_test_report.py
@@ -5,6 +5,7 @@
# python3 -m unittest discover -p generate_test_report.py
import argparse
+import os
import subprocess
import unittest
from io import StringIO
@@ -267,6 +268,46 @@ def test_report_dont_list_failures(self):
),
)
+ def test_report_dont_list_failures_link_to_log(self):
+ self.assertEqual(
+ _generate_report(
+ "Foo",
+ [
+ junit_from_xml(
+ dedent(
+ """\
+ <?xml version="1.0" encoding="UTF-8"?>
+ <testsuites time="0.02">
+ <testsuite name="Bar" tests="1" failures="1" skipped="0" time="0.02">
+ <testcase classname="Bar/test_1" name="test_1" time="0.02">
+ <failure><![CDATA[Output goes here]]></failure>
+ </testcase>
+ </testsuite>
+ </testsuites>"""
+ )
+ )
+ ],
+ list_failures=False,
+ buildkite_info={
+ "BUILDKITE_ORGANIZATION_SLUG": "organization_slug",
+ "BUILDKITE_PIPELINE_SLUG": "pipeline_slug",
+ "BUILDKITE_BUILD_NUMBER": "build_number",
+ "BUILDKITE_JOB_ID": "job_id",
+ },
+ ),
+ (
+ dedent(
+ """\
+ # Foo
+
+ * 1 test failed
+
+ Failed tests and their output was too large to report. [Download](https://buildkite.com/organizations/organization_slug/pipelines/pipeline_slug/builds/build_number/jobs/job_id/download.txt) the build's log file to see the details."""
+ ),
+ "error",
+ ),
+ )
+
def test_report_size_limit(self):
self.assertEqual(
_generate_report(
@@ -308,7 +349,13 @@ def test_report_size_limit(self):
# listed. This minimal report will always fit into an annotation.
# If include failures is False, total number of test will be reported but their names
# and output will not be.
-def _generate_report(title, junit_objects, size_limit=1024 * 1024, list_failures=True):
+def _generate_report(
+ title,
+ junit_objects,
+ size_limit=1024 * 1024,
+ list_failures=True,
+ buildkite_info=None,
+):
if not junit_objects:
return ("", "success")
@@ -354,11 +401,21 @@ def plural(num_tests):
report.append(f"* {tests_failed} {plural(tests_failed)} failed")
if not list_failures:
+ if buildkite_info is not None:
+ log_url = (
+ "https://buildkite.com/organizations/{BUILDKITE_ORGANIZATION_SLUG}/"
+ "pipelines/{BUILDKITE_PIPELINE_SLUG}/builds/{BUILDKITE_BUILD_NUMBER}/"
+ "jobs/{BUILDKITE_JOB_ID}/download.txt".format(**buildkite_info)
+ )
+ download_text = f"[Download]({log_url})"
+ else:
+ download_text = "Download"
+
report.extend(
[
"",
"Failed tests and their output was too large to report. "
- "Download the build's log file to see the details.",
+ f"{download_text} the build's log file to see the details.",
]
)
elif failures:
@@ -381,13 +438,23 @@ def plural(num_tests):
report = "\n".join(report)
if len(report.encode("utf-8")) > size_limit:
- return _generate_report(title, junit_objects, size_limit, list_failures=False)
+ return _generate_report(
+ title,
+ junit_objects,
+ size_limit,
+ list_failures=False,
+ buildkite_info=buildkite_info,
+ )
return report, style
-def generate_report(title, junit_files):
- return _generate_report(title, [JUnitXml.fromfile(p) for p in junit_files])
+def generate_report(title, junit_files, buildkite_info):
+ return _generate_report(
+ title,
+ [JUnitXml.fromfile(p) for p in junit_files],
+ buildkite_info=buildkite_info,
+ )
if __name__ == "__main__":
@@ -399,7 +466,18 @@ def generate_report(title, junit_files):
parser.add_argument("junit_files", help="Paths to JUnit report files.", nargs="*")
args = parser.parse_args()
- report, style = generate_report(args.title, args.junit_files)
+ # All of these are required to build a link to download the log file.
+ env_var_names = [
+ "BUILDKITE_ORGANIZATION_SLUG",
+ "BUILDKITE_PIPELINE_SLUG",
+ "BUILDKITE_BUILD_NUMBER",
+ "BUILDKITE_JOB_ID",
+ ]
+ buildkite_info = {k: v for k, v in os.environ.items() if k in env_var_names}
+ if len(buildkite_info) != len(env_var_names):
+ buildkite_info = None
+
+ report, style = generate_report(args.title, args.junit_files, buildkite_info)
if report:
p = subprocess.Popen(
|
ping! |
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.
LGTM.
Sorry for taking so long on the review. Thanks for the improvement!
Now "Download" will be a link to the file so people don't have to know
to open the build tab and find the download button.
This is a URL from a real build:
https://buildkite.com/organizations/llvm-project/pipelines/github-pull-requests/builds/123979/jobs/01937132-0fc3-4c95-a884-2fc0048cb9a7/download.txt
And this is how we can build it:
https://buildkite.com/organizations/{BUILDKITE_ORGANIZATION_SLUG}/pipelines/{BUILDKITE_PIPELINE_SLUG}/builds/{BUILDKITE_BUILD_NUMBER}/jobs/{BUILDKITE_JOB_ID}/download.txt
Given these env vars that were set in that job:
BUILDKITE_ORGANIZATION_SLUG="llvm-project"
BUILDKITE_PIPELINE_SLUG="github-pull-requests"
BUILDKITE_BUILD_NUMBER="123979"
BUILDKITE_JOB_ID="01937132-0fc3-4c95-a884-2fc0048cb9a7"
In theory these will always be available but:
build a failure because this script failed.
the script locally.