diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b8001b1..282a3cb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,6 +10,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - name: Checkout cpa-templates + uses: actions/checkout@v4 + with: + repository: Create-Python-App/cpa-templates + path: cpa-templates - uses: astral-sh/setup-uv@v6 with: enable-cache: true @@ -17,4 +22,7 @@ jobs: with: python-version-file: .python-version - run: uv sync --group dev - - run: uv run pytest --cov --cov-report=term-missing + - name: Run tests + env: + CPA_TEMPLATES_ROOT: ${{ github.workspace }}/cpa-templates + run: uv run pytest --cov --cov-report=term-missing diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index daa07cd..2e3f409 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,4 +24,13 @@ make typecheck ## Templates -Template bank work will live in `cpa-templates` (tracked in #44). Until then use `fixtures/`. +Template and extension authoring lives in [`cpa-templates`](https://github.com/Create-Python-App/cpa-templates). + +To test scaffolding against a local `cpa-templates` checkout: + +```bash +export CPA_TEMPLATES_ROOT=/path/to/cpa-templates +uv run pytest packages/create-awesome-python-app/tests/test_cpa_templates_integration.py -v +``` + +The catalog is fetched from `cpa-templates` `templates.json` (override with `CPA_CATALOG_URL`). diff --git a/packages/create-awesome-python-app/tests/test_cpa_templates_integration.py b/packages/create-awesome-python-app/tests/test_cpa_templates_integration.py new file mode 100644 index 0000000..9425212 --- /dev/null +++ b/packages/create-awesome-python-app/tests/test_cpa_templates_integration.py @@ -0,0 +1,96 @@ +"""Integration tests against the cpa-templates bank.""" + +from __future__ import annotations + +import os +import subprocess +from pathlib import Path + +import pytest + +_REPO_ROOT = Path(__file__).resolve().parents[4] +_DEFAULT_CPA_TEMPLATES = (_REPO_ROOT.parent / "cpa-templates").resolve() +CPA_TEMPLATES_ROOT = Path( + os.environ.get("CPA_TEMPLATES_ROOT", str(_DEFAULT_CPA_TEMPLATES)) +).resolve() +FASTAPI_TEMPLATE = CPA_TEMPLATES_ROOT / "templates" / "fastapi-starter" +GITHUB_SETUP = CPA_TEMPLATES_ROOT / "extensions" / "github-setup" + + +def _cpa_templates_available() -> bool: + return (FASTAPI_TEMPLATE / "pyproject.toml").is_file() + + +@pytest.mark.skipif( + not _cpa_templates_available(), + reason="cpa-templates checkout not available (set CPA_TEMPLATES_ROOT)", +) +def test_scaffold_fastapi_starter_from_cpa_templates( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + monkeypatch.setenv("CI", "1") + monkeypatch.setenv("CPA_SKIP_GIT", "1") + dest = tmp_path / "api" + template_url = f"file://{CPA_TEMPLATES_ROOT}?subdir=templates/fastapi-starter" + + result = subprocess.run( + [ + "uv", + "run", + "create-awesome-python-app", + "--template", + template_url, + "--no-interactive", + "--no-install", + str(dest), + ], + cwd=_REPO_ROOT, + capture_output=True, + text=True, + check=False, + ) + assert result.returncode == 0, result.stdout + result.stderr + assert (dest / "app" / "main.py").is_file() + assert (dest / "pyproject.toml").is_file() + + sync = subprocess.run(["uv", "sync"], cwd=dest, capture_output=True, text=True) + assert sync.returncode == 0, sync.stderr + + lint = subprocess.run(["uv", "run", "ruff", "check", "."], cwd=dest, capture_output=True, text=True) + assert lint.returncode == 0, lint.stderr + + tests = subprocess.run(["uv", "run", "pytest", "-q"], cwd=dest, capture_output=True, text=True) + assert tests.returncode == 0, tests.stdout + tests.stderr + + +@pytest.mark.skipif( + not (_cpa_templates_available() and GITHUB_SETUP.is_dir()), + reason="cpa-templates extensions not available", +) +def test_scaffold_fastapi_with_github_setup_extension( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + monkeypatch.setenv("CI", "1") + monkeypatch.setenv("CPA_SKIP_GIT", "1") + dest = tmp_path / "api-ext" + repo = CPA_TEMPLATES_ROOT + result = subprocess.run( + [ + "uv", + "run", + "create-awesome-python-app", + "--template", + f"file://{repo}?subdir=templates/fastapi-starter", + "--addons", + f"file://{repo}?subdir=extensions/github-setup", + "--no-interactive", + "--no-install", + str(dest), + ], + cwd=_REPO_ROOT, + capture_output=True, + text=True, + check=False, + ) + assert result.returncode == 0, result.stdout + result.stderr + assert (dest / ".github" / "workflows" / "ci.yml").is_file()