import os
from atlassian import Jira
from dotenv import load_dotenv
load_dotenv()
class JiraClient:
def __init__(self):
self.jira = Jira(
url=os.getenv("JIRA_BASE_URL"),
username=os.getenv("JIRA_EMAIL"),
password=os.getenv("JIRA_API_TOKEN")
)
def create_board(self, board_name: str, project_key: str):
# Jira Cloud doesn't expose "create board" directly in REST.
# Boards are tied to projects, so usually you create a project and board is auto-generated.
# For now, let's create a project (classic software project).
print("INSIDE 1")
payload = {
"key": project_key,
"name": board_name,
"projectTypeKey": "software",
"projectTemplateKey": "com.pyxis.greenhopper.jira:gh-scrum-template",
"lead": os.getenv("JIRA_EMAIL"),
}
return self.jira.post("/rest/api/3/project", data=payload)
def create_issue(self, project_key: str, summary: str, description: str, issue_type: str = "Task"):
print("INSIDE 2")
issue = {
"fields": {
"project": {"key": project_key},
"summary": summary,
"description": description,
"issuetype": {"name": issue_type}
}
}
return self.jira.issue_create(fields=issue["fields"])
def search_issues(self, query: str):
# JQL search
print("INSIDE 3")
return self.jira.jql(query)
def add_comment(self, issue_id: str, comment: str):
print("INSIDE 4")
return self.jira.issue_add_comment(issue_id, comment)
def change_status(self, issue_id: str, new_status: str):
print("INSIDE 5")
# Get transitions available for this issue
transitions = self.jira.get_issue_transitions(issue_id)
target = next((t for t in transitions["transitions"] if t["name"].lower() == new_status.lower()), None)
if not target:
return {"error": f"Status '{new_status}' not available", "available": [t["name"] for t in transitions["transitions"]]}
return self.jira.set_issue_status(issue_id, target["id"])