Joedroid's picture
feat: local CI/release scripts, web UI as default command
be42be3
Raw
History Blame Contribute Delete
1.48 kB
#!/usr/bin/env python3
"""
StudyCraft CI script -- runs lint, test, and build locally.
Usage:
uv run python scripts/ci.py # full pipeline
uv run python scripts/ci.py --lint # lint only
uv run python scripts/ci.py --test # test only
uv run python scripts/ci.py --build # build only
"""
import subprocess
import sys
RED = "\033[91m"
GREEN = "\033[92m"
DIM = "\033[2m"
RESET = "\033[0m"
def run(label: str, cmd: list[str]) -> bool:
print(f"\n{DIM}--- {label} ---{RESET}")
print(f"{DIM}$ {' '.join(cmd)}{RESET}")
result = subprocess.run(cmd)
if result.returncode != 0:
print(f"{RED}FAILED: {label}{RESET}")
return False
print(f"{GREEN}PASSED: {label}{RESET}")
return True
def main() -> None:
args = set(sys.argv[1:])
run_all = not args or args == {"--all"}
steps: list[tuple[str, list[str], bool]] = [
("Lint", ["uv", "run", "ruff", "check", "src/", "tests/"], run_all or "--lint" in args),
("Test", ["uv", "run", "pytest", "tests/", "-v"], run_all or "--test" in args),
("Build", ["uv", "build"], run_all or "--build" in args),
]
failed = []
for label, cmd, should_run in steps:
if should_run and not run(label, cmd):
failed.append(label)
print()
if failed:
print(f"{RED}CI FAILED: {', '.join(failed)}{RESET}")
sys.exit(1)
else:
print(f"{GREEN}CI PASSED{RESET}")
if __name__ == "__main__":
main()