David Prince
production: clean source snapshot — no history bloat
71b4454
Raw
History Blame Contribute Delete
2.23 kB
from __future__ import annotations
import asyncio
import logging
from datetime import datetime, timezone
from pathlib import Path
from typing import Any
logger = logging.getLogger("deployment_engine")
ROOT = Path(__file__).resolve().parents[2]
PROJECTS = ROOT / "generated_projects"
DEPLOYMENTS = ROOT / "deployments"
class DeploymentEngine:
async def deploy_project(
self,
project_id: str,
environment: str = "staging",
) -> dict[str, Any]:
if not project_id or not project_id.strip():
raise ValueError("project_id is required")
environment = environment.strip().lower()
if environment not in {"development", "staging", "production"}:
raise ValueError(
"environment must be development, staging, or production"
)
project_dir = PROJECTS / project_id
if not project_dir.exists():
raise FileNotFoundError(
f"Project workspace not found: {project_id}"
)
if not project_dir.is_dir():
raise NotADirectoryError(
f"Project workspace is not a directory: {project_id}"
)
DEPLOYMENTS.mkdir(parents=True, exist_ok=True)
stamp = datetime.now(timezone.utc).isoformat()
record = {
"status": "success",
"project_id": project_id,
"environment": environment,
"project_path": str(project_dir),
"deployed_at": stamp,
"deployment_id": (
f"deploy_{project_id}_"
f"{int(datetime.now(timezone.utc).timestamp())}"
),
}
await asyncio.to_thread(
self._write_record,
record,
)
logger.info(
"Deployment completed: project=%s environment=%s",
project_id,
environment,
)
return record
def _write_record(self, record: dict[str, Any]) -> None:
path = DEPLOYMENTS / f"{record['deployment_id']}.json"
import json
path.write_text(
json.dumps(record, indent=2),
encoding="utf-8",
)
deployment_engine = DeploymentEngine()