#!/usr/bin/env python """ Script to create stories in JIRA from issues in GitHub. Discussion of technical issues can happen in GitHub, while project management happens in JIRA. Requires a github.rackspace.com personal access token, accessible via keyring. - resource: github.rackspace.com - username: your sso """ import argparse import keyring import requests from nscli.auth import ns_auth GH_HOST = "github.rackspace.com" GH_API_URL = "https://{}/api/v3".format(GH_HOST) JIRA_HOST = "jira.rax.io" JIRA_API_URL = "https://{}/rest/api/2".format(JIRA_HOST) def init_parser(): parser = argparse.ArgumentParser(description="Create an NSCLI JIRA story from an NSCLI GitHub issue.") parser.add_argument("issue", type=int, help="The issue number in GitHub") return parser def validate_gh_issue_url(token, issue): """Returns the title and URL of the given NSCLI GitHub issue, if it exists. If it does not exist, returns (`None`, `None`).""" url = GH_API_URL + "/repos/NSI/nscli/issues/{}".format(issue) headers = {"Authorization": "token " + token} r = requests.get(url, headers=headers) if r.status_code == 404: return None, None r.raise_for_status() j = r.json() return j["title"], j["html_url"] def create_jira(summary, gh_issue, user, password): """ https://developer.atlassian.com/jiradev/jira-apis/jira-rest-apis/jira-rest-api-tutorials/jira-rest-api-example-create-issue """ # Create new issue url = JIRA_API_URL + "/issue" payload = { "fields": { "project": { "key": "NSCLI" }, "summary": summary, "issuetype": { "name": "Story" } } } r = requests.post(url=url, json=payload, auth=(user, password)) r.raise_for_status() story_url = r.json()['self'] jira_number = r.json()['key'] # Update issue with link to NSCLI epic. Can't be set during creation. url = story_url payload = { "fields": { "customfield_10001": "NSCLI-2" } } r = requests.put(url=url, json=payload, auth=(user, password)) r.raise_for_status() # Update issue with link to GitHub issue. Can't be set during creation. url = story_url + "/remotelink" payload = { "object": { "url": "https://{}/NSI/nscli/issues/{}".format(GH_HOST, gh_issue), "title": "GitHub Issue", "icon": { "url16x16": "https://{}/favicon.ico".format(GH_HOST) } } } r = requests.post(url=url, json=payload, auth=(user, password)) r.raise_for_status() return jira_number def main(): parser = init_parser() args = parser.parse_args() issue = args.issue ns_token = ns_auth.Token() sso = ns_token.sso_user password = ns_token.sso_password gh_token = keyring.get_password(GH_HOST, sso) issue_title, issue_url = validate_gh_issue_url(gh_token, issue) if not all((issue_url, issue_title)): raise ValueError("The given issue does not exist: {}".format(issue)) jira_number = create_jira(issue_title, issue, sso, password) print("Created JIRA at https://{}/browse/{}".format(JIRA_HOST, jira_number)) if __name__ == '__main__': main()