Skip to content

Commit

Permalink
HPCC-31397 Jirabot improvements / Cloud Jira support
Browse files Browse the repository at this point in the history
- Externalized variables that differ between the Jira versions
- Externalized variables that change such as user mappings
- Added support for addtional workflow transitions
- Added support for Cloud Jira
- Changed PR attachment logic to post additional PRs in a Jira comment
- Changed comment code to use Jira API to post comments

Signed-off-by: James McMullan [email protected]
  • Loading branch information
jpmcmu committed Mar 22, 2024
1 parent a418c0b commit 57654c4
Showing 1 changed file with 110 additions and 50 deletions.
160 changes: 110 additions & 50 deletions .github/workflows/jirabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,80 +24,140 @@ jobs:
python -m site
python -m pip install --upgrade pip setuptools wheel
python -m pip install --upgrade jira
python -m pip --version
python -m pip freeze | grep jira
- name: "Run"
env:
env:
JIRABOT_USERNAME : ${{ secrets.JIRABOT_USERNAME }}
JIRABOT_PASSWORD : ${{ secrets.JIRABOT_PASSWORD }}
JIRA_URL : ${{ secrets.JIRA_URL }}
JIRA_URL : ${{ vars.JIRA_URL }}
PULL_REQUEST_NUMBER : ${{ github.event.pull_request.number }}
PULL_REQUEST_TITLE : ${{ github.event.pull_request.title }}
PULL_REQUEST_AUTHOR_NAME : ${{ github.event.pull_request.user.login }}
PULL_URL: ${{ github.event.pull_request.html_url }}
COMMENTS_URL: ${{ github.event.pull_request.comments_url }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

GHUB_JIRA_USER_MAP: ${{ vars.GHUB_JIRA_USER_MAP }}
JIRA_ISSUE_PROPERTY_MAP: ${{ vars.JIRA_ISSUE_PROPERTY_MAP }}
JIRA_ISSUE_TRANSITION_MAP: ${{ vars.JIRA_ISSUE_TRANSITION_MAP }}
run: |
import os
import re
import time
import json
from jira.client import JIRA
def updateIssue(jira, issue, prAuthorEmail : str, transitionMap: dict, propertyMap: dict, pull_url: str) -> str:
result = ''
statusName = str(issue.fields.status)
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)
result += 'Workflow Transition: ' + transition + '\n'
except Exception as error:
transitions = jira.transitions(issue)
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:
currentPR = None
print('Error: Unable to get current pull request with field name: ' + prFieldName)
if currentPR is None:
issue.update(fields={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'
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)
return result
jirabot_user = os.environ['JIRABOT_USERNAME']
jirabot_pass = os.environ['JIRABOT_PASSWORD']
jira_url = os.environ['JIRA_URL']
pr = os.environ['PULL_REQUEST_NUMBER']
title = os.environ['PULL_REQUEST_TITLE']
user = os.environ['PULL_REQUEST_AUTHOR_NAME']
comments_url = os.environ['COMMENTS_URL']
prAuthor = os.environ['PULL_REQUEST_AUTHOR_NAME']
pull_url = os.environ['PULL_URL']
github_token = os.environ['GITHUB_TOKEN']
print("%s %s %s" % (title, user, comments_url))
status = ''
issuem = re.search("(HPCC|HH|IDE|EPE|ML|JAPI)-[0-9]+", title)
comments_url = os.environ['COMMENTS_URL']
print("%s %s %s" % (title, prAuthor, comments_url))
result = ''
issuem = re.search("(HPCC|HH|IDE|EPE|ML|HPCC4J|JAPI)-[0-9]+", title)
if issuem:
issue_name = issuem.group()
if user == 'dehilsterlexis':
user = 'dehilster'
if user == 'kunalaswani':
user = 'kunal.aswani'
if user == 'timothyklemm':
user = 'klemti01'
if user == 'jpmcmu':
user = 'mcmuja01'
if user == 'asselitx':
user = 'terrenceasselin'
if user == 'jeclrsg':
user = 'clemje01'
if user == 'jackdelv':
user = 'delvecja'
userDict = json.loads(os.environ['GHUB_JIRA_USER_MAP'])
if not isinstance(userDict, dict):
userDict = {}
if prAuthor in userDict:
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))
issue = jira.issue(issue_name)
status = jira_url + '/browse/' + issue_name + '\\n'
if False and issue.fields.status.name != 'Active' and issue.fields.status.name != 'Open' and issue.fields.status.name != 'New' and issue.fields.status.name != 'Discussing' and issue.fields.status.name != 'Awaiting Information':
status += 'Jira not updated (state was not active or new)'
elif issue.fields.customfield_10010 != None:
if issue.fields.customfield_10010 != pull_url:
status += 'Jira not updated (pull request "%s" already registered)' % issue.fields.customfield_10010
else:
status += 'This pull request is already registered'
elif issue.fields.assignee is not None and issue.fields.assignee.name.lower() != user.lower():
status += 'Jira not updated (user does not match)'
else:
if issue.fields.assignee is None:
jira.assign_issue(issue, user)
issue.update(fields={'customfield_10010': pull_url})
issue = jira.issue(issue_name)
# Check if the jira session is valid, if not retry authentication
# This appears to be an issue with the Cloud Jira / Python library
for attempt in range(3):
try:
transitions = jira.transitions(issue)
jira.transition_issue(issue, '291') # Attach Pull Request
except:
status += 'Failed to set to merge pending: transitions=%s' % transitions
status += 'Jira updated'
print('curl -X POST %s -H "Content-Type: application/json" -H "Authorization: token %s" --data \'{ "body": "%s" }\'' % ( comments_url, github_token, status ))
os.system('curl -X POST %s -H "Content-Type: application/json" -H "Authorization: token %s" --data \'{ "body": "%s" }\'' % ( comments_url, github_token, status ))
print(status)
shell: python
jira.session()
break
except Exception as error:
print('Service account authentication failed, retrying in 10s.')
time.sleep(10)
jira = JIRA(options=options, basic_auth=(jirabot_user, jirabot_pass))
userSearchResults = jira.search_users(query=prAuthor)
if userSearchResults and len(userSearchResults) > 0:
jiraUser = userSearchResults[0]
jiraUserEmail = None
if jiraUser is None:
print('Error: Unable to find Jira user: ' + prAuthor + ' continuing without assigning')
else:
jiraUserEmail = jiraUser.emailAddress
issue = jira.issue(issue_name)
result = 'Jirabot Action Result:\n'
transitionMap = json.loads(os.environ['JIRA_ISSUE_TRANSITION_MAP'])
if not isinstance(transitionMap, dict):
print('Error: JIRA_ISSUE_TRANSITION_MAP is not a valid JSON object, ignoring.')
transitionMap = {}
jiraIssuePropertyMap = json.loads(os.environ['JIRA_ISSUE_PROPERTY_MAP'])
if not isinstance(jiraIssuePropertyMap, dict):
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)
else:
print('Unable to find Jira issue name in title')
print(result)
shell: python

0 comments on commit 57654c4

Please sign in to comment.