From 0e2c37c4bef9c00085e8f1d9cc573907ceb36dd6 Mon Sep 17 00:00:00 2001 From: James McMullan Date: Thu, 28 Mar 2024 09:16:57 -0400 Subject: [PATCH] HPCC4J-574 Jirabot Improvements - Updated Jirabot to use Atlassian python library - Updated Jirabot to leave a comment on the Github PR Signed-off-by: James McMullan James.McMullan@lexisnexis.com --- .github/workflows/Jirabot.yml | 103 ++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 49 deletions(-) diff --git a/.github/workflows/Jirabot.yml b/.github/workflows/Jirabot.yml index a0c295916..7bdcd1632 100644 --- a/.github/workflows/Jirabot.yml +++ b/.github/workflows/Jirabot.yml @@ -14,7 +14,7 @@ jobs: jirabot: runs-on: ubuntu-20.04 steps: - - uses: "actions/setup-python@v2" + - uses: "actions/setup-python@v5" with: python-version: "3.8" - name: "Install dependencies" @@ -23,9 +23,8 @@ jobs: python -VV python -m site python -m pip install --upgrade pip setuptools wheel - python -m pip install --upgrade jira + python -m pip install --upgrade atlassian-python-api python -m pip --version - python -m pip freeze | grep jira - name: "Run" env: JIRABOT_USERNAME : ${{ secrets.JIRABOT_USERNAME }} @@ -43,49 +42,61 @@ jobs: run: | import os import re + import time + import sys import json - from jira.client import JIRA + from atlassian.jira import Jira - def updateIssue(jira, issue, prAuthorEmail : str, transitionMap: dict, propertyMap: dict, pull_url: str) -> str: + def updateIssue(jira, issue, prAuthor : str, transitionMap: dict, propertyMap: dict, pull_url: str) -> str: result = '' - statusName = str(issue.fields.status) + issueName = issue['key'] + issueFields = issue['fields'] + + statusName = str(issueFields['status']['name']) transition = transitionMap.get(statusName, None) if transition == None: print('Error: Unable to find transition for status: ' + statusName) elif transition != '': try: - jira.transition_issue(issue, transition) + jira.issue_transition(issueName, transition) result += 'Workflow Transition: ' + transition + '\n' except Exception as error: - transitions = jira.transitions(issue) + transitions = jira.get_issue_transitions(issueName) result += 'Error: Transition: "' + transition + '" failed with: "' + str(error) + '" Valid transitions=' + str(transitions) + '\n' prFieldName = propertyMap.get('pullRequestFieldName', 'customfield_10010') - try: - currentPR = getattr(issue.fields, prFieldName) - except: + + if prFieldName in issueFields: + currentPR = issueFields[prFieldName] + else: + print('Error: Unable to find pull request field with field name: ' + prFieldName) currentPR = None - print('Error: Unable to get current pull request with field name: ' + prFieldName) if currentPR is None: - issue.update(fields={prFieldName: pull_url}) + jira.update_issue_field(issueName, {prFieldName: pull_url}) result += 'Updated PR\n' elif currentPR is not None and currentPR != pull_url: result += 'Additional PR: ' + pull_url + '\n' - if prAuthorEmail: - if issue.fields.assignee is None: - jira.assign_issue(issue, prAuthorEmail) - result += 'Assigning user: ' + prAuthorEmail + '\n' + if prAuthor: + assignee = issueFields['assignee'] + if assignee is None: + assigneeId = '' + assigneeEmail = '' else: - assigneeEmail = None - if issue.fields.assignee: - assigneeEmail = issue.fields.assignee.emailAddress - if assigneeEmail is None or assigneeEmail.lower() != assigneeEmail.lower(): - result += 'Changing assignee from: ' + assigneeEmail + ' to: ' + prAuthorEmail + '\n' - jira.assign_issue(issue, prAuthorEmail) + assigneeId = assignee['accountId'] + assigneeEmail = assignee["emailAddress"] + + prAuthorId = prAuthor["accountId"] + prAuthorEmail = prAuthor["emailAddress"] + if assigneeId is None or assigneeId == '': + jira.assign_issue(issueName, prAuthorId) + result += 'Assigning user: ' + prAuthorEmail + '\n' + elif assigneeId != prAuthorId: + result += 'Changing assignee from: ' + assigneeEmail + ' to: ' + prAuthorEmail + '\n' + jira.assign_issue(issueName, prAuthorId) return result @@ -114,34 +125,20 @@ jobs: prAuthor = userDict.get(prAuthor) print('Mapped Github user to Jira user: ' + prAuthor) - options = { - 'server': jira_url - } - - jira = JIRA(options=options, basic_auth=(jirabot_user, jirabot_pass)) + jira = Jira(url=jira_url, username= jirabot_user, password= jirabot_pass, cloud=True) - # Need to change how we find users for Jira Cloud, unfortunately the API doesn't provide this information. - # At the moment checking if the URL contains atlassian.net appears to be the easiest way to determine if it's Jira Cloud. - isJiraCloud = False - if jira_url.find('atlassian.net') > 0: - isJiraCloud = True - - if isJiraCloud: - res = jira.search_users(query=prAuthor) - if res and len(res) > 0: - jiraUser = res[0] + jiraUser = None + userSearchResults = jira.user_find_by_user_string(query=prAuthor) + if userSearchResults and len(userSearchResults) > 0: + jiraUser = userSearchResults[0] else: - jiraUser = jira.user(prAuthor) - - jiraUserEmail = None - if jiraUser is None: print('Error: Unable to find Jira user: ' + prAuthor + ' continuing without assigning') - else: - jiraUserEmail = jiraUser.emailAddress - print("Jira User Email:" + str(jiraUserEmail)) + if not jira.issue_exists(issue_name): + sys.exit('Error: Unable to find Jira issue: ' + issue_name) + else: + issue = jira.issue(issue_name) - issue = jira.issue(issue_name) result = 'Jirabot Action Result:\n' transitionMap = json.loads(os.environ['JIRA_ISSUE_TRANSITION_MAP']) @@ -154,10 +151,18 @@ jobs: print('Error: JIRA_ISSUE_PROPERTY_MAP is not a valid JSON object, ignoring.') jiraIssuePropertyMap = {} - result += updateIssue(jira, issue, jiraUserEmail, transitionMap, jiraIssuePropertyMap, pull_url) - jira.add_comment(issue, result) + result += updateIssue(jira, issue, jiraUser, transitionMap, jiraIssuePropertyMap, pull_url) + jira.issue_add_comment(issue_name, result) + + result = 'Jira Issue: ' + jira_url + '/browse/' + issue_name + '\n\n' + result + + # Escape the result for JSON + result = json.dumps(result) + + curlCommand = 'curl -X POST %s -H "Content-Type: application/json" -H "Authorization: token %s" --data \'{ "body": %s }\'' % ( comments_url, github_token, result ) + os.system(curlCommand) else: print('Unable to find Jira issue name in title') print(result) - shell: python + shell: python \ No newline at end of file