feat: new git imports (desc, open, is_archived)
This commit is contained in:
parent
533f5079e1
commit
87802db0f4
|
|
@ -339,6 +339,10 @@ 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),
|
||||
"description": repository.description,
|
||||
"open_issues_count": repository.open_issues_count if repository.open_issues_count is not None else 0,
|
||||
"is_archived": bool(repository.is_archived),
|
||||
"topics": repository.topics if repository.topics is not None else [],
|
||||
"labels": repository.labels if repository.labels is not None else [],
|
||||
"last_sync_at": repository.last_sync_at,
|
||||
"last_sync_error": repository.last_sync_error,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from __future__ import annotations
|
|||
from datetime import datetime
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy import JSON, Column
|
||||
from sqlmodel import Field, Index, SQLModel
|
||||
|
||||
|
|
@ -24,13 +25,15 @@ class ForgejoIssue(SQLModel, table=True):
|
|||
forgejo_issue_number: int = Field(index=True)
|
||||
|
||||
title: str
|
||||
body: str | None = Field(default=None, sa_column=Column(sa.Text, nullable=True))
|
||||
body_preview: str | None = Field(default=None, max_length=1000)
|
||||
state: str = Field(default="open") # open, closed, open
|
||||
state: str = Field(default="open")
|
||||
is_pull_request: bool = Field(default=False)
|
||||
|
||||
# JSON fields for complex data
|
||||
labels: list[dict[str, object]] = Field(default_factory=list, sa_column=Column(JSON))
|
||||
assignees: list[dict[str, object]] = Field(default_factory=list, sa_column=Column(JSON))
|
||||
milestone: dict[str, object] | None = Field(default=None, sa_column=Column(JSON, nullable=True))
|
||||
|
||||
author: str
|
||||
html_url: str
|
||||
|
|
|
|||
|
|
@ -29,6 +29,13 @@ class ForgejoRepository(QueryModel, table=True):
|
|||
default_branch: str = Field(default="main")
|
||||
active: bool = Field(default=True)
|
||||
webhook_secret: str | None = Field(default=None)
|
||||
description: str | None = Field(default=None)
|
||||
open_issues_count: int = Field(default=0)
|
||||
is_archived: bool = Field(default=False)
|
||||
topics: list[str] = Field(
|
||||
default_factory=list,
|
||||
sa_column=Column(JSON, nullable=False, server_default="[]"),
|
||||
)
|
||||
labels: list[dict[str, object]] = Field(
|
||||
default_factory=list,
|
||||
sa_column=Column(JSON, nullable=False, server_default="[]"),
|
||||
|
|
|
|||
|
|
@ -14,11 +14,13 @@ class ForgejoIssueBase(SQLModel):
|
|||
|
||||
forgejo_issue_number: int
|
||||
title: str
|
||||
body: str | None = None
|
||||
body_preview: str | None = None
|
||||
state: str
|
||||
is_pull_request: bool
|
||||
labels: list[dict[str, Any]] = []
|
||||
assignees: list[dict[str, Any]] = []
|
||||
milestone: dict[str, Any] | None = None
|
||||
author: str
|
||||
html_url: str
|
||||
forgejo_created_at: datetime
|
||||
|
|
|
|||
|
|
@ -108,6 +108,10 @@ class ForgejoRepositoryRead(ForgejoRepositoryBase):
|
|||
connection_id: UUID
|
||||
connection: ForgejoRepositoryConnectionInfo
|
||||
has_webhook_secret: bool = False
|
||||
description: str | None = None
|
||||
open_issues_count: int = 0
|
||||
is_archived: bool = False
|
||||
topics: list[str] = Field(default_factory=list)
|
||||
labels: list[dict[str, object]] = Field(default_factory=list)
|
||||
last_sync_at: datetime | None
|
||||
last_sync_error: str | None
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ class IssueSyncService:
|
|||
labels_data = []
|
||||
for label in (issue_data.get("labels") or []):
|
||||
labels_data.append({
|
||||
"id": label.get("id"),
|
||||
"name": label.get("name", ""),
|
||||
"color": label.get("color", ""),
|
||||
"description": label.get("description", ""),
|
||||
|
|
@ -93,6 +94,24 @@ class IssueSyncService:
|
|||
"avatar_url": assignee.get("avatar_url", ""),
|
||||
})
|
||||
|
||||
# Parse milestone
|
||||
milestone_data = None
|
||||
raw_milestone = issue_data.get("milestone")
|
||||
if raw_milestone and isinstance(raw_milestone, dict):
|
||||
milestone_data = {
|
||||
"id": raw_milestone.get("id"),
|
||||
"title": raw_milestone.get("title", ""),
|
||||
"state": raw_milestone.get("state", "open"),
|
||||
"description": raw_milestone.get("description") or None,
|
||||
"due_on": raw_milestone.get("due_on") or None,
|
||||
"closed_at": raw_milestone.get("closed_at") or None,
|
||||
}
|
||||
|
||||
# Full body and preview
|
||||
raw_body = issue_data.get("body") or ""
|
||||
body_full = raw_body if raw_body else None
|
||||
body_preview = raw_body[:1000] if raw_body else None
|
||||
|
||||
# Parse dates
|
||||
created_at = self._parse_iso_date(issue_data.get("created_at"))
|
||||
updated_at = self._parse_iso_date(issue_data.get("updated_at"))
|
||||
|
|
@ -107,11 +126,13 @@ class IssueSyncService:
|
|||
repository_id=repository_id,
|
||||
forgejo_issue_number=forgejo_number,
|
||||
title=issue_data.get("title", ""),
|
||||
body_preview=(issue_data.get("body") or "")[:1000],
|
||||
body=body_full,
|
||||
body_preview=body_preview,
|
||||
state=state,
|
||||
is_pull_request=False,
|
||||
labels=labels_data,
|
||||
assignees=assignees_data,
|
||||
milestone=milestone_data,
|
||||
author=issue_data.get("user", {}).get("login", ""),
|
||||
html_url=issue_data.get("html_url", ""),
|
||||
forgejo_created_at=created_at,
|
||||
|
|
@ -123,10 +144,12 @@ class IssueSyncService:
|
|||
created += 1
|
||||
else:
|
||||
existing.title = issue_data.get("title", "")
|
||||
existing.body_preview = (issue_data.get("body") or "")[:1000]
|
||||
existing.body = body_full
|
||||
existing.body_preview = body_preview
|
||||
existing.state = state
|
||||
existing.labels = labels_data
|
||||
existing.assignees = assignees_data
|
||||
existing.milestone = milestone_data
|
||||
existing.author = issue_data.get("user", {}).get("login", "")
|
||||
existing.html_url = issue_data.get("html_url", "")
|
||||
existing.forgejo_created_at = created_at
|
||||
|
|
@ -170,6 +193,25 @@ class IssueSyncService:
|
|||
error=str(exc),
|
||||
)
|
||||
|
||||
# Sync repository remote metadata (description, archived, topics, issue count)
|
||||
try:
|
||||
async with get_forgejo_client(connection) as client:
|
||||
repo_meta = await client.get_repository(
|
||||
owner=repository.owner,
|
||||
repo=repository.repo,
|
||||
)
|
||||
repository.description = repo_meta.get("description") or None
|
||||
repository.open_issues_count = int(repo_meta.get("open_issues_count") or 0)
|
||||
repository.is_archived = bool(repo_meta.get("archived", False))
|
||||
raw_topics = repo_meta.get("topics")
|
||||
repository.topics = list(raw_topics) if isinstance(raw_topics, list) else []
|
||||
except Exception as exc:
|
||||
logger.warning(
|
||||
"repo_metadata_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,71 @@
|
|||
"""add body and milestone to issues; description, open_issues_count, is_archived, topics to repos
|
||||
|
||||
Revision ID: b2c3d4e5f6a7
|
||||
Revises: a1b2c3d4e5f7
|
||||
Create Date: 2026-05-19 00:00:00.000000
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
revision = "b2c3d4e5f6a7"
|
||||
down_revision = "a1b2c3d4e5f7"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# forgejo_issues — full body text and milestone JSON
|
||||
op.add_column(
|
||||
"forgejo_issues",
|
||||
sa.Column("body", sa.Text(), nullable=True),
|
||||
)
|
||||
op.add_column(
|
||||
"forgejo_issues",
|
||||
sa.Column("milestone", sa.JSON(), nullable=True),
|
||||
)
|
||||
|
||||
# forgejo_repositories — remote metadata fields
|
||||
op.add_column(
|
||||
"forgejo_repositories",
|
||||
sa.Column("description", sa.String(), nullable=True),
|
||||
)
|
||||
op.add_column(
|
||||
"forgejo_repositories",
|
||||
sa.Column(
|
||||
"open_issues_count",
|
||||
sa.Integer(),
|
||||
nullable=False,
|
||||
server_default="0",
|
||||
),
|
||||
)
|
||||
op.add_column(
|
||||
"forgejo_repositories",
|
||||
sa.Column(
|
||||
"is_archived",
|
||||
sa.Boolean(),
|
||||
nullable=False,
|
||||
server_default="false",
|
||||
),
|
||||
)
|
||||
op.add_column(
|
||||
"forgejo_repositories",
|
||||
sa.Column(
|
||||
"topics",
|
||||
sa.JSON(),
|
||||
nullable=False,
|
||||
server_default="[]",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_column("forgejo_repositories", "topics")
|
||||
op.drop_column("forgejo_repositories", "is_archived")
|
||||
op.drop_column("forgejo_repositories", "open_issues_count")
|
||||
op.drop_column("forgejo_repositories", "description")
|
||||
op.drop_column("forgejo_issues", "milestone")
|
||||
op.drop_column("forgejo_issues", "body")
|
||||
|
|
@ -44,6 +44,10 @@ export interface ForgejoRepository {
|
|||
default_branch: string;
|
||||
active: boolean;
|
||||
has_webhook_secret: boolean;
|
||||
description: string | null;
|
||||
open_issues_count: number;
|
||||
is_archived: boolean;
|
||||
topics: string[];
|
||||
labels: ForgejoRepoLabel[];
|
||||
connection: ForgejoConnection;
|
||||
last_sync_at: string | null;
|
||||
|
|
@ -258,17 +262,28 @@ export interface ForgejoIssueLabel {
|
|||
description?: string | null;
|
||||
}
|
||||
|
||||
export interface ForgejoIssueMilestone {
|
||||
id: number | null;
|
||||
title: string;
|
||||
state: string;
|
||||
description: string | null;
|
||||
due_on: string | null;
|
||||
closed_at: string | null;
|
||||
}
|
||||
|
||||
export interface ForgejoIssue {
|
||||
id: string;
|
||||
organization_id: string;
|
||||
repository_id: string;
|
||||
forgejo_issue_number: number;
|
||||
title: string;
|
||||
body: string | null;
|
||||
body_preview: string | null;
|
||||
state: string;
|
||||
is_pull_request: boolean;
|
||||
labels: ForgejoIssueLabel[];
|
||||
assignees: Record<string, unknown>[];
|
||||
milestone: ForgejoIssueMilestone | null;
|
||||
author: string;
|
||||
html_url: string;
|
||||
forgejo_created_at: string;
|
||||
|
|
|
|||
Loading…
Reference in New Issue