From 31f9964d1f07b6a4c2f449203b1b85766c555850 Mon Sep 17 00:00:00 2001 From: "Jon Michael Aanes (aider)" Date: Tue, 15 Apr 2025 23:14:30 +0200 Subject: [PATCH] feat: add issue commenting on PR creation and push failures --- aider_gitea/__init__.py | 50 ++++++++++++---- aider_gitea/gitea_client.py | 22 +++++++ test/test_issue_comment_on_failure.py | 86 +++++++++++++++++++++++++++ 3 files changed, 147 insertions(+), 11 deletions(-) create mode 100644 test/test_issue_comment_on_failure.py diff --git a/aider_gitea/__init__.py b/aider_gitea/__init__.py index d966ff8..3548911 100644 --- a/aider_gitea/__init__.py +++ b/aider_gitea/__init__.py @@ -228,19 +228,47 @@ def push_changes( # First push the branch without creating a PR cmd = ['git', 'push', 'origin', branch_name, '--force'] - run_cmd(cmd, cwd) + push_success = run_cmd(cmd, cwd, check=False) + + if not push_success: + error_message = f"Failed to push branch '{branch_name}'. The changes could not be uploaded to the repository." + logger.error(error_message) + try: + gitea_client.create_issue_comment( + owner=owner, + repo=repo, + issue_number=issue_number, + body=f"❌ **Automated Solution Failed**\n\n{error_message}\n\nPlease check repository permissions and try again." + ) + except Exception as e: + logger.exception(f"Failed to comment on issue #{issue_number} after push failure: {e}") + return False # Then create the PR with the aider label - gitea_client.create_pull_request( - owner=owner, - repo=repo, - title=issue_title, - body=description, - head=branch_name, - base=base_branch, - labels=['aider'], - ) - return True + try: + gitea_client.create_pull_request( + owner=owner, + repo=repo, + title=issue_title, + body=description, + head=branch_name, + base=base_branch, + labels=['aider'], + ) + return True + except Exception as e: + error_message = f"Failed to create pull request for branch '{branch_name}': {str(e)}" + logger.exception(error_message) + try: + gitea_client.create_issue_comment( + owner=owner, + repo=repo, + issue_number=issue_number, + body=f"❌ **Automated Solution Failed**\n\n{error_message}\n\nThe changes were pushed to branch `{branch_name}` but creating a pull request failed." + ) + except Exception as comment_error: + logger.exception(f"Failed to comment on issue #{issue_number} after PR creation failure: {comment_error}") + return False def has_commits_on_branch(cwd: Path, base_branch: str, current_branch: str) -> bool: diff --git a/aider_gitea/gitea_client.py b/aider_gitea/gitea_client.py index 267c3c7..c583028 100644 --- a/aider_gitea/gitea_client.py +++ b/aider_gitea/gitea_client.py @@ -169,3 +169,25 @@ class GiteaClient: response = self.session.post(url, json=json_data) response.raise_for_status() return response.json() + + def create_issue_comment(self, owner: str, repo: str, issue_number: str, body: str) -> dict: + """Create a comment on an issue. + + Args: + owner (str): Owner of the repository. + repo (str): Name of the repository. + issue_number (str): The issue number to comment on. + body (str): The content of the comment. + + Returns: + dict: The created comment data. + + Raises: + requests.HTTPError: If the API request fails. + """ + url = f'{self.gitea_url}/repos/{owner}/{repo}/issues/{issue_number}/comments' + json_data = {'body': body} + + response = self.session.post(url, json=json_data) + response.raise_for_status() + return response.json() diff --git a/test/test_issue_comment_on_failure.py b/test/test_issue_comment_on_failure.py new file mode 100644 index 0000000..1cf8c58 --- /dev/null +++ b/test/test_issue_comment_on_failure.py @@ -0,0 +1,86 @@ +import pytest +from unittest.mock import MagicMock, patch +from pathlib import Path + +from aider_gitea import push_changes + + +class TestIssueCommentOnFailure: + def setup_method(self): + self.cwd = Path('/tmp/test-repo') + self.branch_name = 'issue-123-test-branch' + self.issue_number = '123' + self.issue_title = 'Test Issue' + self.base_branch = 'main' + self.gitea_client = MagicMock() + self.owner = 'test-owner' + self.repo = 'test-repo' + + @patch('aider_gitea.run_cmd', return_value=False) + @patch('aider_gitea.has_commits_on_branch', return_value=True) + @patch('aider_gitea.get_commit_messages', return_value=['Test commit']) + def test_comment_on_push_failure(self, mock_get_commit_messages, mock_has_commits, mock_run_cmd): + """Test that a comment is added to the issue when git push fails.""" + result = push_changes( + self.cwd, + self.branch_name, + self.issue_number, + self.issue_title, + self.base_branch, + self.gitea_client, + self.owner, + self.repo, + ) + + assert result is False + self.gitea_client.create_issue_comment.assert_called_once() + comment_body = self.gitea_client.create_issue_comment.call_args[1]['body'] + assert "Failed to push branch" in comment_body + assert "❌ **Automated Solution Failed**" in comment_body + + @patch('aider_gitea.run_cmd', return_value=True) + @patch('aider_gitea.has_commits_on_branch', return_value=True) + @patch('aider_gitea.get_commit_messages', return_value=['Test commit']) + def test_comment_on_pr_creation_failure(self, mock_get_commit_messages, mock_has_commits, mock_run_cmd): + """Test that a comment is added to the issue when PR creation fails.""" + self.gitea_client.create_pull_request.side_effect = Exception("PR creation failed") + + result = push_changes( + self.cwd, + self.branch_name, + self.issue_number, + self.issue_title, + self.base_branch, + self.gitea_client, + self.owner, + self.repo, + ) + + assert result is False + self.gitea_client.create_issue_comment.assert_called_once() + comment_body = self.gitea_client.create_issue_comment.call_args[1]['body'] + assert "Failed to create pull request" in comment_body + assert "❌ **Automated Solution Failed**" in comment_body + assert self.branch_name in comment_body + + @patch('aider_gitea.run_cmd', return_value=True) + @patch('aider_gitea.has_commits_on_branch', return_value=True) + @patch('aider_gitea.get_commit_messages', return_value=['Test commit']) + def test_comment_failure_handled(self, mock_get_commit_messages, mock_has_commits, mock_run_cmd): + """Test that exceptions during commenting are properly handled.""" + self.gitea_client.create_pull_request.side_effect = Exception("PR creation failed") + self.gitea_client.create_issue_comment.side_effect = Exception("Comment creation failed") + + # This should not raise an exception + result = push_changes( + self.cwd, + self.branch_name, + self.issue_number, + self.issue_title, + self.base_branch, + self.gitea_client, + self.owner, + self.repo, + ) + + assert result is False