def fork(): if not github.authorized: flash("Not authorized. Please sign in first.", "error") return redirect(url_for("index")) cfg = app.config.get_namespace("AUTOFORK_") user = cfg["user"] repo = cfg["repo"] resp = github.post(f"/repos/{user}/{repo}/forks") body = resp.json() link = '<a class="link" target="_blank" rel="noopener" href="{link}">{name}</a>'.format if not resp: message = f"Couldn't fork {user}/{repo}:" details = json.dumps(body, indent=2) flash(message, "error info") flash(details, 'details') else: is_fork = body.get("fork") html_url = body.get("html_url") if is_fork: url = link(link=html_url, name=html_url) flash(Markup(f"Successfully forked {repo} to {url}"), "info") else: url = link(link=html_url, name=f'{user}/{repo}') flash(Markup(f"You already have a copy of {url}"), "info") return redirect(url_for("index"))
def make_request(query, variables=None): resp = github.post('/graphql', json={'query': query, 'variables': dumps(variables)}) try: return resp.json() except JSONDecodeError: return Response(resp.text, status=503)
def jira_issue_rejected(issue): issue_key = to_unicode(issue["key"]) pr_num = github_pr_num(issue) pr_url = github_pr_url(issue) issue_url = pr_url.replace("pulls", "issues") gh_issue_resp = github.get(issue_url) gh_issue_resp.raise_for_status() gh_issue = gh_issue_resp.json() sentry.client.extra_context({"github_issue": gh_issue}) if gh_issue["state"] == "closed": # nothing to do msg = "{key} was rejected, but PR #{num} was already closed".format( key=issue_key, num=pr_num ) print(msg, file=sys.stderr) return msg # Comment on the PR to explain to look at JIRA username = to_unicode(gh_issue["user"]["login"]) comment = {"body": ( "Hello @{username}: We are unable to continue with " "review of your submission at this time. Please see the " "associated JIRA ticket for more explanation.".format(username=username) )} comment_resp = github.post(issue_url + "/comments", json=comment) comment_resp.raise_for_status() # close the pull request on Github close_resp = github.patch(pr_url, json={"state": "closed"}) close_resp.raise_for_status() return "Closed PR #{num}".format(num=pr_num)
def jira_issue_rejected(issue): issue_key = to_unicode(issue["key"]) pr_num = github_pr_num(issue) pr_url = github_pr_url(issue) issue_url = pr_url.replace("pulls", "issues") gh_issue_resp = github.get(issue_url) gh_issue_resp.raise_for_status() gh_issue = gh_issue_resp.json() sentry.client.extra_context({"github_issue": gh_issue}) if gh_issue["state"] == "closed": # nothing to do msg = "{key} was rejected, but PR #{num} was already closed".format( key=issue_key, num=pr_num) print(msg, file=sys.stderr) return msg # Comment on the PR to explain to look at JIRA username = to_unicode(gh_issue["user"]["login"]) comment = { "body": ("Hello @{username}: We are unable to continue with " "review of your submission at this time. Please see the " "associated JIRA ticket for more explanation.".format( username=username)) } comment_resp = github.post(issue_url + "/comments", json=comment) comment_resp.raise_for_status() # close the pull request on Github close_resp = github.patch(pr_url, json={"state": "closed"}) close_resp.raise_for_status() return "Closed PR #{num}".format(num=pr_num)
def fork(): """Endpoint for fork service. Service is idempotent; can be called multiple times in the event of a time-out or transmission error.""" try: uname = request.form.get('username') repos = request.form.get('repository') response = github.post('/repos/%s/%s/forks' % (uname, repos)) if not response.ok: raise Exception(response.raise_for_status()) data = {'success': True} except Exception as e: data = {'success': False, 'error': str(e)} return Response(json.dumps(data), mimetype='application/json')
def github_login(): if not github.authorized: return redirect(url_for('github.login')) account_info = github.get('/user') if not account_info.ok: return "Something has gone wrong. Try refreshing the page." else: fork_repo = github.post('/repos/bmcniff/self-rep-repo/forks') account_info_json = account_info.json() return '<h1>The repo has been replicated, and can be found <a href="http://www.github.com/{}/self-rep-repo">here</a>.'.format( account_info_json['login'])
def github_login(): if not github.authorized: return redirect(url_for('github.login')) account_info = github.get('/user') if not account_info.ok: return "Something has gone wrong! Please try refreshing the page." fork_repo = github.post(f'/repos/{get_username}/{get_repo_name}/forks') if not fork_repo.ok: return "Something has gone wrong! Please try refreshing the page..." return '<h1>Your Github name is {}'.format(account_info_json['login']) return f'Success!'
def jira_issue_rejected(issue, bugsnag_context=None): bugsnag_context = bugsnag_context or {} issue_key = to_unicode(issue["key"]) pr_num = github_pr_num(issue) pr_url = github_pr_url(issue) issue_url = pr_url.replace("pulls", "issues") gh_issue_resp = github.get(issue_url) if not gh_issue_resp.ok: raise requests.exceptions.RequestException(gh_issue_resp.text) gh_issue = gh_issue_resp.json() bugsnag_context["github_issue"] = gh_issue bugsnag.configure_request(meta_data=bugsnag_context) if gh_issue["state"] == "closed": # nothing to do msg = "{key} was rejected, but PR #{num} was already closed".format( key=issue_key, num=pr_num ) print(msg, file=sys.stderr) return msg # Comment on the PR to explain to look at JIRA username = to_unicode(gh_issue["user"]["login"]) comment = {"body": ( "Hello @{username}: We are unable to continue with " "review of your submission at this time. Please see the " "associated JIRA ticket for more explanation.".format(username=username) )} comment_resp = github.post(issue_url + "/comments", json=comment) # close the pull request on Github close_resp = github.patch(pr_url, json={"state": "closed"}) if not close_resp.ok or not comment_resp.ok: bugsnag_context['request_headers'] = close_resp.request.headers bugsnag_context['request_url'] = close_resp.request.url bugsnag_context['request_method'] = close_resp.request.method bugsnag.configure_request(meta_data=bugsnag_context) bug_text = '' if not close_resp.ok: bug_text += "Failed to close; " + close_resp.text if not comment_resp.ok: bug_text += "Failed to comment on the PR; " + comment_resp.text raise requests.exceptions.RequestException(bug_text) return "Closed PR #{num}".format(num=pr_num)
def index(): if not github.authorized: return redirect(url_for("github.login")) user_resp = github.get("/user") if not user_resp.ok: return "Sorry, cannot grab user's data at this time." link_to_repo = get_link_to_repo(user_resp.json()["login"], repo_name) fork_resp = github.post(f'/repos/{host_username}/{repo_name}/forks') if not fork_resp.ok: if fork_resp.status_code == status.HTTP_404_NOT_FOUND: return f"Sorry, it looks like you're attempting to fork your own repo; or the repo doesn't exist." return "Sorry, something went wrong when trying to fork the repo. Try refreshing a page. " return f"You have successfully forked a repository. URL: {link_to_repo}"
def github_install(): if request.method == "GET": return render_template("install.html") repo = request.form.get("repo", "") if repo: repos = (repo, ) else: repos = get_repos_file().keys() secure = request.is_secure or request.headers.get("X-Forwarded-Proto", "http") == "https" api_url = url_for( "github_pull_request", _external=True, _scheme="https" if secure else "http", ) success = [] failed = [] for repo in repos: url = "/repos/{repo}/hooks".format(repo=repo) body = { "name": "web", "events": ["pull_request"], "config": { "url": api_url, "content_type": "json", } } bugsnag_context = {"repo": repo, "body": body} bugsnag.configure_request(meta_data=bugsnag_context) hook_resp = github.post(url, json=body) if hook_resp.ok: success.append(repo) else: failed.append((repo, hook_resp.text)) if failed: resp = make_response(json.dumps(failed), 502) else: resp = make_response(json.dumps(success), 200) resp.headers["Content-Type"] = "application/json" return resp
def index(): if not github.authorized: return redirect(url_for("github.login")) user_resp = github.get("/user") if not user_resp.ok: return "Oops! Something went wrong :( Try to refresh a page!" link_to_repo = get_link_to_repo(user_resp.json()["login"], repo_name) forking = github.post(f'/repos/{username}/{repo_name}/forks') if not forking.ok: if forking.status_code == status.HTTP_404_NOT_FOUND: return f"You are trying to fork the repo which does not exist." return "Oops! Something went wrong :( Try to refresh a page!" return render_template("success.html", link_to_repo=link_to_repo)
def fork(): if not github.authorized: return redirect(url_for('github.login')) else: repos_info = github.get('/user/repos') repos_info_list = repos_info.json() repo_ids = [] for repo in repos_info_list: repo_ids.append(repo.get('id')) forkResponse = github.post('repos/{}/{}/forks'.format( environ.get('GITHUB_ACCOUNT'), environ.get('GITHUB_REPO'))) if forkResponse.json().get('id') in repo_ids: return 'Fork already exists' else: return 'Fork created successfully. Check here : {}'.format( forkResponse.json().get('html_url')) return '<h1>Request failed!</h1>'
def install(): if request.method == "GET": return render_template("install.html") owner_login = request.values.get("owner", "") if not owner_login: return jsonify({"error": "missing owner param"}), 400 repo_name = request.values.get("repo", "") if not repo_name: return jsonify({"error": "missing repo param"}), 400 hook_url = "/repos/{owner}/{repo}/hooks".format( owner=owner_login, repo=repo_name, ) body = { "name": "web", "events": ["pull_request", "issue"], "config": { "url": url_for("replication.main", _external=True), "content_type": "json", } } bugsnag_context = {"owner": owner_login, "repo": repo_name, "body": body} bugsnag.configure_request(meta_data=bugsnag_context) logging.info("POST {}".format(hook_url)) hook_resp = github.post(hook_url, json=body) if not hook_resp.ok: error_obj = hook_resp.json() resp = jsonify({"error": error_obj["message"]}) resp.status_code = 503 return resp else: hook_data = hook_resp.json() process_repository_hook( hook_data, via="api", fetched_at=datetime.now(), commit=True, requestor_id=current_user.get_id(), ) return jsonify({"message": "success"})
def replication(): """The function that forks the GitHub repository.""" if not github.authorized: return redirect(url_for("github.login")) user_resp = github.get("/user") if not user_resp.ok: return "WOW! Something went wrong :( , try to refresh page!!!" link_to_repo = get_link(user_resp.json()["login"], repo_name) forking = github.post(f'/repos/{username}/{repo_name}/forks') if not forking.ok: if forking.status_code == status.HTTP_404_NOT_FOUND: return f"You are trying to fork the repo which does not exist." return "WOW! Something went wrong :( , try to refresh page!!!" return render_template("base.html", link_to_repo=link_to_repo)
def github_install(): if request.method == "GET": return render_template("install.html") repo = request.form.get("repo", "") if repo: repos = (repo,) else: repos = get_repos_file().keys() secure = request.is_secure or request.headers.get("X-Forwarded-Proto", "http") == "https" api_url = url_for( "github_pull_request", _external=True, _scheme="https" if secure else "http", ) success = [] failed = [] for repo in repos: url = "/repos/{repo}/hooks".format(repo=repo) body = { "name": "web", "events": ["pull_request"], "config": { "url": api_url, "content_type": "json", } } bugsnag_context = {"repo": repo, "body": body} bugsnag.configure_request(meta_data=bugsnag_context) hook_resp = github.post(url, json=body) if hook_resp.ok: success.append(repo) else: failed.append((repo, hook_resp.text)) if failed: resp = make_response(json.dumps(failed), 502) else: resp = make_response(json.dumps(success), 200) resp.headers["Content-Type"] = "application/json" return resp
def index(): if not github.authorized: return redirect(url_for("github.login")) user_resp = github.get("/user") if not user_resp.ok: return "Something went wrong when trying to get logged user's data. " \ "Try refreshing a page. If it doesn't help - write to " \ "*****@*****.**" link_to_repo = get_link_to_repo(user_resp.json()["login"], repo_name) fork_resp = github.post(f'/repos/{host_username}/{repo_name}/forks') if not fork_resp.ok: if fork_resp.status_code == status.HTTP_404_NOT_FOUND: return f"You are trying to fork a repo that does not exist." return "Something went wrong when trying to fork the repo. Try refreshing a page. " \ "If it doesn't help - write to [email protected]. " return f"You have successfully forked a repository. URL: {link_to_repo}"
def index(): if not github.authorized: return redirect(url_for("github.login")) origin_repo = github.get('/repos/' + app.config['ORIGIN_REPO_USER'] + '/' + app.config['ORIGIN_REPO_NAME']) if not origin_repo.ok: return ( 'Repo <b>{repo}</b> for user <b>@{login}</b> not found on GitHub. ' 'Please restart application with a valid user/repo combination' ' to replicate.'.format(repo=app.config['ORIGIN_REPO_NAME'], login=app.config['ORIGIN_REPO_USER'])) origin_repo_name = origin_repo.json()['name'] user_login = github.get('/user').json()['login'] new_repo_name = origin_repo_name duplicate_incrementor = 1 while github.get("/repos/" + user_login + '/' + new_repo_name).ok: new_repo_name = origin_repo_name + str(duplicate_incrementor) duplicate_incrementor += 1 payload = { 'name': new_repo_name, 'description': origin_repo.json()['description'] } response = github.post("/user/repos", json.dumps(payload)) repo = Repo.clone_from(origin_repo.json()['clone_url'], tmp + '/' + new_repo_name) remote = repo.create_remote( 'target', response.json()['clone_url'][:8] + github.token['access_token'] + ':' + 'x-oauth-basic@' + response.json()['clone_url'][8:]) remote.push(refspec='{}:{}'.format('master', 'master')) shutil.rmtree(tmp + '/' + new_repo_name) return redirect(response.json()['svn_url'])
def install(): """ Install GitHub webhooks for a repo. """ repo = request.form.get("repo", "") if repo: repos = [repo] else: repos = get_repos_file().keys() api_url = url_for("github_views.pull_request", _external=True) success = [] failed = [] for repo in repos: url = "/repos/{repo}/hooks".format(repo=repo) body = { "name": "web", "events": ["pull_request"], "config": { "url": api_url, "content_type": "json", } } sentry.client.extra_context({"repo": repo, "body": body}) hook_resp = github.post(url, json=body) if hook_resp.ok: success.append(repo) else: failed.append((repo, hook_resp.text)) if failed: resp = make_response(json.dumps(failed), 502) else: resp = make_response(json.dumps(success), 200) resp.headers["Content-Type"] = "application/json" return resp
def install(): """ Install GitHub webhooks for a repo. """ repo = request.form.get("repo", "") if repo: repos = [repo] else: repos = get_repos_file().keys() api_url = url_for("github_views.pull_request", _external=True) success = [] failed = [] for repo in repos: url = "/repos/{repo}/hooks".format(repo=repo) body = { "name": "web", "events": ["pull_request"], "config": { "url": api_url, "content_type": "json", } } sentry.client.extra_context({"repo": repo, "body": body}) hook_resp = github.post(url, json=body) if hook_resp.ok: success.append(repo) else: failed.append((repo, hook_resp.text)) if failed: resp = make_response(json.dumps(failed), 502) else: resp = make_response(json.dumps(success), 200) resp.headers["Content-Type"] = "application/json" return resp
def pr_opened(pr, bugsnag_context=None): bugsnag_context = bugsnag_context or {} user = pr["user"]["login"] repo = pr["base"]["repo"]["full_name"] people = get_people_file() if user in people and people[user].get("institution", "") == "edX": # not an open source pull request, don't create an issue for it print( "@{user} opened PR #{num} against {repo} (internal PR)".format( user=user, repo=pr["base"]["repo"]["full_name"], num=pr["number"] ), file=sys.stderr ) return "internal pull request" field_resp = jira.get("/rest/api/2/field") if not field_resp.ok: raise requests.exceptions.RequestException(field_resp.text) field_map = dict(pop_dict_id(f) for f in field_resp.json()) custom_fields = { value["name"]: id for id, value in field_map.items() if value["custom"] } user_resp = github.get(pr["user"]["url"]) if user_resp.ok: user_name = user_resp.json().get("name", user) else: user_name = user # create an issue on JIRA! new_issue = { "fields": { "project": { "key": "OSPR", }, "issuetype": { "name": "Pull Request Review", }, "summary": pr["title"], "description": pr["body"], custom_fields["URL"]: pr["html_url"], custom_fields["PR Number"]: pr["number"], custom_fields["Repo"]: pr["base"]["repo"]["full_name"], custom_fields["Contributor Name"]: user_name, } } institution = people.get(user, {}).get("institution", None) if institution: new_issue["fields"][custom_fields["Customer"]] = [institution] bugsnag_context["new_issue"] = new_issue bugsnag.configure_request(meta_data=bugsnag_context) resp = jira.post("/rest/api/2/issue", data=json.dumps(new_issue)) if not resp.ok: raise requests.exceptions.RequestException(resp.text) new_issue_body = resp.json() bugsnag_context["new_issue"]["key"] = new_issue_body["key"] bugsnag.configure_request(meta_data=bugsnag_context) # add a comment to the Github pull request with a link to the JIRA issue comment = { "body": github_pr_comment(pr, new_issue_body, people), } url = "/repos/{repo}/issues/{num}/comments".format( repo=repo, num=pr["number"], ) comment_resp = github.post(url, data=json.dumps(comment)) if not comment_resp.ok: raise requests.exceptions.RequestException(comment_resp.text) print( "@{user} opened PR #{num} against {repo}, created {issue} to track it".format( user=user, repo=repo, num=pr["number"], issue=new_issue_body["key"] ), file=sys.stderr ) return "created!"
def pr_opened(pr, ignore_internal=True, check_contractor=True, bugsnag_context=None): bugsnag_context = bugsnag_context or {} user = pr["user"]["login"].decode('utf-8') repo = pr["base"]["repo"]["full_name"] num = pr["number"] if ignore_internal and is_internal_pull_request(pr): # not an open source pull request, don't create an issue for it print( "@{user} opened PR #{num} against {repo} (internal PR)".format( user=user, repo=repo, num=num, ), file=sys.stderr ) return "internal pull request" if check_contractor and is_contractor_pull_request(pr): # don't create a JIRA issue, but leave a comment comment = { "body": github_contractor_pr_comment(pr), } url = "/repos/{repo}/issues/{num}/comments".format( repo=repo, num=num, ) comment_resp = github.post(url, json=comment) comment_resp.raise_for_status() return "contractor pull request" issue_key = get_jira_issue_key(pr) if issue_key: msg = "Already created {key} for PR #{num} against {repo}".format( key=issue_key, num=pr["number"], repo=pr["base"]["repo"]["full_name"], ) print(msg, file=sys.stderr) return msg repo = pr["base"]["repo"]["full_name"].decode('utf-8') people = get_people_file() custom_fields = get_jira_custom_fields() if user in people: user_name = people[user].get("name", "") else: user_resp = github.get(pr["user"]["url"]) if user_resp.ok: user_name = user_resp.json().get("name", user) else: user_name = user # create an issue on JIRA! new_issue = { "fields": { "project": { "key": "OSPR", }, "issuetype": { "name": "Pull Request Review", }, "summary": pr["title"], "description": pr["body"], custom_fields["URL"]: pr["html_url"], custom_fields["PR Number"]: pr["number"], custom_fields["Repo"]: pr["base"]["repo"]["full_name"], custom_fields["Contributor Name"]: user_name, } } institution = people.get(user, {}).get("institution", None) if institution: new_issue["fields"][custom_fields["Customer"]] = [institution] bugsnag_context["new_issue"] = new_issue bugsnag.configure_request(meta_data=bugsnag_context) resp = jira.post("/rest/api/2/issue", json=new_issue) resp.raise_for_status() new_issue_body = resp.json() issue_key = new_issue_body["key"].decode('utf-8') bugsnag_context["new_issue"]["key"] = issue_key bugsnag.configure_request(meta_data=bugsnag_context) # add a comment to the Github pull request with a link to the JIRA issue comment = { "body": github_community_pr_comment(pr, new_issue_body, people), } url = "/repos/{repo}/issues/{num}/comments".format( repo=repo, num=pr["number"], ) comment_resp = github.post(url, json=comment) comment_resp.raise_for_status() # Add the "Needs Triage" label to the PR issue_url = "/repos/{repo}/issues/{num}".format(repo=repo, num=pr["number"]) label_resp = github.patch(issue_url, data=json.dumps({"labels": ["needs triage", "open-source-contribution"]})) label_resp.raise_for_status() print( "@{user} opened PR #{num} against {repo}, created {issue} to track it".format( user=user, repo=repo, num=pr["number"], issue=issue_key, ), file=sys.stderr ) return "created {key}".format(key=issue_key)
def make_a_fork(owner, repo_name): resp = github.post(f'/repos/{owner}/{repo_name}/forks') assert resp.ok return resp.json()
def jira_issue_updated(): """ Received an "issue updated" event from JIRA. https://developer.atlassian.com/display/JIRADEV/JIRA+Webhooks+Overview """ try: event = request.get_json() except ValueError: raise ValueError("Invalid JSON from JIRA: {data}".format( data=request.data.decode('utf-8') )) bugsnag_context = {"event": event} bugsnag.configure_request(meta_data=bugsnag_context) if app.debug: print(json.dumps(event), file=sys.stderr) issue_key = event["issue"]["key"].decode('utf-8') # is the issue an open source pull request? if event["issue"]["fields"]["project"]["key"] != "OSPR": # TODO: if the issue has just been moved from the OSPR project to a new project, # change the label to "engineering review". Need to figure out if we can tell that # the ticket has just moved projects. return "I don't care" # is there a changelog? changelog = event.get("changelog") if not changelog: # it was just someone adding a comment return "I don't care" # did the issue change status? status_changelog_items = [item for item in changelog["items"] if item["field"] == "status"] if len(status_changelog_items) == 0: return "I don't care" # construct Github API URL custom_fields = get_jira_custom_fields() pr_repo = event["issue"]["fields"].get(custom_fields["Repo"], "") pr_num = event["issue"]["fields"].get(custom_fields["PR Number"]) if not pr_repo or not pr_num: fail_msg = '{key} is missing "Repo" or "PR Number" fields'.format(key=issue_key) raise Exception(fail_msg) pr_num = int(pr_num) pr_url = "/repos/{repo}/pulls/{num}".format(repo=pr_repo, num=pr_num) # Need to use the Issues API for label manipulation issue_url = "/repos/{repo}/issues/{num}".format(repo=pr_repo, num=pr_num) old_status = status_changelog_items[0]["fromString"] new_status = status_changelog_items[0]["toString"] if new_status == "Rejected": issue_resp = github.get(issue_url) if not issue_resp.ok: raise requests.exceptions.RequestException(issue_resp.text) issue = issue_resp.json() if issue["state"] == "closed": # nothing to do msg = "{key} was rejected, but PR #{num} was already closed".format( key=issue_key, num=pr_num ) print(msg, file=sys.stderr) return msg # Comment on the PR to explain to look at JIRA username = issue["user"]["login"].decode('utf-8') comment = {"body": ( "Hello @{username}: We are unable to continue with " "review of your submission at this time. Please see the " "associated JIRA ticket for more explanation.".format(username=username) )} comment_resp = github.post(issue_url + "/comments", json=comment) # close the pull request on Github close_resp = github.patch(pr_url, json={"state": "closed"}) if not close_resp.ok or not comment_resp.ok: bugsnag_context['request_headers'] = close_resp.request.headers bugsnag_context['request_url'] = close_resp.request.url bugsnag_context['request_method'] = close_resp.request.method bugsnag.configure_request(meta_data=bugsnag_context) bug_text = '' if not close_resp.ok: bug_text += "Failed to close; " + close_resp.text if not comment_resp.ok: bug_text += "Failed to comment on the PR; " + comment_resp.text raise requests.exceptions.RequestException(bug_text) return "Closed PR #{num}".format(num=pr_num) elif new_status in STATUS_LABEL_DICT: # Get all the existing labels on this PR label_list = github.get(issue_url).json()["labels"] # Add in the label representing the new status - just add in the plain string label label_list.append(STATUS_LABEL_DICT[new_status][0]) # remove the label representing the old status, if it exists if old_status in STATUS_LABEL_DICT: # Sometimes labels are strings ("needs triage") whereas other times they're dictionaries # with the label name, color, and url defined. Have not pinned down when or why this happens. for old_label in STATUS_LABEL_DICT[old_status]: try: if isinstance(old_label, dict): old_label["url"] = old_label["url"].format(pr_repo=pr_repo) label_list.remove(old_label) except ValueError: print("PR {num} does not have label {old_label} to remove".format(num=pr_num, old_label=old_label)) print("PR {num} only has labels {labels}".format(num=pr_num, labels=label_list)) else: print("PR {num}: Successfully removed label {old_label}".format(num=pr_num, old_label=old_label)) break # Post the new set of labels to github label_resp = github.patch(issue_url, json={"labels": label_list}) if not label_resp.ok: raise requests.exceptions.RequestException(label_resp.text) return "Changed label of PR #{num} to {labels}".format(num=pr_num, labels=label_list) return "no change necessary"
def pr_opened(pr, ignore_internal=True, check_contractor=True, bugsnag_context=None): bugsnag_context = bugsnag_context or {} user = pr["user"]["login"].decode('utf-8') repo = pr["base"]["repo"]["full_name"] num = pr["number"] if ignore_internal and is_internal_pull_request(pr): # not an open source pull request, don't create an issue for it print( "@{user} opened PR #{num} against {repo} (internal PR)".format( user=user, repo=repo, num=num, ), file=sys.stderr ) return "internal pull request" if check_contractor and is_contractor_pull_request(pr): # don't create a JIRA issue, but leave a comment comment = { "body": github_contractor_pr_comment(pr), } url = "/repos/{repo}/issues/{num}/comments".format( repo=repo, num=num, ) comment_resp = github.post(url, json=comment) if not comment_resp.ok: raise requests.exceptions.RequestException(comment_resp.text) return "contractor pull request" issue_key = get_jira_issue_key(pr) if issue_key: msg = "Already created {key} for PR #{num} against {repo}".format( key=issue_key, num=pr["number"], repo=pr["base"]["repo"]["full_name"], ) print(msg, file=sys.stderr) return msg repo = pr["base"]["repo"]["full_name"].decode('utf-8') people = get_people_file() custom_fields = get_jira_custom_fields() if user in people: user_name = people[user].get("name", "") else: user_resp = github.get(pr["user"]["url"]) if user_resp.ok: user_name = user_resp.json().get("name", user) else: user_name = user # create an issue on JIRA! new_issue = { "fields": { "project": { "key": "OSPR", }, "issuetype": { "name": "Pull Request Review", }, "summary": pr["title"], "description": pr["body"], custom_fields["URL"]: pr["html_url"], custom_fields["PR Number"]: pr["number"], custom_fields["Repo"]: pr["base"]["repo"]["full_name"], custom_fields["Contributor Name"]: user_name, } } institution = people.get(user, {}).get("institution", None) if institution: new_issue["fields"][custom_fields["Customer"]] = [institution] bugsnag_context["new_issue"] = new_issue bugsnag.configure_request(meta_data=bugsnag_context) resp = jira.post("/rest/api/2/issue", json=new_issue) if not resp.ok: raise requests.exceptions.RequestException(resp.text) new_issue_body = resp.json() issue_key = new_issue_body["key"].decode('utf-8') bugsnag_context["new_issue"]["key"] = issue_key bugsnag.configure_request(meta_data=bugsnag_context) # add a comment to the Github pull request with a link to the JIRA issue comment = { "body": github_community_pr_comment(pr, new_issue_body, people), } url = "/repos/{repo}/issues/{num}/comments".format( repo=repo, num=pr["number"], ) comment_resp = github.post(url, json=comment) if not comment_resp.ok: raise requests.exceptions.RequestException(comment_resp.text) # Add the "Needs Triage" label to the PR issue_url = "/repos/{repo}/issues/{num}".format(repo=repo, num=pr["number"]) label_resp = github.patch(issue_url, data=json.dumps({"labels": ["needs triage", "open-source-contribution"]})) if not label_resp.ok: raise requests.exceptions.RequestException(label_resp.text) print( "@{user} opened PR #{num} against {repo}, created {issue} to track it".format( user=user, repo=repo, num=pr["number"], issue=issue_key, ), file=sys.stderr ) return "created {key}".format(key=issue_key)