Fix Forgejo issue lifecycle identifiers
This commit is contained in:
parent
d58bfd1f96
commit
3523a7decc
3 changed files with 33 additions and 2 deletions
|
|
@ -49,7 +49,7 @@
|
||||||
| task | ISSUE-WP-0006-T04 | todo | — | workplans/ISSUE-WP-0006-forgejo-only-projection-boundary.md |
|
| task | ISSUE-WP-0006-T04 | todo | — | workplans/ISSUE-WP-0006-forgejo-only-projection-boundary.md |
|
||||||
| task | ISSUE-WP-0007-T00 | done | — | workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md |
|
| task | ISSUE-WP-0007-T00 | done | — | workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md |
|
||||||
| task | ISSUE-WP-0007-T01 | done | — | workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md |
|
| task | ISSUE-WP-0007-T01 | done | — | workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md |
|
||||||
| task | ISSUE-WP-0007-T02 | todo | — | workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md |
|
| task | ISSUE-WP-0007-T02 | progress | — | workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md |
|
||||||
| task | ISSUE-WP-0007-T03 | todo | — | workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md |
|
| task | ISSUE-WP-0007-T03 | todo | — | workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md |
|
||||||
| task | ISSUE-WP-0007-T04 | todo | — | workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md |
|
| task | ISSUE-WP-0007-T04 | todo | — | workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md |
|
||||||
| task | ISSUE-WP-0007-T05 | todo | — | workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md |
|
| task | ISSUE-WP-0007-T05 | todo | — | workplans/ISSUE-WP-0007-rapp-issue-core-railiance01-migration.md |
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,21 @@ def _mapping_backend_name(backend_type: str) -> str:
|
||||||
return "sqlite" if backend_type == "local" else backend_type
|
return "sqlite" if backend_type == "local" else backend_type
|
||||||
|
|
||||||
|
|
||||||
|
def _public_issue_id(issue: Issue, backend_type: str) -> str:
|
||||||
|
"""Return the identifier accepted by the backend's issue routes.
|
||||||
|
|
||||||
|
Forgejo/Gitea exposes both a database-wide ``id`` and a repository-local
|
||||||
|
issue ``number``. Its issue CRUD routes address the latter, so returning
|
||||||
|
the database ID from ingestion makes the documented POST -> PATCH lifecycle
|
||||||
|
fail with 404. Local backends continue to expose their native string ID.
|
||||||
|
"""
|
||||||
|
if backend_type in {"gitea", "github"} and issue.number:
|
||||||
|
return str(issue.number)
|
||||||
|
if issue.id:
|
||||||
|
return issue.id
|
||||||
|
return str(issue.number)
|
||||||
|
|
||||||
|
|
||||||
def _upsert_mapping_if_requested(
|
def _upsert_mapping_if_requested(
|
||||||
payload: TaskIngestionRequest,
|
payload: TaskIngestionRequest,
|
||||||
*,
|
*,
|
||||||
|
|
@ -184,7 +199,7 @@ async def ingest_task(payload: TaskIngestionRequest) -> TaskIngestionResponse:
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
issue_id = created.id or str(created.number)
|
issue_id = _public_issue_id(created, backend_type)
|
||||||
issue_url: Optional[str] = None
|
issue_url: Optional[str] = None
|
||||||
if created.sync_metadata:
|
if created.sync_metadata:
|
||||||
issue_url = created.sync_metadata.get("url") or created.sync_metadata.get("html_url")
|
issue_url = created.sync_metadata.get("url") or created.sync_metadata.get("html_url")
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import os
|
||||||
import tempfile
|
import tempfile
|
||||||
import uuid
|
import uuid
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from types import SimpleNamespace
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
@ -15,6 +16,7 @@ pytest.importorskip("httpx")
|
||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
|
|
||||||
from issue_core.api.app import create_app
|
from issue_core.api.app import create_app
|
||||||
|
from issue_core.api.ingest import _public_issue_id
|
||||||
|
|
||||||
|
|
||||||
API_KEY = "test-key-not-a-real-secret-only-for-pytest"
|
API_KEY = "test-key-not-a-real-secret-only-for-pytest"
|
||||||
|
|
@ -75,6 +77,20 @@ def test_healthz(client):
|
||||||
assert response.json()["status"] == "ok"
|
assert response.json()["status"] == "ok"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
def test_public_issue_id_uses_repository_number_for_gitea():
|
||||||
|
issue = SimpleNamespace(id="91234", number=176)
|
||||||
|
|
||||||
|
assert _public_issue_id(issue, "gitea") == "176"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.unit
|
||||||
|
def test_public_issue_id_preserves_native_local_id():
|
||||||
|
issue = SimpleNamespace(id="2c29792e-1234-4567-890a-22c4fa664abc", number=12)
|
||||||
|
|
||||||
|
assert _public_issue_id(issue, "local") == issue.id
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.unit
|
@pytest.mark.unit
|
||||||
def test_ingest_rejects_missing_api_key(client, valid_payload):
|
def test_ingest_rejects_missing_api_key(client, valid_payload):
|
||||||
response = client.post("/issues/", json=valid_payload)
|
response = client.post("/issues/", json=valid_payload)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue