feat: git label import
This commit is contained in:
parent
d6d094a67d
commit
017ab4951a
|
|
@ -339,6 +339,7 @@ def _mask_repository(repository: ForgejoRepository, connection: ForgejoConnectio
|
|||
"active": repository.active,
|
||||
"connection": _create_connection_info(connection) if connection is not None else None,
|
||||
"has_webhook_secret": bool(repository.webhook_secret),
|
||||
"labels": repository.labels if repository.labels is not None else [],
|
||||
"last_sync_at": repository.last_sync_at,
|
||||
"last_sync_error": repository.last_sync_error,
|
||||
"created_at": repository.created_at,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ from __future__ import annotations
|
|||
from datetime import datetime
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
from sqlalchemy import Column
|
||||
from sqlalchemy import JSON
|
||||
from sqlmodel import Field
|
||||
|
||||
from app.core.time import utcnow
|
||||
|
|
@ -27,6 +29,10 @@ class ForgejoRepository(QueryModel, table=True):
|
|||
default_branch: str = Field(default="main")
|
||||
active: bool = Field(default=True)
|
||||
webhook_secret: str | None = Field(default=None)
|
||||
labels: list[dict[str, object]] = Field(
|
||||
default_factory=list,
|
||||
sa_column=Column(JSON, nullable=False, server_default="[]"),
|
||||
)
|
||||
last_sync_at: datetime | None = Field(default=None)
|
||||
last_sync_error: str | None = Field(default=None)
|
||||
created_at: datetime = Field(default_factory=utcnow)
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ class ForgejoRepositoryRead(ForgejoRepositoryBase):
|
|||
connection_id: UUID
|
||||
connection: ForgejoRepositoryConnectionInfo
|
||||
has_webhook_secret: bool = False
|
||||
labels: list[dict[str, object]] = Field(default_factory=list)
|
||||
last_sync_at: datetime | None
|
||||
last_sync_error: str | None
|
||||
created_at: datetime
|
||||
|
|
|
|||
|
|
@ -157,6 +157,32 @@ class ForgejoAPIClient:
|
|||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
async def list_labels(
|
||||
self,
|
||||
owner: str,
|
||||
repo: str,
|
||||
limit: int = 50,
|
||||
) -> list[dict[str, object]]:
|
||||
"""
|
||||
List all labels defined on a repository.
|
||||
|
||||
Args:
|
||||
owner: Repository owner
|
||||
repo: Repository name
|
||||
limit: Max labels to fetch per page
|
||||
|
||||
Returns:
|
||||
List of label dicts with id, name, color, description.
|
||||
"""
|
||||
client = await self._get_client()
|
||||
response = await client.get(
|
||||
f"/api/v1/repos/{owner}/{repo}/labels",
|
||||
params={"limit": limit, "page": 1},
|
||||
)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
return list(data) if isinstance(data, list) else []
|
||||
|
||||
async def list_user_repos(
|
||||
self,
|
||||
limit: int = 50,
|
||||
|
|
|
|||
|
|
@ -146,6 +146,30 @@ class IssueSyncService:
|
|||
break
|
||||
current_page += 1
|
||||
|
||||
# Sync repository label catalog
|
||||
try:
|
||||
async with get_forgejo_client(connection) as client:
|
||||
fetched_labels = await client.list_labels(
|
||||
owner=repository.owner,
|
||||
repo=repository.repo,
|
||||
)
|
||||
repository.labels = [
|
||||
{
|
||||
"id": lbl.get("id"),
|
||||
"name": lbl.get("name", ""),
|
||||
"color": lbl.get("color", ""),
|
||||
"description": lbl.get("description") or "",
|
||||
}
|
||||
for lbl in fetched_labels
|
||||
if lbl.get("name")
|
||||
]
|
||||
except Exception as exc:
|
||||
logger.warning(
|
||||
"label_sync_failed",
|
||||
repository_id=str(repository_id),
|
||||
error=str(exc),
|
||||
)
|
||||
|
||||
# Update repository sync metadata
|
||||
repository.last_sync_at = utcnow()
|
||||
repository.last_sync_error = None
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
"""add labels column to forgejo_repositories
|
||||
|
||||
Revision ID: a1b2c3d4e5f7
|
||||
Revises: f5a2b3c4d5e6
|
||||
Create Date: 2026-05-19 00:00:00.000000
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
revision = "a1b2c3d4e5f7"
|
||||
down_revision = "f5a2b3c4d5e6"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.add_column(
|
||||
"forgejo_repositories",
|
||||
sa.Column(
|
||||
"labels",
|
||||
sa.JSON(),
|
||||
nullable=False,
|
||||
server_default="[]",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_column("forgejo_repositories", "labels")
|
||||
|
|
@ -27,6 +27,13 @@ export interface ForgejoConnectionUpdate {
|
|||
}
|
||||
|
||||
// Forgejo Repository types
|
||||
export interface ForgejoRepoLabel {
|
||||
id: number | null;
|
||||
name: string;
|
||||
color: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface ForgejoRepository {
|
||||
id: string;
|
||||
organization_id: string;
|
||||
|
|
@ -37,6 +44,7 @@ export interface ForgejoRepository {
|
|||
default_branch: string;
|
||||
active: boolean;
|
||||
has_webhook_secret: boolean;
|
||||
labels: ForgejoRepoLabel[];
|
||||
connection: ForgejoConnection;
|
||||
last_sync_at: string | null;
|
||||
last_sync_error: string | null;
|
||||
|
|
|
|||
Loading…
Reference in New Issue