Fail CI when the manual shows a picture no scene makes
The traceability job now runs `tools/manual/record.sh --check`: every picture docs/manual/README.md shows must be made by a scene in tools/manual/scenes.py, and every picture a scene makes must be shown. It reads the two files and nothing else, so it needs no app, display or LFS pull. --changed now dates a scene by the newest commit among its pictures rather than each picture alone. A scene that also makes a picture which re-records byte for byte (panorama-aligned beside panorama.gif) no longer stays listed for ever. A scene all of whose pictures come out identical (launch) stays listed until one differs, which costs one harmless re-run.
This commit is contained in:
@@ -67,6 +67,12 @@ jobs:
|
|||||||
# threshold: zero requirements parsed, zero files scanned, a ratio above
|
# threshold: zero requirements parsed, zero files scanned, a ratio above
|
||||||
# 100%, or any orphan tag all fail the build. A misconfigured run must not
|
# 100%, or any orphan tag all fail the build. A misconfigured run must not
|
||||||
# report a plausible-looking 0%.
|
# report a plausible-looking 0%.
|
||||||
|
# Every picture the manual shows is made by a scene in
|
||||||
|
# tools/manual/scenes.py, and every picture a scene makes is shown.
|
||||||
|
# Two files read; no app, no display.
|
||||||
|
- name: Manual pictures have scenes
|
||||||
|
run: tools/manual/record.sh --check
|
||||||
|
|
||||||
- name: Traceability gate
|
- name: Traceability gate
|
||||||
run: cargo run -q -p traceability -- check
|
run: cargo run -q -p traceability -- check
|
||||||
|
|
||||||
|
|||||||
+12
-12
@@ -1197,28 +1197,28 @@ def own_code_changed(s, since):
|
|||||||
|
|
||||||
|
|
||||||
def changed():
|
def changed():
|
||||||
"""The scenes whose pictures are older than their sources: for each
|
"""The scenes whose pictures are older than their sources: the commit
|
||||||
picture, the commit that last touched it, and whether any source — or
|
that last touched any of a scene's pictures, and whether a source — or
|
||||||
the scene's own code — has changed since (the working tree included).
|
the scene's own code — has changed since (the working tree included).
|
||||||
A picture never committed is new, and so is its scene."""
|
A scene none of whose pictures was ever committed is new.
|
||||||
|
|
||||||
|
A re-recording that comes out byte-identical touches no picture, so its
|
||||||
|
scene stays listed until one of its pictures really changes; re-running
|
||||||
|
it is harmless."""
|
||||||
out = []
|
out = []
|
||||||
for s in SCENES.values():
|
for s in SCENES.values():
|
||||||
pics = [m for m in s.media if '.' in m]
|
pics = [f'{MEDIA}/{m}' for m in s.media if '.' in m]
|
||||||
if not pics:
|
if not pics:
|
||||||
continue
|
continue
|
||||||
reasons = []
|
since = git('log', '-1', '--format=%H', '--', *pics).strip()
|
||||||
for m in pics:
|
|
||||||
since = git('log', '-1', '--format=%H', '--', f'{MEDIA}/{m}').strip()
|
|
||||||
if not since:
|
if not since:
|
||||||
reasons.append(f'media/{m} was never committed')
|
out.append((s.name, 'its pictures were never committed'))
|
||||||
continue
|
continue
|
||||||
paths = git('diff', '--name-only', since, '--', *[f':(glob){g}' for g in s.sources]).split()
|
paths = git('diff', '--name-only', since, '--', *[f':(glob){g}' for g in s.sources]).split()
|
||||||
if paths:
|
if paths:
|
||||||
reasons.append(f'{", ".join(sorted(set(paths))[:3])} changed since media/{m}')
|
out.append((s.name, f'{", ".join(sorted(set(paths))[:3])} changed since {since[:9]}'))
|
||||||
elif own_code_changed(s, since):
|
elif own_code_changed(s, since):
|
||||||
reasons.append(f'its scene changed since media/{m}')
|
out.append((s.name, f'its scene changed since {since[:9]}'))
|
||||||
if reasons:
|
|
||||||
out.append((s.name, reasons[0]))
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user