Skip to content

Commit 19467ed

Browse files
committed
HPCC4J-574 Jirabot improvements
- Moved github user dictionary to github action var - Changed logic for changing jira issue user - Added JirabotMerge to 8.12.x - Backported various Jirabot changes Signed-off-by: James McMullan [email protected]
1 parent 87ea98f commit 19467ed

File tree

2 files changed

+305
-44
lines changed

2 files changed

+305
-44
lines changed

.github/workflows/Jirabot.yml

Lines changed: 78 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -24,79 +24,113 @@ jobs:
2424
python -m site
2525
python -m pip install --upgrade pip setuptools wheel
2626
python -m pip install --upgrade jira
27+
python -m pip --version
28+
python -m pip freeze | grep jira
2729
- name: "Run"
2830
env:
2931
JIRABOT_USERNAME : ${{ secrets.JIRABOT_USERNAME }}
3032
JIRABOT_PASSWORD : ${{ secrets.JIRABOT_PASSWORD }}
31-
JIRA_URL : ${{ secrets.JIRA_URL }}
33+
JIRA_URL : ${{ vars.JIRA_URL }}
3234
PULL_REQUEST_NUMBER : ${{ github.event.pull_request.number }}
3335
PULL_REQUEST_TITLE : ${{ github.event.pull_request.title }}
3436
PULL_REQUEST_AUTHOR_NAME : ${{ github.event.pull_request.user.login }}
3537
PULL_URL: ${{ github.event.pull_request.html_url }}
3638
COMMENTS_URL: ${{ github.event.pull_request.comments_url }}
3739
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
38-
40+
GHUB_JIRA_USER_MAP: ${{ vars.GHUB_JIRA_USER_MAP }}
3941
run: |
4042
import os
4143
import re
44+
import json
4245
from jira.client import JIRA
4346
47+
def updateIssue(jira, issue, prAuthor: str, pull_url: str) -> str:
48+
result = ''
49+
50+
statusName = str(issue.fields.status)
51+
if statusName == 'Open':
52+
transition = 'Start Progress'
53+
elif statusName == 'In Progress':
54+
transition = ''
55+
elif statusName == 'Resolved':
56+
transition = 'Reopen Issue'
57+
elif statusName == 'Closed':
58+
transition = 'Reopen Issue'
59+
else:
60+
transition = ''
61+
62+
if transition != '':
63+
try:
64+
jira.transition_issue(issue, transition)
65+
result += 'Workflow Transition: ' + transition + '\n'
66+
except Exception as error:
67+
transitions = jira.transitions(issue)
68+
result += 'Error: Transition: "' + transition + '" failed with: "' + str(error) + '" Valid transitions=' + str(transitions) + '\n'
69+
70+
if issue.fields.customfield_10010 is None:
71+
issue.update(fields={'customfield_10010': pull_url})
72+
result += 'Updated PR\n'
73+
elif issue.fields.customfield_10010 is not None and issue.fields.customfield_10010 != pull_url:
74+
result += 'Additional PR: ' + pull_url + '\n'
75+
76+
if prAuthor:
77+
if issue.fields.assignee is None:
78+
jira.assign_issue(issue, prAuthor)
79+
result += 'Assigning user: ' + prAuthor + '\n'
80+
elif issue.fields.assignee is not None and issue.fields.assignee.name.lower() != prAuthor.lower():
81+
result += 'Changing assignee from: ' + issue.fields.assignee.name + ' to: ' + prAuthor + '\n'
82+
jira.assign_issue(issue, prAuthor)
83+
84+
return result
85+
4486
jirabot_user = os.environ['JIRABOT_USERNAME']
4587
jirabot_pass = os.environ['JIRABOT_PASSWORD']
4688
jira_url = os.environ['JIRA_URL']
4789
pr = os.environ['PULL_REQUEST_NUMBER']
4890
title = os.environ['PULL_REQUEST_TITLE']
49-
user = os.environ['PULL_REQUEST_AUTHOR_NAME']
50-
comments_url = os.environ['COMMENTS_URL']
91+
prAuthor = os.environ['PULL_REQUEST_AUTHOR_NAME']
5192
pull_url = os.environ['PULL_URL']
5293
github_token = os.environ['GITHUB_TOKEN']
94+
comments_url = os.environ['COMMENTS_URL']
5395
54-
print("%s %s %s" % (title, user, comments_url))
55-
status = ''
96+
print("%s %s %s" % (title, prAuthor, comments_url))
97+
result = ''
5698
issuem = re.search("(HPCC4J|JAPI)-[0-9]+", title)
5799
if issuem:
58100
nameCorrectionPattern = re.compile("hpcc4j", re.IGNORECASE)
59101
issue_name = nameCorrectionPattern.sub("JAPI",issuem.group())
60-
if user == 'kunalaswani':
61-
user = 'kunal.aswani'
62-
if user == 'timothyklemm':
63-
user = 'klemti01'
64-
if user == 'jpmcmu':
65-
user = 'mcmuja01'
66-
if user == 'asselitx':
67-
user = 'terrenceasselin'
68-
if user == 'jeclrsg':
69-
user = 'clemje01'
70-
if user == 'jackdelv':
71-
user = 'delvecja'
102+
103+
userDict = json.loads(os.environ['GHUB_JIRA_USER_MAP'])
104+
if not isinstance(userDict, dict):
105+
userDict = {}
106+
107+
if prAuthor in userDict:
108+
prAuthor = userDict.get(prAuthor)
109+
print('Mapped Github user to Jira user: ' + prAuthor)
110+
72111
options = {
73112
'server': jira_url
74113
}
114+
75115
jira = JIRA(options=options, basic_auth=(jirabot_user, jirabot_pass))
116+
117+
# Check if prAuthor exists in Jira
118+
try:
119+
jiraUser = jira.user(prAuthor)
120+
if jiraUser is None:
121+
prAuthor = None
122+
print('Error: Unable to find Jira user: ' + prAuthor + ' continuing without assigning')
123+
except Exception as error:
124+
prAuthor = None
125+
print('Error: Unable to find Jira user: ' + prAuthor + ' with error: ' + str(error) + ' continuing without assigning')
126+
76127
issue = jira.issue(issue_name)
77-
status = jira_url + '/browse/' + issue_name + '\\n'
78-
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':
79-
status += 'Jira not updated (state was not active or new)'
80-
elif issue.fields.customfield_10010 != None:
81-
if issue.fields.customfield_10010 != pull_url:
82-
status += 'Jira not updated (pull request "%s" already registered)' % issue.fields.customfield_10010
83-
else:
84-
status += 'This pull request is already registered'
85-
elif issue.fields.assignee is not None and issue.fields.assignee.name.lower() != user.lower():
86-
status += 'Jira not updated (user does not match)'
87-
else:
88-
if issue.fields.assignee is None:
89-
jira.assign_issue(issue, user)
90-
issue.update(fields={'customfield_10010': pull_url})
91-
issue = jira.issue(issue_name)
92-
try:
93-
transitions = jira.transitions(issue)
94-
jira.transition_issue(issue, '291') # Attach Pull Request
95-
except:
96-
status += 'Failed to set to merge pending: transitions=%s' % transitions
97-
status += 'Jira updated'
98-
print('curl -X POST %s -H "Content-Type: application/json" -H "Authorization: token %s" --data \'{ "body": "%s" }\'' % ( comments_url, github_token, status ))
99-
os.system('curl -X POST %s -H "Content-Type: application/json" -H "Authorization: token %s" --data \'{ "body": "%s" }\'' % ( comments_url, github_token, status ))
100-
101-
print(status)
102-
shell: python
128+
result = 'Jirabot Action Result:\n'
129+
130+
result += updateIssue(jira, issue, prAuthor, pull_url)
131+
jira.add_comment(issue, result)
132+
else:
133+
print('Unable to find Jira issue name in title')
134+
135+
print(result)
136+
shell: python

.github/workflows/JirabotMerge.yml

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
name: Jirabot - Merge
2+
3+
on:
4+
pull_request_target:
5+
types: [closed]
6+
branches:
7+
- "master"
8+
- "candidate-*"
9+
10+
jobs:
11+
jirabot:
12+
runs-on: ubuntu-latest
13+
if: github.event.pull_request.merged == true
14+
steps:
15+
- name: "Debug Vars"
16+
run: |
17+
echo "JIRA_URL: ${{ vars.JIRA_URL }}"
18+
echo "Pull Request Number: ${{ github.event.pull_request.number }}"
19+
echo "Pull Request Title: ${{ github.event.pull_request.title }}"
20+
echo "Pull Request Author Name: ${{ github.event.pull_request.user.login }}"
21+
echo "Pull Request URL: ${{ github.event.pull_request.html_url }}"
22+
echo "Comments URL: ${{ github.event.pull_request.comments_url }}"
23+
echo "Branch Name: ${{ github.ref_name }}"
24+
- uses: "actions/setup-python@v2"
25+
with:
26+
python-version: "3.8"
27+
- name: "Install dependencies"
28+
run: |
29+
set -xe
30+
python -VV
31+
python -m site
32+
python -m pip install --upgrade pip setuptools wheel
33+
python -m pip install --upgrade jira
34+
- name: "Checkout"
35+
uses: actions/checkout@v2
36+
with:
37+
ref: ${{ github.event.pull_request.base.ref }}
38+
fetch-depth: 0
39+
fetch-tags: true
40+
- name: "Run"
41+
env:
42+
JIRABOT_USERNAME : ${{ secrets.JIRABOT_USERNAME }}
43+
JIRABOT_PASSWORD : ${{ secrets.JIRABOT_PASSWORD }}
44+
JIRA_URL : ${{ vars.JIRA_URL }}
45+
PULL_REQUEST_NUMBER : ${{ github.event.pull_request.number }}
46+
PULL_REQUEST_TITLE : ${{ github.event.pull_request.title }}
47+
PULL_REQUEST_AUTHOR_NAME : ${{ github.event.pull_request.user.login }}
48+
PULL_URL: ${{ github.event.pull_request.html_url }}
49+
COMMENTS_URL: ${{ github.event.pull_request.comments_url }}
50+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
51+
BRANCH_NAME: ${{ github.ref_name }}
52+
53+
run: |
54+
import os
55+
import re
56+
import subprocess
57+
import time
58+
import sys
59+
from jira.client import JIRA
60+
61+
def extractVersion(versionStr):
62+
parts = versionStr.split('.')
63+
if len(parts) != 3:
64+
print('Invalid version: ' + version)
65+
sys.exit(1)
66+
if parts[2].lower() == 'x':
67+
parts[2] = '0'
68+
69+
major, minor, point = map(int, parts)
70+
return [major, minor, point]
71+
72+
def getTagVersionForCmd(cmd):
73+
versionPattern = re.compile(r".*([0-9]+\.[0-9]+\.[0-9]+).*")
74+
75+
# Get latest release version
76+
gitTagProcess = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
77+
(output, err) = gitTagProcess.communicate()
78+
gitTagProcessStatus = gitTagProcess.wait()
79+
80+
if gitTagProcessStatus != 0:
81+
print('Unable to retrieve latest git tag.')
82+
sys.exit(1)
83+
84+
latestGitTag = str(output)
85+
86+
versionMatch = versionPattern.match(latestGitTag)
87+
if versionMatch:
88+
return extractVersion(versionMatch.group(1))
89+
else:
90+
print('Unable to extract version from git tag.')
91+
sys.exit(2)
92+
93+
def buildVersionString(version):
94+
major, minor, point = map(int, version)
95+
return f"{major}.{minor}.{point}"
96+
97+
def generateFixVersionList(jira, branchName):
98+
99+
latestVersion = getTagVersionForCmd("git tag --list 'hpcc4j_*-release' --sort=-v:refname | head -n 1")
100+
101+
# If we are merging into master we assume it is going into the next minor release
102+
fixVersions = []
103+
if branchName == "master":
104+
fixVersions = [buildVersionString([latestVersion[0], latestVersion[1] + 2, 0])]
105+
else:
106+
# Extract candidate branch major / minor version
107+
candidateBranchPattern = re.compile(r"candidate-([0-9]+\.[0-9]+\.([0-9]+|x)).*")
108+
branchVersionMatch = candidateBranchPattern.match(branchName)
109+
branchVersion = extractVersion(branchVersionMatch.group(1))
110+
111+
# Get latest release in branch
112+
findLatestBranchVer = "git tag --list 'hpcc4j_" + str(branchVersion[0]) + "." + str(branchVersion[1]) + "*-release' --sort=-v:refname | head -n 1"
113+
latestBranchVer = getTagVersionForCmd(findLatestBranchVer)
114+
115+
curMajor = branchVersion[0]
116+
latestMajor = latestVersion[0]
117+
while curMajor <= latestMajor:
118+
latestVersionInMajor = getTagVersionForCmd("git tag --list 'hpcc4j_" + str(curMajor) + "*-release' --sort=-v:refname | head -n 1")
119+
120+
curMinor = 0
121+
if curMajor == branchVersion[0]:
122+
curMinor = branchVersion[1]
123+
124+
latestMinor = latestVersionInMajor[1]
125+
126+
while curMinor <= latestMinor:
127+
latestPointInMinor = getTagVersionForCmd("git tag --list 'hpcc4j_" + str(curMajor) + "." + str(curMinor) + "*-release' --sort=-v:refname | head -n 1")
128+
fixVersions.append(buildVersionString([latestPointInMinor[0], latestPointInMinor[1], latestPointInMinor[2] + 2]))
129+
curMinor += 2
130+
curMajor += 1
131+
132+
for fixVersion in fixVersions:
133+
alreadyHasFixVersion = False
134+
versions = jira.project_versions('JAPI')
135+
for v in versions:
136+
if v.name == fixVersion:
137+
alreadyHasFixVersion = True
138+
139+
if not alreadyHasFixVersion:
140+
jira.create_version(name=fixVersion, project='JAPI', description=fixVersion)
141+
142+
return fixVersions
143+
144+
def resolveIssue(jira, issue, fixVersions) -> str:
145+
result = ''
146+
147+
versionsToAdd = []
148+
149+
for addedVersion in fixVersions:
150+
alreadyHasFixVersion = False
151+
for v in issue.fields.fixVersions:
152+
if v.name == addedVersion:
153+
alreadyHasFixVersion = True
154+
break
155+
if not alreadyHasFixVersion:
156+
versionsToAdd.append(addedVersion)
157+
158+
versions = jira.project_versions('JAPI')
159+
updatedVersionList = []
160+
for v in issue.fields.fixVersions:
161+
updatedVersionList.append({'id' : v.id})
162+
163+
for fixVersionName in versionsToAdd:
164+
fixVersion = None
165+
for v in versions:
166+
if v.name == fixVersionName:
167+
fixVersion = v
168+
break
169+
170+
if fixVersion:
171+
updatedVersionList.append({'id' : fixVersion.id})
172+
result += "Added fix version: " + fixVersionName + "\n"
173+
else:
174+
result += "Error: Unable to find fix version: " + fixVersionName + "\n"
175+
176+
if len(versionsToAdd) > 0:
177+
issue.update(fields={'fixVersions': updatedVersionList})
178+
else:
179+
result += "Fix versions already added.\n"
180+
181+
statusName = str(issue.fields.status)
182+
if statusName != 'Resolved':
183+
transition = 'Resolve Issue'
184+
jira.transition_issue(issue, transition)
185+
result += "Workflow Transition: 'Resolve issue'\n"
186+
187+
return result
188+
189+
jirabot_user = os.environ['JIRABOT_USERNAME']
190+
jirabot_pass = os.environ['JIRABOT_PASSWORD']
191+
jira_url = os.environ['JIRA_URL']
192+
193+
pr = os.environ['PULL_REQUEST_NUMBER']
194+
title = os.environ['PULL_REQUEST_TITLE']
195+
user = os.environ['PULL_REQUEST_AUTHOR_NAME']
196+
pull_url = os.environ['PULL_URL']
197+
github_token = os.environ['GITHUB_TOKEN']
198+
branch_name = os.environ['BRANCH_NAME']
199+
comments_url = os.environ['COMMENTS_URL']
200+
201+
print("Attempting to close out Jira issue: %s %s %s" % (title, user, comments_url))
202+
result = ''
203+
issuem = re.search("(HPCC4J|JAPI)-[0-9]+", title)
204+
if issuem:
205+
nameCorrectionPattern = re.compile("hpcc4j", re.IGNORECASE)
206+
issue_name = nameCorrectionPattern.sub("JAPI",issuem.group())
207+
208+
options = {
209+
'server': jira_url
210+
}
211+
212+
jira = JIRA(options=options, basic_auth=(jirabot_user, jirabot_pass))
213+
issue = jira.issue(issue_name)
214+
if issue is None:
215+
print('Unable to find issue with name: ' + issue_name)
216+
sys.exit(1)
217+
218+
result = 'Jirabot Action Result:\n'
219+
220+
fixVersions = generateFixVersionList(jira, branch_name)
221+
result += resolveIssue(jira, issue, fixVersions)
222+
jira.add_comment(issue, result)
223+
else:
224+
print('Unable to find Jira issue name in title')
225+
226+
print(result)
227+
shell: python

0 commit comments

Comments
 (0)