From f3b4d787d0ff0661ca8a21ce3fa6abc088694258 Mon Sep 17 00:00:00 2001 From: G-Fourteen Date: Sat, 1 Nov 2025 07:46:44 -0600 Subject: [PATCH] Streamline CI into single pipeline --- .../setup-python-playwright/action.yml | 23 --- .github/scripts/run_tests.py | 51 ----- .github/scripts/write_summary.py | 128 ------------ .github/workflows/main-branch.yml | 187 +++--------------- AI/index.html | 2 +- 5 files changed, 25 insertions(+), 366 deletions(-) delete mode 100644 .github/actions/setup-python-playwright/action.yml delete mode 100755 .github/scripts/run_tests.py delete mode 100755 .github/scripts/write_summary.py diff --git a/.github/actions/setup-python-playwright/action.yml b/.github/actions/setup-python-playwright/action.yml deleted file mode 100644 index a0fac48..0000000 --- a/.github/actions/setup-python-playwright/action.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Setup Python Playwright Environment -description: Install Python dependencies and Playwright browsers for testing. -inputs: - python-version: - description: Python version to install. - required: false - default: '3.11' -runs: - using: composite - steps: - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ inputs.python-version }} - - name: Install Python dependencies - shell: bash - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - - name: Install Playwright browsers - shell: bash - run: | - python -m playwright install --with-deps chromium diff --git a/.github/scripts/run_tests.py b/.github/scripts/run_tests.py deleted file mode 100755 index 192d954..0000000 --- a/.github/scripts/run_tests.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python3 -import json -import subprocess -import sys -from pathlib import Path - -def main() -> int: - tests_dir = Path("tests") - results = [] - exit_code = 0 - - if not tests_dir.exists(): - print("::warning::No tests directory found at ./tests") - else: - test_files = sorted(tests_dir.glob("test_*.py")) - if not test_files: - print("::warning::No tests matching pattern 'test_*.py' found in ./tests") - for test_file in test_files: - print(f"Running pytest on {test_file}") - completed = subprocess.run([ - sys.executable, - "-m", - "pytest", - str(test_file), - ]) - status = "passed" if completed.returncode == 0 else "failed" - results.append({ - "name": test_file.name, - "path": str(test_file), - "status": status, - }) - if completed.returncode != 0: - exit_code = completed.returncode - print(f"::warning::Test {test_file.name} failed with exit code {completed.returncode}") - - payload = { - "tests": results, - "overall_status": "passed" if exit_code == 0 else "failed", - } - Path("test-results.json").write_text(json.dumps(payload)) - - if exit_code != 0: - print("::warning::One or more tests failed. See pytest output above for details.") - else: - print("All tests passed.") - - return exit_code - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/.github/scripts/write_summary.py b/.github/scripts/write_summary.py deleted file mode 100755 index 25479d6..0000000 --- a/.github/scripts/write_summary.py +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/env python3 -"""Aggregate CI results into a GitHub Actions step summary.""" - -from __future__ import annotations - -import argparse -import json -import os -from pathlib import Path -from typing import Any - - -def load_json(path: Path) -> dict[str, Any] | None: - if not path.exists() or not path.is_file(): - return None - try: - return json.loads(path.read_text()) - except json.JSONDecodeError as exc: # noqa: TRY003 - print(f"::warning::Unable to parse JSON from {path}: {exc}") - return None - - -def render_tests_section(data: dict[str, Any] | None) -> list[str]: - lines = ["## Test Results", ""] - if not data: - lines.append("No test results were produced.") - return lines - - tests = data.get("tests") or [] - if not tests: - lines.append("No tests were discovered under /tests.") - return lines - - lines.append(f"Processed {len(tests)} test file(s).") - lines.append("") - lines.append("| Test file | Status |") - lines.append("| --- | --- |") - for entry in tests: - name = entry.get("name", "unknown") - status = (entry.get("status") or "unknown").lower() - if status == "passed": - emoji = "✅" - elif status == "failed": - emoji = "❌" - else: - emoji = "⚠️" - lines.append(f"| {name} | {emoji} {status.title()} |") - return lines - - -def render_build_section(data: dict[str, Any] | None) -> list[str]: - lines = ["## Build Status", ""] - if not data: - lines.append("No build output was produced.") - return lines - - status = (data.get("status") or "unknown").lower() - message = data.get("message") - copied = data.get("copied") or [] - - if status == "success": - emoji = "✅" - elif status == "warning": - emoji = "⚠️" - else: - emoji = "❌" - lines.append(f"Overall build result: {emoji} {status.title()}") - - if copied: - lines.append("") - lines.append("### Copied static files") - for item in copied: - lines.append(f"- {item}") - - if message: - lines.append("") - lines.append(f"Details: {message}") - - return lines - - -def append_summary(sections: list[list[str]]) -> None: - summary_path = os.environ.get("GITHUB_STEP_SUMMARY") - text = "\n".join(line for section in sections for line in (*section, "")) - print(text) - if summary_path: - with open(summary_path, "a", encoding="utf-8") as handle: - handle.write(text + "\n") - - -def parse_args() -> argparse.Namespace: - parser = argparse.ArgumentParser( - description="Aggregate CI results into a GitHub Actions step summary.", - ) - parser.add_argument( - "--include-tests", - action="store_true", - help="Include the tests section in the summary.", - ) - parser.add_argument( - "--include-build", - action="store_true", - help="Include the build section in the summary.", - ) - args = parser.parse_args() - if not args.include_tests and not args.include_build: - args.include_tests = True - args.include_build = True - return args - - -def main() -> None: - args = parse_args() - repo_root = Path(".") - tests_data = load_json(repo_root / "test-results.json") - build_data = load_json(repo_root / "build-results.json") - - sections: list[list[str]] = [] - if args.include_tests: - sections.append(render_tests_section(tests_data)) - if args.include_build and (build_data or (repo_root / "build-results.json").exists()): - sections.append(render_build_section(build_data)) - - append_summary(sections) - - -if __name__ == "__main__": - main() diff --git a/.github/workflows/main-branch.yml b/.github/workflows/main-branch.yml index 1a89cd6..4e056c1 100644 --- a/.github/workflows/main-branch.yml +++ b/.github/workflows/main-branch.yml @@ -1,186 +1,47 @@ -name: Main Branch Workflow +name: Build, Test, and Publish on: push: branches: [main] pull_request: - types: - - opened - - synchronize - - reopened - - ready_for_review - - edited - workflow_dispatch: + branches: [main] permissions: - contents: read - pages: write - id-token: write + contents: write concurrency: - group: pages + group: talk-to-unity-ci cancel-in-progress: true jobs: - build_artifacts: - name: Build and Upload Artifacts + pipeline: runs-on: ubuntu-latest - outputs: - status: ${{ steps.collect.outputs.status }} - results: ${{ steps.collect.outputs.results }} steps: - name: Checkout repository uses: actions/checkout@v4 - - name: Set up Python environment - uses: ./.github/actions/setup-python-playwright - - - name: Build static site - id: build-site - continue-on-error: true - run: python .github/scripts/build_static.py - - - name: Upload Pages artifact - if: github.event_name == 'push' && steps.build-site.outcome == 'success' - uses: actions/upload-pages-artifact@v3 + - name: Set up Python + uses: actions/setup-python@v5 with: - path: dist - - - name: Collect build metadata - id: collect - run: | - python - <<'PY' - import base64 - import json - import os - from pathlib import Path - - path = Path("build-results.json") - data: dict[str, object] = {} - status = "missing" - if path.exists(): - data = json.loads(path.read_text()) - status = data.get("status", "unknown") - encoded = base64.b64encode(json.dumps(data).encode("utf-8")).decode("utf-8") - with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as handle: - handle.write(f"status={status}\n") - handle.write(f"results={encoded}\n") - PY - - report_build_status: - name: Report Build Status - runs-on: ubuntu-latest - needs: build_artifacts - if: always() - steps: - - name: Checkout repository - uses: actions/checkout@v4 + python-version: '3.11' - - name: Restore build results - env: - BUILD_RESULTS_B64: ${{ needs.build_artifacts.outputs.results }} + - name: Install dependencies run: | - python - <<'PY' - import base64 - import json - import os - from pathlib import Path - - raw = os.environ.get("BUILD_RESULTS_B64", "") - data: dict[str, object] = {} - if raw: - try: - decoded = base64.b64decode(raw.encode("utf-8")).decode("utf-8") - if decoded: - data = json.loads(decoded) - except Exception as exc: # noqa: BLE001 - data = {"status": "unknown", "message": f"Unable to decode build results: {exc}"} - Path("build-results.json").write_text(json.dumps(data)) - PY - - - name: Report Build Status - run: python .github/scripts/write_summary.py --include-build + python -m pip install --upgrade pip + pip install -r requirements.txt + python -m playwright install --with-deps chromium - - name: Fail if build failed - if: needs.build_artifacts.outputs.status == 'failure' - run: exit 1 + - name: Run test suite + run: pytest --color=yes - tests: - name: Run Tests - runs-on: ubuntu-latest - needs: build_artifacts - if: always() - outputs: - status: ${{ steps.collect.outputs.status }} - results: ${{ steps.collect.outputs.results }} - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Python environment - uses: ./.github/actions/setup-python-playwright - - - name: Run Tests - id: run-tests - continue-on-error: true - run: python .github/scripts/run_tests.py - - - name: Collect test metadata - id: collect - run: | - python - <<'PY' - import base64 - import json - import os - from pathlib import Path - - path = Path("test-results.json") - data: dict[str, object] = {} - status = "missing" - if path.exists(): - data = json.loads(path.read_text()) - status = data.get("overall_status", "unknown") - encoded = base64.b64encode(json.dumps(data).encode("utf-8")).decode("utf-8") - with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as handle: - handle.write(f"status={status}\n") - handle.write(f"results={encoded}\n") - PY - - report_tests_statuses: - name: Report Tests Statuses - runs-on: ubuntu-latest - needs: tests - if: always() - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Restore test results - env: - TEST_RESULTS_B64: ${{ needs.tests.outputs.results }} - run: | - python - <<'PY' - import base64 - import json - import os - from pathlib import Path - - raw = os.environ.get("TEST_RESULTS_B64", "") - data: dict[str, object] = {} - if raw: - try: - decoded = base64.b64decode(raw.encode("utf-8")).decode("utf-8") - if decoded: - data = json.loads(decoded) - except Exception as exc: # noqa: BLE001 - data = {"tests": [], "overall_status": "failed", "message": f"Unable to decode test results: {exc}"} - Path("test-results.json").write_text(json.dumps(data)) - PY - - - name: Report Tests Statuses - run: python .github/scripts/write_summary.py --include-tests - - - name: Fail if tests failed - if: needs.tests.outputs.status == 'failed' - run: exit 1 + - name: Build static site assets + run: python .github/scripts/build_static.py + - name: Publish to GitHub Pages + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: dist + force_orphan: true + commit_message: Deploy updated static site diff --git a/AI/index.html b/AI/index.html index 147506c..da94636 100644 --- a/AI/index.html +++ b/AI/index.html @@ -64,4 +64,4 @@ - \ No newline at end of file +