Skip to content

Commit 935e88b

Browse files
authored
ci: read gh's 'no artifact matches' as no step summaries (#2074) (#2075)
1 parent 221e9da commit 935e88b

2 files changed

Lines changed: 45 additions & 3 deletions

File tree

‎tests/project/test_unit_tests_push_reports_2030.py‎

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ def nodes(*runs: 'tuple[str, str, list[tuple[str, ...]]]') -> 'list[dict[str, An
155155
('NOTICE', '', 'The ubuntu-latest label will migrate to Ubuntu 26')])
156156

157157
#: A stand-in ``gh``: ``api graphql -f ...``, the check-suite query, answers
158-
#: ``$FAKE_SUITE_ANSWER``; ``run download`` copies ``$FAKE_ARTIFACTS``' folders;
158+
#: ``$FAKE_SUITE_ANSWER``; ``run download`` copies ``$FAKE_ARTIFACTS``' folders,
159+
#: or, given ``say:TEXT``, fails printing ``TEXT``;
159160
#: both log their arguments to ``$FAKE_SUITE_LOG``. ``api graphql --input -``, the
160161
#: posting script's own calls, goes to the stand-in GitHub beside it.
161162
FAKE_GH = textwrap.dedent('''\
@@ -170,6 +171,9 @@ def nodes(*runs: 'tuple[str, str, list[tuple[str, ...]]]') -> 'list[dict[str, An
170171
if source == 'fail':
171172
print('HTTP 403: Resource not accessible by integration', file=sys.stderr)
172173
sys.exit(1)
174+
if source.startswith('say:'):
175+
print(source[4:], file=sys.stderr)
176+
sys.exit(1)
173177
if not source or not os.listdir(source):
174178
print('no valid artifacts found to download', file=sys.stderr)
175179
sys.exit(1)
@@ -729,6 +733,32 @@ def test_unreadable_summaries_warn(self) -> None:
729733
report)
730734
self.assertIn('::warning title=CI report not written::The job summaries could not be read', stdout)
731735

736+
def test_each_nothing_to_download_wording_is_no_summary(self) -> None:
737+
# #2074: each way gh's pkg/cmd/run/download/download.go says it found nothing.
738+
for text in ('no valid artifacts found to download',
739+
'no artifact matches any of the names or patterns provided',
740+
'no artifact matches any of the names provided'):
741+
with self.subTest(text=text):
742+
outputs, report, stdout = self.report('success', check_runs(GREEN), FAKE_ARTIFACTS=f'say:{text}')
743+
self.assertEqual(outputs['post'], 'true')
744+
self.assertNotIn('Job summaries', report)
745+
self.assertNotIn('could not be read', report)
746+
self.assertNotIn('::warning', stdout)
747+
748+
def test_a_genuine_download_error_still_warns(self) -> None:
749+
# The last holds a wording inside a longer line, which is not gh saying it.
750+
for text in ('error fetching artifacts: HTTP 401: Bad credentials (https://api.github.com/repos/'
751+
'JarryShaw/PyPCAPKit/actions/runs/1/artifacts?per_page=100)',
752+
'error fetching artifacts: HTTP 404: Not Found (https://api.github.com/repos/'
753+
'JarryShaw/PyPCAPKit/actions/runs/1/artifacts?per_page=100)',
754+
'error fetching artifacts: Get "https://api.github.com/repos/JarryShaw/PyPCAPKit/actions/'
755+
'runs/1/artifacts?per_page=100": dial tcp: lookup api.github.com: no such host',
756+
'error downloading job-summary-test-0: unexpected EOF (not: no valid artifacts found to download)'):
757+
with self.subTest(text=text):
758+
_, report, stdout = self.report('success', check_runs(GREEN), FAKE_ARTIFACTS=f'say:{text}')
759+
self.assertIn(f'The job summaries could not be read: `{text}`.', report)
760+
self.assertIn('::warning title=CI report not written::The job summaries could not be read', stdout)
761+
732762

733763
class TestTheDownload(unittest.TestCase):
734764
""":func:`check_suite_report.download` reads each artifact's folder, and one unpacked in place."""

‎util/check_suite_report.py‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,15 @@ class Workflow(NamedTuple):
128128
ARTIFACT = 'job-summary-*'
129129
SHA = re.compile(r'[0-9a-f]{40}')
130130
RUN_PAGE = re.compile(r'https://[\w.-]+/[\w.-]+/[\w.-]+/actions/runs/\d+')
131+
#: What ``gh run download`` says, failing, where it found nothing to download, as
132+
#: :file:`pkg/cmd/run/download/download.go` in cli/cli writes each (#2074): a run
133+
#: with no artifact that has not expired, and one with none :data:`ARTIFACT`
134+
#: matches, worded the latter way since gh 2.11.0 and the former before it.
135+
NOTHING = frozenset({
136+
'no valid artifacts found to download',
137+
'no artifact matches any of the names or patterns provided',
138+
'no artifact matches any of the names provided',
139+
})
131140
#: A mention, which a summary's text must not make.
132141
MENTION = re.compile(r'@(?=[A-Za-z0-9])')
133142
#: What the report joins its job summaries' blocks by.
@@ -237,8 +246,11 @@ def download(repo: 'str', run_id: 'str', directory: 'pathlib.Path') -> 'tuple[li
237246
return [], f'gh could not run: {error}'
238247
if proc.returncode:
239248
text = proc.stderr.strip() or proc.stdout.strip()
240-
# A run whose jobs wrote no summary uploaded no artifact, which gh reports so.
241-
return [], '' if 'no valid artifacts' in text else (text.splitlines() or ['gh failed'])[-1]
249+
# A run whose jobs wrote no summary uploaded no artifact it matches, which
250+
# gh reports as one of NOTHING's lines; anything else is an error.
251+
if any(line.strip() in NOTHING for line in text.splitlines()):
252+
return [], ''
253+
return [], (text.splitlines() or ['gh failed'])[-1]
242254
found = []
243255
# gh puts each artifact a pattern matches in a folder of its name; a lone
244256
# one unpacked into the directory itself is read there too.

0 commit comments

Comments
 (0)