The invocations in CLAUDE.md were correct but long, and retyping them is how flags get dropped. `make check` is the gate a change should pass: Yarn compiles, voice sheets are in sync, EditMode is green. `make test` and `make build` depend on a `lock` target that fails if the Editor has the project open, which removes the most common confusing failure. It filters out AssetImportWorker children, which are not a second Editor. tools/ci/report_tests.py parses the NUnit results and exits non-zero on failure, because Unity documents no common exit-code definition across the components under test — the XML is the authority, not $?. `make merge-driver` configures UnityYAMLMerge for the .gitattributes rules added earlier. Note the binary lives in the Editor bundle under Contents/Helpers, not Contents/Tools as most guides say; there is no Tools directory in Unity 6 on macOS. Also ignores the local .test-results/ and build/ output. Co-Authored-By: Claude Opus 5 <[email protected]>
45 lines
1.4 KiB
Python
Executable File
45 lines
1.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Summarise an NUnit results file and exit non-zero if anything failed.
|
|
|
|
Unity's own docs state there is no common exit-code definition across the
|
|
components under test, so the results XML is the authority, not $?.
|
|
"""
|
|
|
|
import sys
|
|
import xml.etree.ElementTree as ET
|
|
|
|
|
|
def main(path):
|
|
try:
|
|
root = ET.parse(path).getroot()
|
|
except FileNotFoundError:
|
|
print(f"no results at {path} — the run did not get far enough to write one")
|
|
return 1
|
|
except ET.ParseError as exc:
|
|
print(f"could not parse {path}: {exc}")
|
|
return 1
|
|
|
|
total = int(root.get("total") or 0)
|
|
passed = int(root.get("passed") or 0)
|
|
failed = int(root.get("failed") or 0)
|
|
skipped = int(root.get("skipped") or 0)
|
|
|
|
for case in root.iter("test-case"):
|
|
if case.get("result") == "Passed":
|
|
continue
|
|
print(f"FAIL {case.get('fullname')}")
|
|
message = case.find("failure/message")
|
|
if message is not None and message.text:
|
|
for line in message.text.strip().splitlines()[:6]:
|
|
print(f" {line}")
|
|
|
|
if total == 0:
|
|
print("no tests ran")
|
|
else:
|
|
print(f"{passed}/{total} passed" + (f", {skipped} skipped" if skipped else ""))
|
|
return 1 if failed else 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main(sys.argv[1] if len(sys.argv) > 1 else ".test-results/editmode.xml"))
|