aboutsummaryrefslogtreecommitdiff
path: root/.run
diff options
context:
space:
mode:
Diffstat (limited to '.run')
-rw-r--r--.run/src/bin/ci.py74
1 files changed, 74 insertions, 0 deletions
diff --git a/.run/src/bin/ci.py b/.run/src/bin/ci.py
new file mode 100644
index 0000000..ced6566
--- /dev/null
+++ b/.run/src/bin/ci.py
@@ -0,0 +1,74 @@
+"""Full CI orchestration for the mingling project.
+
+Runs every `cargo ci` step in order: lock the workspace, run all checks,
+refresh the generated artifacts, then unlock. The final `git-unlock` doubles
+as the idempotency check: it fails with a non-zero exit code when the run
+left the working tree dirty.
+
+The script locates the git repository root and runs with it as the working
+directory, so it can be invoked from anywhere inside the repo.
+"""
+
+import os
+import subprocess
+import sys
+from pathlib import Path
+
+# The pipeline steps, in execution order.
+STEPS = [
+ "git-lock",
+ "report-clean",
+ "build-check",
+ "clippy-check",
+ "test-all",
+ "example-check",
+ "docs-check",
+ "example-refresh",
+ "docsify-refresh",
+ "features-refresh",
+ # Idempotency check: exits non-zero if CI contaminated the workspace.
+ "git-unlock",
+]
+
+
+def find_repo_root() -> Path:
+ """Return the nearest ancestor directory containing `.git`."""
+ current = Path.cwd()
+ for directory in (current, *current.parents):
+ if (directory / ".git").is_dir():
+ return directory
+ raise SystemExit("error: not inside a git repository")
+
+
+def main() -> int:
+ root = find_repo_root()
+ os.chdir(root)
+
+ # Signature banner: docs/res/ci_banner.txt, relative to this script
+ # (.run/src/bin -> four levels up is the repo root).
+ banner = (
+ Path(__file__).resolve().parent.parent.parent.parent
+ / "docs"
+ / "res"
+ / "ci_banner.txt"
+ )
+ try:
+ print(banner.read_text(encoding="utf-8"), end="")
+ except OSError:
+ pass
+
+ for step in STEPS:
+ print(f"==> cargo ci {step}")
+ result = subprocess.run(["cargo", "ci", step], check=False)
+ if result.returncode != 0:
+ print(
+ f"error: step `{step}` failed with exit code {result.returncode}",
+ file=sys.stderr,
+ )
+ return result.returncode
+
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())