-
Notifications
You must be signed in to change notification settings - Fork 24
178 lines (149 loc) · 7.67 KB
/
Jirabot.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# JiraBot github action
# =====================
#
name: jirabot
on:
pull_request_target:
types: [opened, reopened]
branches:
- "master"
- "candidate-*"
jobs:
jirabot:
runs-on: ubuntu-20.04
steps:
- uses: "actions/setup-python@v5"
with:
python-version: "3.8"
- name: "Install dependencies"
run: |
set -xe
python -VV
python -m site
python -m pip install --upgrade pip setuptools wheel
python -m pip install --upgrade atlassian-python-api
python -m pip --version
- name: "Run"
env:
JIRABOT_USERNAME : ${{ secrets.JIRABOT_USERNAME }}
JIRABOT_PASSWORD : ${{ secrets.JIRABOT_PASSWORD }}
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 }}
run: |
import os
import re
import time
import sys
import json
import subprocess
from email.utils import parseaddr
from atlassian.jira import Jira
def sanitizeInput(input: str, inputType: str) -> str:
if inputType.lower() == 'email':
# Return the email address only, returns '' if not valid or found
return parseaddr(input)[1]
else:
return ''
def updateIssue(jira, issue, prAuthor : str, propertyMap: dict, pull_url: str) -> str:
result = ''
issueName = issue['key']
issueFields = issue['fields']
# Need to update user first in case we are starting from Unresourced
if prAuthor:
assignee = issueFields['assignee']
if assignee is None:
assigneeId = ''
assigneeEmail = ''
else:
assigneeId = assignee['accountId']
assigneeEmail = assignee["emailAddress"]
assigneeEmail = sanitizeInput(assigneeEmail, 'email')
prAuthorId = prAuthor["accountId"]
prAuthorEmail = prAuthor["emailAddress"]
prAuthorEmail = sanitizeInput(prAuthorEmail, 'email')
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)
# We should be able to transition directly to Merge Pending, keeping this for future reference
transitionFlow = ['Merge Pending']
# statusName = str(issueFields['status']['name'])
# if statusName == 'Awaiting Information' or statusName == 'Unresourced':
# transitionFlow = ['Accepted', 'Active', 'Merge Pending']
# elif statusName != 'Active':
# transitionFlow = ['Active', 'Merge Pending']
for desiredStatus in transitionFlow:
try:
transitionId = jira.get_transition_id_to_status_name(issueName, desiredStatus)
jira.set_issue_status_by_transition_id(issueName, transitionId)
result += 'Workflow Transition To: ' + desiredStatus + '\n'
except Exception as error:
transitions = jira.get_issue_transitions(issueName)
result += 'Error: Transitioning to: "' + desiredStatus + '" failed with: "' + str(error) + '" Valid transitions=' + str(transitions) + '\n'
prFieldName = propertyMap.get('pullRequestFieldName', 'customfield_10010')
if prFieldName in issueFields:
currentPR = issueFields[prFieldName]
else:
print('Error: Unable to find pull request field with field name: ' + prFieldName)
currentPR = None
if currentPR is None:
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'
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']
prAuthor = os.environ['PULL_REQUEST_AUTHOR_NAME']
pull_url = os.environ['PULL_URL']
github_token = os.environ['GITHUB_TOKEN']
comments_url = os.environ['COMMENTS_URL']
result = ''
issuem = re.search("(HPCC4J|JAPI)-[0-9]+", title)
if issuem:
nameCorrectionPattern = re.compile("hpcc4j", re.IGNORECASE)
issue_name = nameCorrectionPattern.sub("HPCC4J",issuem.group())
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)
jira = Jira(url=jira_url, username= jirabot_user, password= jirabot_pass, cloud=True)
jiraUser = None
userSearchResults = jira.user_find_by_user_string(query=prAuthor)
if userSearchResults and len(userSearchResults) > 0:
jiraUser = userSearchResults[0]
else:
print('Error: Unable to map GitHub user to Jira user, continuing without assigning')
if not jira.issue_exists(issue_name):
sys.exit('Error: Unable to find Jira issue: ' + issue_name)
else:
issue = jira.issue(issue_name)
result = 'Jirabot Action Result:\n'
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, jiraUser, 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)
subprocess.run(['curl', '-X', 'POST', comments_url, '-H', 'Content-Type: application/json', '-H', f'Authorization: token {github_token}', '--data', f'{{ "body": {result} }}'], check=True)
else:
print('Unable to find Jira issue name in title')
print(result)
shell: python