feat(FN-011): complete Step 1 — Git types and provider abstraction
Fusion-Task-Id: FN-011 Fusion-Task-Lineage: 4a9aca6f-9d91-43aa-8d2a-d59657c1541a
This commit is contained in:
@@ -0,0 +1,19 @@
|
|||||||
|
"""Git provider abstraction, credentials, SSH keys, and operations."""
|
||||||
|
|
||||||
|
from app.git.credentials import AccessTokenCredential, CredentialStorage, GitCredential
|
||||||
|
from app.git.operations import GitOperations, LocalGitOperations
|
||||||
|
from app.git.provider import GitProvider
|
||||||
|
from app.git.types import ConnectionStatus, CredentialKind, ProviderKind, SshKeyStatus
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"AccessTokenCredential",
|
||||||
|
"ConnectionStatus",
|
||||||
|
"CredentialKind",
|
||||||
|
"CredentialStorage",
|
||||||
|
"GitCredential",
|
||||||
|
"GitOperations",
|
||||||
|
"GitProvider",
|
||||||
|
"LocalGitOperations",
|
||||||
|
"ProviderKind",
|
||||||
|
"SshKeyStatus",
|
||||||
|
]
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
"""Abstract base class for Git provider adapters."""
|
||||||
|
|
||||||
|
import abc
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from app.git.types import ConnectionStatus, ProviderKind
|
||||||
|
|
||||||
|
|
||||||
|
class GitProvider(abc.ABC):
|
||||||
|
"""Provider API adapter for remote Git operations.
|
||||||
|
|
||||||
|
This abstraction is separate from :class:`~app.git.operations.GitOperations`,
|
||||||
|
which handles local Git subprocess workflows.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def get_kind(self) -> ProviderKind:
|
||||||
|
"""Return the provider kind identifier."""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
async def validate_connection(
|
||||||
|
self, git_url: str, credential_id: str
|
||||||
|
) -> ConnectionStatus:
|
||||||
|
"""Validate that the given credential can access *git_url*.
|
||||||
|
|
||||||
|
Returns a :class:`ConnectionStatus` indicating the result.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
async def list_repositories(self, credential_id: str) -> list[dict[str, Any]]:
|
||||||
|
"""List repositories accessible with *credential_id*."""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
async def create_deploy_key(
|
||||||
|
self, git_url: str, public_key: str
|
||||||
|
) -> str:
|
||||||
|
"""Register a deploy key on the remote provider.
|
||||||
|
|
||||||
|
Returns the provider-side deploy key ID.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
async def delete_deploy_key(self, git_url: str, deploy_key_id: str) -> None:
|
||||||
|
"""Remove a previously registered deploy key."""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
async def get_default_branch(self, git_url: str, credential_id: str) -> str:
|
||||||
|
"""Return the default branch name for the repository at *git_url*."""
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
"""Enumerations for Git provider abstraction."""
|
||||||
|
|
||||||
|
from enum import StrEnum
|
||||||
|
|
||||||
|
|
||||||
|
class ProviderKind(StrEnum):
|
||||||
|
"""Supported Git provider kinds."""
|
||||||
|
|
||||||
|
github = "github"
|
||||||
|
gitlab = "gitlab"
|
||||||
|
gitea = "gitea"
|
||||||
|
forgejo = "forgejo"
|
||||||
|
generic = "generic"
|
||||||
|
|
||||||
|
|
||||||
|
class CredentialKind(StrEnum):
|
||||||
|
"""Supported credential kinds for Git authentication."""
|
||||||
|
|
||||||
|
ssh_key = "ssh_key"
|
||||||
|
access_token = "access_token"
|
||||||
|
|
||||||
|
|
||||||
|
class ConnectionStatus(StrEnum):
|
||||||
|
"""Lifecycle states for a repository connection."""
|
||||||
|
|
||||||
|
pending = "pending"
|
||||||
|
connected = "connected"
|
||||||
|
disconnected = "disconnected"
|
||||||
|
error = "error"
|
||||||
|
|
||||||
|
|
||||||
|
class SshKeyStatus(StrEnum):
|
||||||
|
"""Lifecycle states for an SSH key pair."""
|
||||||
|
|
||||||
|
generated = "generated"
|
||||||
|
registered = "registered"
|
||||||
|
rotating = "rotating"
|
||||||
|
revoked = "revoked"
|
||||||
Reference in New Issue
Block a user