ci.py (69 lines of code) (raw):

#!/usr/bin/env python3 # Copyright © Meta Platforms, Inc. and affiliates # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. # coding=utf8 """ ptr CI run script - Will either run unittests via 'python ptr_tests.py' OR run ptr itself to enfore coverage, black, and mypy type results 🐓🥚 """ import json import sys from os import environ from pathlib import Path from subprocess import PIPE, run from tempfile import gettempdir def check_ptr_stats_json(stats_file: Path) -> int: stats_errors = 0 if not stats_file.exists(): print(f"{stats_file} stats file does not exist") return 68 try: with stats_file.open("r") as sfp: stats_json = json.load(sfp) except json.JSONDecodeError as jde: print(f"Stats JSON Error: {jde}") return 69 # Lets always print JSON to help debug any failures and have JSON history print(json.dumps(stats_json, indent=2, sort_keys=True)) any_fail = int(stats_json["total.fails"]) + int(stats_json["total.timeouts"]) if any_fail: print(f"Stats report {any_fail} fails/timeouts", file=sys.stderr) return any_fail if int(stats_json["total.setup_pys"]) > 1: print("Somehow we had more than 1 setup.py - What?", file=sys.stderr) stats_errors += 1 if int(stats_json["pct.setup_py_ptr_enabled"]) != 100: print("We didn't test all setup.py files ...", file=sys.stderr) stats_errors += 1 # TODO: Make getting project name better - For now quick CI hack coverage_key_count = 0 for key in stats_json.keys(): if "_coverage." in key: coverage_key_count += 1 if coverage_key_count != 4: print("We didn't get coverage stats for all ptr files + total", file=sys.stderr) stats_errors += 1 print(f"Stats check found {stats_errors} error(s)") return stats_errors def integration_test() -> int: # TODO: Plumb up to a coverage system - e.g. codecov (Issue #6) print("Running `ptr` integration tests (aka run itself)", file=sys.stderr) stats_file = Path(gettempdir()) / "ptr_ci_stats" ci_cmd = [ "python", "ptr.py", "-d", "--print-cov", "--run-disabled", "--error-on-warnings", "--stats-file", str(stats_file), ] if "VIRTUAL_ENV" in environ: ci_cmd.extend(["--venv", environ["VIRTUAL_ENV"]]) cp = run(ci_cmd, check=True) return cp.returncode + check_ptr_stats_json(stats_file) def ci(show_env: bool = False) -> int: # Output exact python version cp = run(("python", "-V"), check=True, stdout=PIPE, universal_newlines=True) print(f"Using {cp.stdout}", file=sys.stderr) if show_env: print("- Environment:", file=sys.stderr) for key in sorted(environ.keys()): print(f"{key}: {environ[key]}", file=sys.stderr) # Azure sets CI_ENV=PTR_INTEGRATION # Travis sets PTR_INTEGRATION=1 if "PTR_INTEGRATION" in environ or ( "CI_ENV" in environ and environ["CI_ENV"] == "PTR_INTEGRATION" ): return integration_test() print("Running `ptr` unit tests", file=sys.stderr) return run(("python", "ptr_tests.py", "-v"), check=True).returncode if __name__ == "__main__": sys.exit(ci())