From 3c6614820580ecacc8c27810a66396813dd1c69b Mon Sep 17 00:00:00 2001 From: tegwick Date: Thu, 25 Jun 2026 19:40:15 +0200 Subject: [PATCH] Fix Gitea issue label payloads --- issue_core/__init__.py | 2 +- issue_core/backends/gitea/backend.py | 18 ++++++++++++++---- tests/test_gitea_backend.py | 25 +++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/issue_core/__init__.py b/issue_core/__init__.py index e9a0eee..9778f34 100644 --- a/issue_core/__init__.py +++ b/issue_core/__init__.py @@ -19,6 +19,6 @@ Supported Backends: - Future: GitHub, GitLab, JIRA, Redmine """ -__version__ = "0.2.0" +__version__ = "0.2.1" __author__ = "Coulomb / MarkiTect Project" __description__ = "Authoritative task lifecycle manager with plugin architecture" diff --git a/issue_core/backends/gitea/backend.py b/issue_core/backends/gitea/backend.py index ed4887d..4ed4b15 100644 --- a/issue_core/backends/gitea/backend.py +++ b/issue_core/backends/gitea/backend.py @@ -195,10 +195,20 @@ class GiteaBackend(RemoteBackend, SyncableBackend): if issue.milestone: data['milestone'] = int(issue.milestone.backend_id) if issue.milestone.backend_id else None - # Convert labels - if issue.labels: - data['labels'] = [label.name for label in issue.labels] - + # Gitea expects numeric label IDs on issue create/update. Name-only + # labels are preserved in issue-core metadata but omitted from the API + # payload until a label-resolution step exists. + label_ids = [] + for label in issue.labels: + if not label.backend_id: + continue + try: + label_ids.append(int(label.backend_id)) + except (TypeError, ValueError): + continue + if label_ids: + data['labels'] = label_ids + return data # Issue CRUD Operations diff --git a/tests/test_gitea_backend.py b/tests/test_gitea_backend.py index 73df749..e3107c8 100644 --- a/tests/test_gitea_backend.py +++ b/tests/test_gitea_backend.py @@ -6,8 +6,10 @@ These tests ensure the Gitea backend works correctly with the API. import pytest import json +from datetime import datetime, timezone from unittest.mock import Mock, patch, MagicMock from issue_core.backends.gitea.backend import GiteaBackend, GiteaAPIError +from issue_core.core.models import Issue, IssueState, Label class TestGiteaBackend: @@ -96,6 +98,29 @@ class TestGiteaBackend: called_url = mock_request.call_args[1]['url'] if 'url' in mock_request.call_args[1] else mock_request.call_args[0][1] assert called_url == 'https://git.example.com/api/v1/repos/owner/repo' + def test_gitea_payload_omits_name_only_labels(self): + """Gitea issue payloads only include numeric label IDs.""" + now = datetime.now(timezone.utc) + issue = Issue( + id="", + number=0, + title="Test issue", + description="Test description", + state=IssueState.OPEN, + created_at=now, + updated_at=now, + labels=[ + Label(name="priority:low"), + Label(name="source:rule", backend_id="not-a-number"), + Label(name="existing", backend_id="42"), + ], + ) + + payload = self.backend._unified_issue_to_gitea(issue) + + assert payload["labels"] == [42] + assert payload["title"] == "Test issue" + @patch('issue_core.backends.gitea.backend.requests.Session') def test_test_connection_success(self, mock_session_class): """Test test_connection method works correctly."""