Coverage for src\gibr\trackers\jira.py: 100%

23 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-10-20 09:51 +0300

1"""Jira issue tracker implementation.""" 

2 

3from jira import JIRA 

4from jira.exceptions import JIRAError 

5 

6from gibr.issue import Issue 

7from gibr.notify import error 

8 

9from .base import IssueTracker 

10 

11 

12class JiraTracker(IssueTracker): 

13 """Jira issue tracker.""" 

14 

15 def __init__(self, url: str, user: str, token: str, project_key: str): 

16 """Construct JiraTracker object.""" 

17 self.project_key = project_key 

18 try: 

19 self.client = JIRA(server=url, basic_auth=(user, token)) 

20 except JIRAError as e: 

21 raise ValueError(f"Failed to connect to Jira: {e.text}") 

22 

23 def get_issue(self, issue_id: str) -> dict: 

24 """Fetch issue details by issue number (using project key).""" 

25 issue_key = f"{self.project_key}-{issue_id}" 

26 try: 

27 issue = self.client.issue(issue_key) 

28 except JIRAError: 

29 error(f"Issue {issue_key} not found in Jira project {self.project_key}.") 

30 

31 return Issue( 

32 id=issue.key, 

33 title=issue.fields.summary, 

34 type=issue.fields.issuetype.name, 

35 ) 

36 

37 def list_issues(self) -> list[dict]: 

38 """List open issues in the Jira project.""" 

39 jql = ( 

40 f'project = "{self.project_key}" ' 

41 "AND statusCategory != Done " 

42 "ORDER BY created DESC" 

43 ) 

44 issues = self.client.search_issues(jql) 

45 return [ 

46 Issue( 

47 id=issue.key, 

48 title=issue.fields.summary, 

49 type=issue.fields.issuetype.name, 

50 ) 

51 for issue in issues 

52 ]