feat(web): support ssh owner repo clone flow

- Add SSH-only owner/repo clone path for git.commumedia.org
- Preflight remote repository existence with git ls-remote before cloning
- Keep advanced URL paste fallback and blank repository creation
- Add focused backend and frontend coverage plus docs updates

Quality gates: python -m py_compile, vitest run src/components/repositories-settings-tab.test.tsx, npm run typecheck
This commit is contained in:
2026-05-22 19:07:04 +02:00
parent 5af4de0d7e
commit 2525c58471
9 changed files with 310 additions and 63 deletions
+29
View File
@@ -89,6 +89,32 @@ def _get_repo_path(user_id: uuid.UUID, project_id: uuid.UUID, name: str) -> str:
return os.path.join(base, str(user_id), str(project_id), f"{name}.git")
def _build_provider_clone_url(owner: str, repo: str) -> str:
"""Build the SSH clone URL for the fixed git provider."""
return f"git@git.commumedia.org:{owner}/{repo}.git"
def _preflight_remote_repository(remote_url: str) -> None:
"""Verify a remote repository is reachable before cloning."""
try:
result = subprocess.run(
["git", "ls-remote", remote_url],
capture_output=True,
text=True,
timeout=60,
)
except subprocess.TimeoutExpired:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="remote repository check timed out")
except FileNotFoundError:
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="git command not found")
if result.returncode != 0:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="repository not found or inaccessible",
)
class GitRepositoryCreate(BaseModel):
name: str
remote_url: str | None = None
@@ -267,6 +293,9 @@ async def create_repository(
if parse_result["base_url"]:
remote_url = parse_result["base_url"]
if remote_url:
_preflight_remote_repository(remote_url)
repo_path = _get_repo_path(user_id, project_id, data.name)
# Ensure parent directory exists