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
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-20 09:51 +0300
1"""Jira issue tracker implementation."""
3from jira import JIRA
4from jira.exceptions import JIRAError
6from gibr.issue import Issue
7from gibr.notify import error
9from .base import IssueTracker
12class JiraTracker(IssueTracker):
13 """Jira issue tracker."""
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}")
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}.")
31 return Issue(
32 id=issue.key,
33 title=issue.fields.summary,
34 type=issue.fields.issuetype.name,
35 )
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 ]