Last active
July 4, 2024 01:22
-
-
Save atharvai/88b151c309bd8d972adae6b65263e5ef to your computer and use it in GitHub Desktop.
migration script for open Github issues to JIRA Tickets
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Exports Issues from a specified repository to a CSV file and creates corresponding tickets in JIRA. | |
Uses basic authentication (Github username + password) to retrieve Issues | |
from a repository that username has access to. Supports Github API v3. | |
Use the following gist as config for this script: https://gist.github.com/atharvai/16996fbb73442f8a1cfb5bffb11c412e | |
""" | |
import csv | |
import requests | |
import json | |
import sys | |
from jira import JIRA | |
from migrate_config import GITHUB_AUTH, JIRA_SERVER, JIRA_AUTH, JIRA_PROJECT, REPO, JIRA_TICKET_TYPE, user_map, \ | |
labels_map | |
ISSUES_FOR_REPO_URL = 'https://api.github.com/repos/%s/issues?state=open' % REPO | |
try: | |
jira = JIRA(server=JIRA_SERVER, basic_auth=JIRA_AUTH, validate=False, | |
options={'rest_api_version': 'latest', 'verify': False}) | |
except Exception as e: | |
print(e.message) | |
sys.exit(1) | |
def write_issues_to_csv(rows): | |
csvfile = '%s-issues.csv' % (REPO.replace('/', '-')) | |
with open(csvfile, 'wb') as f: | |
csvout = csv.DictWriter(f, rows[0].keys()) | |
csvout.writeheader() | |
csvout.writerows(rows) | |
def github_get_issues(url): | |
r = requests.get(url, auth=GITHUB_AUTH) | |
issues_only = [i for i in r.json() if i['state'] == 'open' and 'pull_request' not in i] | |
issues_rest = github_get_further_issues(r) | |
return issues_only + issues_rest | |
def github_get_further_issues(orig_response): | |
# more pages? examine the 'link' header returned | |
all_issues = [] | |
if 'link' in orig_response.headers: | |
pages = dict( | |
[(rel[6:-1], url[url.index('<') + 1:-1]) for url, rel in | |
[link.split(';') for link in | |
orig_response.headers['link'].split(',')]]) | |
while 'last' in pages and 'next' in pages: | |
issues = get_issues(pages['next']) | |
all_issues = all_issues + issues | |
if pages['next'] == pages['last']: | |
break | |
return all_issues | |
def jira_create_ticket(github_issue): | |
description = github_issue['body'] + '\n\nref: ' + github_issue['url'] | |
github_labels = [l['name'] for l in github_issue['labels']] | |
jira_labels = [labels_map[l] for l in github_labels if l in labels_map] | |
ticket = {'project': JIRA_PROJECT, | |
'issuetype': {'name': JIRA_TICKET_TYPE}, | |
'summary': github_issue['title'], | |
'description': description, | |
'labels': jira_labels, | |
} | |
reporter = user_map[github_issue['user']['login']] if github_issue['user'] else None | |
if reporter: | |
ticket['reporter'] = {'name': reporter} | |
assignee = user_map[github_issue['assignee']['login']] if github_issue['assignee'] else None | |
if assignee: | |
ticket['assignee'] = {'name': assignee} | |
new_ticket = jira.create_issue(ticket) | |
return new_ticket | |
def jira_import_issues(github_issues_list): | |
issue_ticket_map = {} | |
for github_issue in github_issues_list: | |
ticket = jira_create_ticket(github_issue) | |
issue_ticket_map[github_issue['number']] = ticket.key | |
print(json.dumps(issue_ticket_map, indent=2)) | |
return issue_ticket_map | |
def add_jira_ref_to_github_issue(issue_ticket_map): | |
issue_url_base = 'https://api.github.com/repos/{repo}/issues/{issue_num}' | |
comment_url_base = 'https://api.github.com/repos/{repo}/issues/{issue_num}/comments' | |
for issue, key in issue_ticket_map.iteritems(): | |
print('Github: {}\tJIRA: {}'.format(issue, key)) | |
comment_url = comment_url_base.format(repo=REPO, issue_num=issue) | |
comment = {'body': 'Tracked in: {}{}'.format(JIRA_SERVER + '/projects/' + JIRA_PROJECT + '/issues/', key)} | |
resp = requests.post(comment_url, json=comment, auth=GITHUB_AUTH) | |
if resp.status_code == 201: | |
print('comment added to github issue') | |
else: | |
print('failed to add comment to github issue') | |
issue_url = issue_url_base.format(repo=REPO, issue_num=issue) | |
body = {'state': 'closed'} | |
resp = requests.post(issue_url, json=body, auth=GITHUB_AUTH) | |
if resp.status_code == 200: | |
print('github issue closed') | |
else: | |
print('failed to close github issue') | |
if __name__ == '__main__': | |
issues = github_get_issues(ISSUES_FOR_REPO_URL) | |
write_issues_to_csv(issues) | |
issue_ticket_map = jira_import_issues(issues) | |
add_jira_ref_to_github_issue(issue_ticket_map) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment