fix: Resolve label assignment issue using dedicated Gitea API endpoint
- Update ProjectManager.set_issue_state() to use /issues/{id}/labels endpoint with PUT method
- Update ProjectManager.set_issue_priority() to use dedicated labels endpoint
- Update IssueWriter.update_labels() to use dedicated labels endpoint for reliability
- Fix API format incompatibility where issue PATCH endpoint was ignoring label updates
- Label assignment now works correctly with proper state and priority management
- Issues will now properly appear in correct Kanban columns based on status labels
Root cause: Gitea API issue PATCH endpoint silently ignores label updates, but the
dedicated labels endpoint (/issues/{id}/labels) with PUT method works correctly.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -90,8 +90,50 @@ class IssueWriter:
|
|||||||
return self.update_issue(issue_number, {'milestone': None})
|
return self.update_issue(issue_number, {'milestone': None})
|
||||||
|
|
||||||
def update_labels(self, issue_number: int, labels: list) -> Dict[str, Any]:
|
def update_labels(self, issue_number: int, labels: list) -> Dict[str, Any]:
|
||||||
"""Update issue labels completely."""
|
"""Update issue labels completely using dedicated labels endpoint."""
|
||||||
return self.update_issue(issue_number, {'labels': labels})
|
if not self.auth_token:
|
||||||
|
raise IssueError("Authentication token required for label updates")
|
||||||
|
|
||||||
|
# Use the dedicated labels endpoint which works more reliably
|
||||||
|
url = f"{self.config.issues_api_url}/{issue_number}/labels"
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Use PUT to replace all labels
|
||||||
|
curl_cmd = [
|
||||||
|
'curl', '-s', '-X', 'PUT',
|
||||||
|
'-H', 'Content-Type: application/json',
|
||||||
|
'-H', f'Authorization: token {self.auth_token}',
|
||||||
|
'-d', json.dumps({'labels': labels}),
|
||||||
|
url
|
||||||
|
]
|
||||||
|
|
||||||
|
result = subprocess.run(
|
||||||
|
curl_cmd,
|
||||||
|
stdout=PIPE,
|
||||||
|
stderr=PIPE,
|
||||||
|
universal_newlines=True,
|
||||||
|
check=True
|
||||||
|
)
|
||||||
|
|
||||||
|
if result.returncode != 0:
|
||||||
|
raise IssueError(f"Failed to update labels for issue #{issue_number}: {result.stderr}")
|
||||||
|
|
||||||
|
# Parse the response - labels endpoint returns array of labels
|
||||||
|
if result.stdout.strip():
|
||||||
|
response_data = json.loads(result.stdout)
|
||||||
|
|
||||||
|
# Convert labels response back to issue format for consistency
|
||||||
|
return {
|
||||||
|
'number': issue_number,
|
||||||
|
'labels': response_data if isinstance(response_data, list) else []
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
return {'number': issue_number, 'labels': []}
|
||||||
|
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
raise IssueError(f"Failed to update labels for issue #{issue_number}: {e}")
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
raise IssueError(f"Failed to parse labels response: {e}")
|
||||||
|
|
||||||
def add_labels(self, issue_number: int, new_labels: list) -> Dict[str, Any]:
|
def add_labels(self, issue_number: int, new_labels: list) -> Dict[str, Any]:
|
||||||
"""Add labels to issue (preserving existing labels)."""
|
"""Add labels to issue (preserving existing labels)."""
|
||||||
|
|||||||
@@ -251,7 +251,10 @@ class ProjectManager:
|
|||||||
|
|
||||||
def set_issue_state(self, issue_number: int, state: ProjectState) -> Dict[str, Any]:
|
def set_issue_state(self, issue_number: int, state: ProjectState) -> Dict[str, Any]:
|
||||||
"""Set issue project state using labels."""
|
"""Set issue project state using labels."""
|
||||||
# First remove any existing state labels
|
# Use the dedicated labels endpoint which works more reliably
|
||||||
|
labels_url = f"{self.config.issues_api_url}/{issue_number}/labels"
|
||||||
|
|
||||||
|
# First get current labels
|
||||||
issue_url = f"{self.config.issues_api_url}/{issue_number}"
|
issue_url = f"{self.config.issues_api_url}/{issue_number}"
|
||||||
issue_data = self._make_api_call('GET', issue_url)
|
issue_data = self._make_api_call('GET', issue_url)
|
||||||
|
|
||||||
@@ -266,12 +269,16 @@ class ProjectManager:
|
|||||||
# Add new state label
|
# Add new state label
|
||||||
current_labels.append(state.value)
|
current_labels.append(state.value)
|
||||||
|
|
||||||
# Update issue with new labels
|
# Use PUT to replace all labels on the dedicated labels endpoint
|
||||||
data = {'labels': current_labels}
|
data = {'labels': current_labels}
|
||||||
return self._make_api_call('PATCH', issue_url, data)
|
return self._make_api_call('PUT', labels_url, data)
|
||||||
|
|
||||||
def set_issue_priority(self, issue_number: int, priority: Priority) -> Dict[str, Any]:
|
def set_issue_priority(self, issue_number: int, priority: Priority) -> Dict[str, Any]:
|
||||||
"""Set issue priority using labels."""
|
"""Set issue priority using labels."""
|
||||||
|
# Use the dedicated labels endpoint which works more reliably
|
||||||
|
labels_url = f"{self.config.issues_api_url}/{issue_number}/labels"
|
||||||
|
|
||||||
|
# First get current labels
|
||||||
issue_url = f"{self.config.issues_api_url}/{issue_number}"
|
issue_url = f"{self.config.issues_api_url}/{issue_number}"
|
||||||
issue_data = self._make_api_call('GET', issue_url)
|
issue_data = self._make_api_call('GET', issue_url)
|
||||||
|
|
||||||
@@ -286,9 +293,9 @@ class ProjectManager:
|
|||||||
# Add new priority label
|
# Add new priority label
|
||||||
current_labels.append(priority.value)
|
current_labels.append(priority.value)
|
||||||
|
|
||||||
# Update issue with new labels
|
# Use PUT to replace all labels on the dedicated labels endpoint
|
||||||
data = {'labels': current_labels}
|
data = {'labels': current_labels}
|
||||||
return self._make_api_call('PATCH', issue_url, data)
|
return self._make_api_call('PUT', labels_url, data)
|
||||||
|
|
||||||
def move_issue_to_done(self, issue_number: int) -> Dict[str, Any]:
|
def move_issue_to_done(self, issue_number: int) -> Dict[str, Any]:
|
||||||
"""Move issue to done state and close it."""
|
"""Move issue to done state and close it."""
|
||||||
|
|||||||
Reference in New Issue
Block a user