[Tracker-discuss] [issue621] Pull request reopened but the PR still shows closed in bug tracker
Anish Shah added the comment: I can work on this! :) -- nosy: +anish.shah, maciej.szulik status: unread -> chatting ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue621> ___ ___ Tracker-discuss mailing list Tracker-discuss@python.org https://mail.python.org/mailman/listinfo/tracker-discuss Code of Conduct: https://www.python.org/psf/codeofconduct/
[Tracker-discuss] [issue614] Duplicate commit message on branch merge
Anish Shah added the comment: Hi Ezio, can you tell me which webhook was triggered? Was it pull request event? ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue614> ___ ___ Tracker-discuss mailing list Tracker-discuss@python.org https://mail.python.org/mailman/listinfo/tracker-discuss Code of Conduct: https://www.python.org/psf/codeofconduct/
[Tracker-discuss] [issue589] Add GitHub PR to b.p.o issues using GitHub webhooks (depends on issue586)
Anish Shah added the comment: I tested the latest patch on the my repository and it is working properly. :) ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue589> ___ ___ Tracker-discuss mailing list Tracker-discuss@python.org https://mail.python.org/mailman/listinfo/tracker-discuss Code of Conduct: https://www.python.org/psf/codeofconduct/
[Tracker-discuss] [issue586] Add GitHub Pull Request URL on issue page
Anish Shah added the comment: Hi, on this link http://bugs.python.org/pull_request, I am getting a textbox where I can delete/edit entries. Do we want this? I am not sure. ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue586> ___ ___ Tracker-discuss mailing list Tracker-discuss@python.org https://mail.python.org/mailman/listinfo/tracker-discuss Code of Conduct: https://www.python.org/psf/codeofconduct/
[Tracker-discuss] [issue600] Convert patches to GitHub Pull Request (depends on issue586)
Anish Shah added the comment: I have updated the patch. > We do need proper error handling, still. The problem is "err" variable has stdout of that process. So, even if we change/push branch, it will be non-empty. Any idea how to solve this problem? One more thing, if we create PR using API, it triggers GitHub webhooks. So, I'm removing the part where we are storing the response in DB. Also, I'm not sure how to add tests for this. -- title: Convert patches to GitHub Pull Request -> Convert patches to GitHub Pull Request (depends on issue586) ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue600> ___diff --git a/detectors/patches.py b/detectors/patches.py index 18d3db4..9e2e01e 100644 --- a/detectors/patches.py +++ b/detectors/patches.py @@ -5,10 +5,97 @@ import posixpath import identify_patch +import os +import subprocess +import string +import random +import json +import requests +import tempfile +import shutil +import logging patchtypes = ('.diff', '.patch') sourcetypes = ('.diff', '.patch', '.py') + +class TemporaryDirectory(object): + +def __enter__(self): +self.name = tempfile.mkdtemp() +return self.name + +def __exit__(self, *args): +shutil.rmtree(self.name) + + +def create_pull_request(db, head, base, issue_id, issue_title): +endpoint = 'https://api.github.com/repos/python/cpython/pulls' +access_token = os.environ['ACCESS_TOKEN'] +headers = {'Authorization': 'token {}'.format(access_token)} +data = json.dumps({ +"title": "{}".format(issue_title), +"body": "fixes issue bpo{}".format(issue_id), +"base": base, "head": head}) +response = requests.post(endpoint, headers=headers, data=data) +if not response.ok: +logging.error(response.text, exc_info=True) +raise Exception('Error while creating pull request') +else: +response_body = response.json() +url = response_body['html_url'] +state = response_body['state'] +pr_id = db.pull_request.create(url=url, state=state) +issue_pr = db.issue.get(issue_id, 'pull_requests') +issue_pr.append(pr_id) +db.issue.set(issue_id, pull_requests=issue_pr) +db.commit() + + +def git_command(command, path): +process = subprocess.Popen(command, cwd=path, shell=True, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) +out, err = process.communicate() +# err takes stdout +# if err: +# raise Exception(err) + + +def git_workflow(db, issue_id, file_id): +try: +path = os.environ['GIT_PATH'] +versions = map(lambda id: (db.version.get(id, 'name'), db.version.get(id, 'order')), + db.issue.get(issue_id, 'versions')) +title = db.issue.get(issue_id, 'title') +commit_msg = 'Fixes issue bpo{} : {}'.format(issue_id, title) +if len(versions) == 0: +parent_branch = "master" +else: +version = versions.pop() +if version[1] == 1: +parent_branch = "master" +else: +parent_branch = version[0].split()[1] +branch_name = ''.join([random.choice(string.ascii_letters) for i in range(random.choice(range(10, 20)))]) +with TemporaryDirectory() as temp_dir: +filepath = os.path.join(temp_dir, db.file.get(file_id, 'name')) +content = db.file.get(file_id, 'content') +with open(filepath, 'wb') as fp: +fp.write(content) +git_command("git checkout {}".format(parent_branch), path) +git_command("git checkout -b {}".format(branch_name), path) +git_command("git apply {}".format(filepath), path) +git_command("git add -A", path) +git_command("git commit -m \"{}\"".format(commit_msg), path) +git_command("git push origin {}".format(branch_name), path) +git_command("git checkout {}".format(parent_branch), path) +git_command("git branch -D {}".format(branch_name), path) +create_pull_request(db, branch_name, parent_branch, issue_id, title) +except Exception, message: +logging.error(message, exc_info=True) +raise ValueError('Error!') + + def ispatch(file, types): return posixpath.splitext(file)[1] in types @@ -26,6 +113,7 @@ def patches_keyword(db, cl, nodeid, newvalues): for fileid in newfiles: if ispatch(db.file.get(fileid, 'name'), patchtypes): newpatch = True +git_workflow(db, nodeid, fileid) break if
[Tracker-discuss] [issue592] Show GitHub comments on b.p.o (depends on issue590)
Anish Shah added the comment: Great! :) ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue592> ___ ___ Tracker-discuss mailing list Tracker-discuss@python.org https://mail.python.org/mailman/listinfo/tracker-discuss Code of Conduct: https://www.python.org/psf/codeofconduct/
[Tracker-discuss] [issue592] Show GitHub comments on b.p.o (depends on issue590)
Anish Shah added the comment: I have updated the patch :) ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue592> ___diff --git a/roundup/pull_request.py b/roundup/pull_request.py index fc70ca5..f5f8c06 100644 --- a/roundup/pull_request.py +++ b/roundup/pull_request.py @@ -1,4 +1,5 @@ from roundup.exceptions import * +from roundup import date import hashlib import hmac @@ -15,6 +16,9 @@ else: return a == b +valid_events = ('pull_request', 'issue_comment', 'pull_request_review_comment') + + class GitHubHandler: def __init__(self, client): @@ -43,7 +47,7 @@ class GitHubHandler: def _extract(self): event = self._get_event() -if event not in ('pull_request', 'issue_comment'): +if event not in valid_events: raise Reject('Unkown X-GitHub-Event {}'.format(event)) data = json.loads(self.form.value) if event == 'pull_request': @@ -52,6 +56,9 @@ class GitHubHandler: elif event == 'issue_comment': handler = IssueComment(self.db, data) handler.dispatch() +elif event == 'pull_request_review_comment': +handler = PullRequestReviewComment(self.db, data) +handler.dispatch() def _validate_webhook_secret(self): key = os.environ['SECRET_KEY'] @@ -95,6 +102,33 @@ class Event: self.db.issue.set(issue_id, pull_requests=urls) self.db.commit() +def handle_comment(self, comment): +url = self._get_url() +issue_id = self._get_issue_id_using_url(url) +if issue_id is not None: +user_id = self.db.user.lookup(os.environ.get('GITHUB_COMMENT_USER', + 'admin')) +messages = self.db.issue.get(issue_id, 'messages') +now = date.Date('.') +min_date = now - date.Interval(os.environ.get('TIME_INTERVAL', + '00:30')) +date_range_string = str(min_date)+';'+str(now) +msg_ids = self.db.msg.filter(None, {'is_github_comment': True, +'creation': date_range_string}) +if not msg_ids: +msg_id = self.db.msg.create(content=comment, author=user_id, +date=now, is_github_comment=True) +messages.append(msg_id) +self.db.issue.set(issue_id, messages=messages) +self.db.commit() + +def _get_issue_id_using_url(self, url): +pr_id = self.db.pull_request.filter(None, {'url': url}) +if len(pr_id) == 1: +issue_id = self.db.issue.filter(None, {'pull_requests': pr_id[0]}) +if len(issue_id) == 1: +return issue_id[0] + def _get_issue_ids(self): raise NotImplementedError @@ -166,8 +200,10 @@ class IssueComment(Event): action = self.data['action'].encode('utf-8') issue_id = self._get_issue_ids() url = self._get_url() +comment = self._get_comment() if action == 'created' and issue_id is not None: self.handle_create(url, issue_id) +self.handle_comment(comment) def _get_issue_ids(self): body = self.data['comment']['body'].encode('utf-8') @@ -181,3 +217,25 @@ class IssueComment(Event): def _get_github_username(self): return self.data['issue']['user']['login'].encode('utf-8') + +def _get_comment(self): +comment_user = self.data['comment']['user']['login'].encode('utf-8') +comment = self.data['comment']['body'].encode('utf-8') +url = self._get_url() +return '%s left a comment on GitHub:\n\n%s' % (comment_user, url) + + +class PullRequestReviewComment(IssueComment): + +def __init__(self, db, data): +self.db = db +self.data = data + +def dispatch(self): +action = self.data['action'].encode('utf-8') +comment = self._get_comment() +if action == 'created': +self.handle_comment(comment) + +def _get_url(self): +return self.data['pull_request']['html_url'] diff --git a/share/roundup/templates/classic/schema.py b/share/roundup/templates/classic/schema.py index 34ae90b..9b548fb 100644 --- a/share/roundup/templates/classic/schema.py +++ b/share/roundup/templates/classic/schema.py @@ -61,7 +61,8 @@ msg = FileClass(db, "msg", summary=String(), files=Multilink("file"), messageid=String(), -inreplyto=String()) +inreplyto=String(), +is_github_comment=Boolean()) file = FileClass(db, "file", name=String()) diff --git a
[Tracker-discuss] [issue592] Show GitHub comments on b.p.o (depends on issue590)
Anish Shah added the comment: > It would be nice to have the user configurable, not admin hardcoded. By configurable, do you mean creating an env var? ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue592> ___ ___ Tracker-discuss mailing list Tracker-discuss@python.org https://mail.python.org/mailman/listinfo/tracker-discuss Code of Conduct: https://www.python.org/psf/codeofconduct/
[Tracker-discuss] [issue592] Show GitHub comments on b.p.o (depends on issue590)
Anish Shah added the comment: I have updated the patch. now, GitHub name, comment and link to the PR will be posted on b.p.o ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue592> ___diff --git a/roundup/pull_request.py b/roundup/pull_request.py index fc70ca5..6f92b83 100644 --- a/roundup/pull_request.py +++ b/roundup/pull_request.py @@ -1,4 +1,5 @@ from roundup.exceptions import * +from roundup import date import hashlib import hmac @@ -15,6 +16,9 @@ else: return a == b +valid_events = ('pull_request', 'issue_comment', 'pull_request_review_comment') + + class GitHubHandler: def __init__(self, client): @@ -43,7 +47,7 @@ class GitHubHandler: def _extract(self): event = self._get_event() -if event not in ('pull_request', 'issue_comment'): +if event not in valid_events: raise Reject('Unkown X-GitHub-Event {}'.format(event)) data = json.loads(self.form.value) if event == 'pull_request': @@ -52,6 +56,9 @@ class GitHubHandler: elif event == 'issue_comment': handler = IssueComment(self.db, data) handler.dispatch() +elif event == 'pull_request_review_comment': +handler = PullRequestReviewComment(self.db, data) +handler.dispatch() def _validate_webhook_secret(self): key = os.environ['SECRET_KEY'] @@ -95,6 +102,32 @@ class Event: self.db.issue.set(issue_id, pull_requests=urls) self.db.commit() +def handle_comment(self, comment): +url = self._get_url() +issue_id = self._get_issue_id_using_url(url) +if issue_id is not None: +user_id = self.db.user.lookup("admin") +messages = self.db.issue.get(issue_id, "messages") +now = date.Date(".") +min_date = now - date.Interval("00:30") +date_range_string = "from " + str(min_date) +msg_ids = self.db.msg.filter(None, {"is_github_comment": True, +"creation": date_range_string}) +if not bool(msg_ids): +msg_id = self.db.msg.create(content=comment, author=user_id, +date=now, is_github_comment=True) +messages.append(msg_id) +self.db.issue.set(issue_id, messages=messages) +self.db.commit() + +def _get_issue_id_using_url(self, url): +pr_id = self.db.pull_request.filter(None, {'url': url}) +pr_exists = len(pr_id) == 1 +if pr_exists: +issue_id = self.db.issue.filter(None, {'pull_requests': pr_id[0]}) +if len(issue_id) == 1: +return issue_id[0] + def _get_issue_ids(self): raise NotImplementedError @@ -166,8 +199,10 @@ class IssueComment(Event): action = self.data['action'].encode('utf-8') issue_id = self._get_issue_ids() url = self._get_url() +comment = self._get_comment() if action == 'created' and issue_id is not None: self.handle_create(url, issue_id) +self.handle_comment(comment) def _get_issue_ids(self): body = self.data['comment']['body'].encode('utf-8') @@ -181,3 +216,26 @@ class IssueComment(Event): def _get_github_username(self): return self.data['issue']['user']['login'].encode('utf-8') + +def _get_comment(self): +comment_user = self.data['comment']['user']['login'].encode('utf-8') +comment = self.data['comment']['body'].encode('utf-8') +url = self._get_url() +return '%s left a comment on GitHub:\n\n%s\n\n%s' % (comment_user, + comment, url) + + +class PullRequestReviewComment(IssueComment): + +def __init__(self, db, data): +self.db = db +self.data = data + +def dispatch(self): +action = self.data['action'].encode('utf-8') +comment = self._get_comment() +if action == 'created': +self.handle_comment(comment) + +def _get_url(self): +return self.data['pull_request']['html_url'] diff --git a/share/roundup/templates/classic/schema.py b/share/roundup/templates/classic/schema.py index 34ae90b..9b548fb 100644 --- a/share/roundup/templates/classic/schema.py +++ b/share/roundup/templates/classic/schema.py @@ -61,7 +61,8 @@ msg = FileClass(db, "msg", summary=String(), files=Multilink("file"), messageid=String(), -inreplyto=String()) +inreplyto=String(), +is_github_comment=Boolean()) file = FileClass(db, &q
[Tracker-discuss] [issue592] Show GitHub comments on b.p.o (depends on issue590)
Anish Shah added the comment: I have updated the patch so that it applies cleanly. I will add the suggestions in a few days. ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue592> ___diff --git a/roundup/pull_request.py b/roundup/pull_request.py index fc70ca5..e8af62a 100644 --- a/roundup/pull_request.py +++ b/roundup/pull_request.py @@ -1,4 +1,5 @@ from roundup.exceptions import * +from roundup import date import hashlib import hmac @@ -15,6 +16,9 @@ else: return a == b +valid_events = ('pull_request', 'issue_comment', 'pull_request_review_comment') + + class GitHubHandler: def __init__(self, client): @@ -43,7 +47,7 @@ class GitHubHandler: def _extract(self): event = self._get_event() -if event not in ('pull_request', 'issue_comment'): +if event not in valid_events: raise Reject('Unkown X-GitHub-Event {}'.format(event)) data = json.loads(self.form.value) if event == 'pull_request': @@ -52,6 +56,9 @@ class GitHubHandler: elif event == 'issue_comment': handler = IssueComment(self.db, data) handler.dispatch() +elif event == 'pull_request_review_comment': +handler = PullRequestReviewComment(self.db, data) +handler.dispatch() def _validate_webhook_secret(self): key = os.environ['SECRET_KEY'] @@ -95,6 +102,32 @@ class Event: self.db.issue.set(issue_id, pull_requests=urls) self.db.commit() +def handle_comment(self, comment): +url = self._get_url() +issue_id = self._get_issue_id_using_url(url) +if issue_id is not None: +user_id = self.db.user.lookup("admin") +messages = self.db.issue.get(issue_id, "messages") +now = date.Date(".") +min_date = now - date.Interval("00:30") +date_range_string = "from " + str(min_date) +msg_ids = self.db.msg.filter(None, {"is_github_comment": True, +"creation": date_range_string}) +if not bool(msg_ids): +msg_id = self.db.msg.create(content=comment, author=user_id, +date=now, is_github_comment=True) +messages.append(msg_id) +self.db.issue.set(issue_id, messages=messages) +self.db.commit() + +def _get_issue_id_using_url(self, url): +pr_id = self.db.pull_request.filter(None, {'url': url}) +pr_exists = len(pr_id) == 1 +if pr_exists: +issue_id = self.db.issue.filter(None, {'pull_requests': pr_id[0]}) +if len(issue_id) == 1: +return issue_id[0] + def _get_issue_ids(self): raise NotImplementedError @@ -166,8 +199,10 @@ class IssueComment(Event): action = self.data['action'].encode('utf-8') issue_id = self._get_issue_ids() url = self._get_url() +comment = self._get_comment() if action == 'created' and issue_id is not None: self.handle_create(url, issue_id) +self.handle_comment(comment) def _get_issue_ids(self): body = self.data['comment']['body'].encode('utf-8') @@ -181,3 +216,26 @@ class IssueComment(Event): def _get_github_username(self): return self.data['issue']['user']['login'].encode('utf-8') + +def _get_comment(self): +comment_user = self.data['comment']['user']['login'].encode('utf-8') +comment = self.data['comment']['body'].encode('utf-8') +url = self.data['comment']['html_url'].encode('utf-8') +return '%s left a comment on GitHub:\n\n%s\n\n%s' % (comment_user, + comment, url) + + +class PullRequestReviewComment(IssueComment): + +def __init__(self, db, data): +self.db = db +self.data = data + +def dispatch(self): +action = self.data['action'].encode('utf-8') +comment = self._get_comment() +if action == 'created': +self.handle_comment(comment) + +def _get_url(self): +return self.data['pull_request']['html_url'] diff --git a/share/roundup/templates/classic/schema.py b/share/roundup/templates/classic/schema.py index 34ae90b..9b548fb 100644 --- a/share/roundup/templates/classic/schema.py +++ b/share/roundup/templates/classic/schema.py @@ -61,7 +61,8 @@ msg = FileClass(db, "msg", summary=String(), files=Multilink("file"), messageid=String(), -inreplyto=String()) +inreplyto=String(), +is_github_com
[Tracker-discuss] [issue589] Add GitHub PR to b.p.o issues using GitHub webhooks (depends on issue586)
Anish Shah added the comment: I have updated the patch with all three changes ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue589> ___diff --git a/roundup/cgi/client.py b/roundup/cgi/client.py index e71983d..abfbf51 100644 --- a/roundup/cgi/client.py +++ b/roundup/cgi/client.py @@ -22,6 +22,7 @@ from roundup.cgi.form_parser import FormParser from roundup.mailer import Mailer, MessageSendError, encode_quopri from roundup.cgi import accept_language from roundup import xmlrpc +from roundup.pull_request import GitHubHandler from roundup.anypy.cookie_ import CookieError, BaseCookie, SimpleCookie, \ get_cookie_date @@ -378,6 +379,8 @@ class Client: try: if self.path == 'xmlrpc': self.handle_xmlrpc() +elif self.path == 'pull_request': +self.handle_pull_request() else: self.inner_main() finally: @@ -385,6 +388,34 @@ class Client: self.db.close() +def handle_pull_request(self): +# Set the charset and language, since other parts of +# Roundup may depend upon that. +self.determine_charset() +self.determine_language() +# Open the database as the correct user. +self.determine_user() +self.check_anonymous_access() + +try: +handler = GitHubHandler(self) +handler.dispatch() +except Unauthorised, message: +self.response_code = 403 +self.write(message) +except UnsupportedMediaType, message: +self.response_code = 415 +self.write(message) +except MethodNotAllowed, message: +self.response_code = 405 +self.write(message) +except Reject, message: +self.response_code = 400 +self.write(message) +else: +self.write("Done!") + + def handle_xmlrpc(self): if self.env.get('CONTENT_TYPE') != 'text/xml': self.write("This is the endpoint of Roundup https://api.github.com/repos/AnishShah/cpython/issues/1","repository_url":"https://api.github.com/repos/AnishShah/cpython","labels_url":"https://api.github.com/repos/AnishShah/cpython/issues/1/labels{/name}","comments_url":"https://api.github.com/repos/AnishShah/cpython/issues/1/comments","events_url":"https://api.github.com/repos/AnishShah/cpython/issues/1/events","html_url":"https://github.com/AnishShah/cpython/pull/1","id":156471938,"number":1,"title":"Test","user":{"login":"AnishShah","id":3175743,"avatar_url":"https://avatars.githubusercontent.com/u/3175743?v=3","gravatar_id":"","url":"https://api.github.com/users/AnishShah","html_url":"https://github.com/AnishShah","followers_url":"https://api.github.com/users/AnishShah/followers","following_url":"https://api.github.com/users/AnishShah/following{/other_user}","gists_url":"https://api.github.com/users/AnishShah/gists{/gist_id}","starred_url":"https://api.github.com/users/AnishShah/sta rred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AnishShah/subscriptions","organizations_url":"https://api.github.com/users/AnishShah/orgs","repos_url":"https://api.github.com/users/AnishShah/repos","events_url":"https://api.github.com/users/AnishShah/events{/privacy}","received_events_url":"https://api.github.com/users/AnishShah/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-05-24T10:22:11Z","updated_at":"2016-05-31T09:05:10Z","closed_at":"2016-05-24T10:23:56Z","pull_request":{"url":"https://api.github.com/repos/AnishShah/cpython/pulls/1","html_url":"https://github.com/AnishShah/cpython/pull/1","diff_url":"https://github.com/AnishShah/cpython/pull/1.diff","patch_url":"https://github.com/AnishShah/cpython/pull/1.patch"},"body":""},"comment":{"url":"https://api.github.com/repos/AnishShah/cpython/issues/comments/222632341","html_url":"https://g ithub.com/AnishShah/cpython/pull/1#issuec
[Tracker-discuss] [issue589] Add GitHub PR to b.p.o issues using GitHub webhooks (depends on issue586)
Anish Shah added the comment: Oops. Got it now. I will include the changes. ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue589> ___ ___ Tracker-discuss mailing list Tracker-discuss@python.org https://mail.python.org/mailman/listinfo/tracker-discuss Code of Conduct: https://www.python.org/psf/codeofconduct/
[Tracker-discuss] [issue589] Add GitHub PR to b.p.o issues using GitHub webhooks (depends on issue586)
Anish Shah added the comment: new tests: - secret key missing - Github event missing in header - non json body - multiple references in PR body - CREATE_ISSUE is not set and no issue is reference in PR - if github field of user is set, then PR/issue is assigned to that user or else anonymous ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue589> ___commit a565735c6ebbb0a664cd7f9e5b68a406094ecf0f Author: Anish Shah <shah.anis...@gmail.com> Date: Wed Jul 27 00:03:46 2016 +0530 Add GitHub PR to bpo using webhooks diff --git a/roundup/cgi/client.py b/roundup/cgi/client.py index e71983d..abfbf51 100644 --- a/roundup/cgi/client.py +++ b/roundup/cgi/client.py @@ -22,6 +22,7 @@ from roundup.cgi.form_parser import FormParser from roundup.mailer import Mailer, MessageSendError, encode_quopri from roundup.cgi import accept_language from roundup import xmlrpc +from roundup.pull_request import GitHubHandler from roundup.anypy.cookie_ import CookieError, BaseCookie, SimpleCookie, \ get_cookie_date @@ -378,6 +379,8 @@ class Client: try: if self.path == 'xmlrpc': self.handle_xmlrpc() +elif self.path == 'pull_request': +self.handle_pull_request() else: self.inner_main() finally: @@ -385,6 +388,34 @@ class Client: self.db.close() +def handle_pull_request(self): +# Set the charset and language, since other parts of +# Roundup may depend upon that. +self.determine_charset() +self.determine_language() +# Open the database as the correct user. +self.determine_user() +self.check_anonymous_access() + +try: +handler = GitHubHandler(self) +handler.dispatch() +except Unauthorised, message: +self.response_code = 403 +self.write(message) +except UnsupportedMediaType, message: +self.response_code = 415 +self.write(message) +except MethodNotAllowed, message: +self.response_code = 405 +self.write(message) +except Reject, message: +self.response_code = 400 +self.write(message) +else: +self.write("Done!") + + def handle_xmlrpc(self): if self.env.get('CONTENT_TYPE') != 'text/xml': self.write("This is the endpoint of Roundup https://api.github.com/repos/AnishShah/cpython/issues/1","repository_url":"https://api.github.com/repos/AnishShah/cpython","labels_url":"https://api.github.com/repos/AnishShah/cpython/issues/1/labels{/name}","comments_url":"https://api.github.com/repos/AnishShah/cpython/issues/1/comments","events_url":"https://api.github.com/repos/AnishShah/cpython/issues/1/events","html_url":"https://github.com/AnishShah/cpython/pull/1","id":156471938,"number":1,"title":"Test","user":{"login":"AnishShah","id":3175743,"avatar_url":"https://avatars.githubusercontent.com/u/3175743?v=3","gravatar_id":"","url":"https://api.github.com/users/AnishShah","html_url":"https://github.com/AnishShah","followers_url":"https://api.github.com/users/AnishShah/followers","following_url":"https://api.github.com/users/AnishShah/following{/other_user}","gists_url":"https://api.github.com/users/AnishShah/gists{/gist_id}","starred_url":"https://api.github.com/users/AnishShah/sta rred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AnishShah/subscriptions","organizations_url":"https://api.github.com/users/AnishShah/orgs","repos_url":"https://api.github.com/users/AnishShah/repos","events_url":"https://api.github.com/users/AnishShah/events{/privacy}","received_events_url":"https://api.github.com/users/AnishShah/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-05-24T10:22:11Z","updated_at":"2016-05-31T09:05:10Z","closed_at":"2016-05-24T10:23:56Z","pull_request":{"url":"https://api.github.com/repos/AnishShah/cpython/pulls/1","html_url":"https://github.com/AnishShah/cpython/pull/1","
[Tracker-discuss] [issue589] Add GitHub PR to b.p.o issues using GitHub webhooks (depends on issue586)
Anish Shah added the comment: > * multiple fixes both in title like you have in pullrequestevent3.txt but also in title Sorry. I didn't get you. You mean, same tests for PR body, right? > Is vulnerable to other exceptions, I'm a lazy person and I test your code with following > command: > curl -X POST -H "content-type: application/json" -H "X-GitHub-Event: pull_request" -d @test/data/pullrequestevent3.txt http://localhost:/python-dev/pull_request > doing so I frequently forgot you have additional data in the testfiles and I'm getting > "ValueError: No JSON object could be decoded" at this point. Verify other exceptions > and throw generic 'Invalid request' in those places (and don't forget to add tests) I was thinking of adding "Exception, e" instead of checking for just KeyError in dispatch method. But that will also catch Unauthorized, MethodNotAllowed and unsupportedmediatype. Can you suggest a better way to do this? ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue589> ___ ___ Tracker-discuss mailing list Tracker-discuss@python.org https://mail.python.org/mailman/listinfo/tracker-discuss Code of Conduct: https://www.python.org/psf/codeofconduct/
[Tracker-discuss] [issue589] Add GitHub PR to b.p.o issues using GitHub webhooks (depends on issue586)
Anish Shah added the comment: Should I throw Reject exception if 'SECRET_KEY' is not set as an environment variable too? ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue589> ___ ___ Tracker-discuss mailing list Tracker-discuss@python.org https://mail.python.org/mailman/listinfo/tracker-discuss Code of Conduct: https://www.python.org/psf/codeofconduct/
[Tracker-discuss] [issue590] Show Pull Request status on b.p.o (depends on issue586, issue589)
Anish Shah added the comment: I have updated the patch ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue590> ___ ___ Tracker-discuss mailing list Tracker-discuss@python.org https://mail.python.org/mailman/listinfo/tracker-discuss Code of Conduct: https://www.python.org/psf/codeofconduct/
[Tracker-discuss] [issue589] Add GitHub PR to b.p.o issues using GitHub webhooks (depends on issue586)
Anish Shah added the comment: I have added few things to this updated patch: - load JSON while extracting - user who creates GitHub PR will be assigned as PR author on bpo if we find github name on bpo or else "anonymous" - if issue is not referenced in PR title or body and an environment variable is set, then a new issue is created on behalf of GitHub PR creator (if we find github name on bpo) ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue589> ___diff --git a/roundup/cgi/client.py b/roundup/cgi/client.py index e71983d..abfbf51 100644 --- a/roundup/cgi/client.py +++ b/roundup/cgi/client.py @@ -22,6 +22,7 @@ from roundup.cgi.form_parser import FormParser from roundup.mailer import Mailer, MessageSendError, encode_quopri from roundup.cgi import accept_language from roundup import xmlrpc +from roundup.pull_request import GitHubHandler from roundup.anypy.cookie_ import CookieError, BaseCookie, SimpleCookie, \ get_cookie_date @@ -378,6 +379,8 @@ class Client: try: if self.path == 'xmlrpc': self.handle_xmlrpc() +elif self.path == 'pull_request': +self.handle_pull_request() else: self.inner_main() finally: @@ -385,6 +388,34 @@ class Client: self.db.close() +def handle_pull_request(self): +# Set the charset and language, since other parts of +# Roundup may depend upon that. +self.determine_charset() +self.determine_language() +# Open the database as the correct user. +self.determine_user() +self.check_anonymous_access() + +try: +handler = GitHubHandler(self) +handler.dispatch() +except Unauthorised, message: +self.response_code = 403 +self.write(message) +except UnsupportedMediaType, message: +self.response_code = 415 +self.write(message) +except MethodNotAllowed, message: +self.response_code = 405 +self.write(message) +except Reject, message: +self.response_code = 400 +self.write(message) +else: +self.write("Done!") + + def handle_xmlrpc(self): if self.env.get('CONTENT_TYPE') != 'text/xml': self.write("This is the endpoint of Roundup \d+)', re.I) + +def handle_create(self, url, issue_id): +issue_exists = len(self.db.issue.filter(None, {'id': issue_id})) == 1 +url_exists = len(self.db.pull_request.filter(None, {'url': url})) == 1 +if issue_exists and not url_exists: +url_id = self.db.pull_request.create(url=url) +urls = self.db.issue.get(issue_id, 'pull_requests') +urls.append(url_id) +self.db.issue.set(issue_id, pull_requests=urls) +self.db.commit() + +def _get_issue_id(self): +raise NotImplementedError + +def _get_url(self): +raise NotImplementedError + + +class PullRequest(Event): + +def __init__(self, db, data): +self.db = db +self.data = data + +def dispatch(self): +github_username = self._get_github_username() +user_id = self.db.user.filter(None, {'github': github_username}) +if len(user_id) == 1: +username = self.db.user.get(user_id[0], 'username') +self.db.setCurrentUser(username) +action = self.data['action'].encode('utf-8') +issue_id = self._get_issue_id() +url = self._get_url() +if action == 'opened' and issue_id is not None: +self.handle_create(url, issue_id) + +def _get_issue_id(self): +title = self.data['pull_request']['title'].encode('utf-8') +body = self.data['pull_request']['body'].encode('utf-8') +title_match = self.issue_re.search(title) +body_match = self.issue_re.search(body) +if body_match: +return body_match.group('id') +elif title_match: +return title_match.group('id') +# No issue id found +create_issue = os.environ.get('CREATE_ISSUE', False) +if create_issue: +return self.db.issue.create(title=title) +return None + +def _get_url(self): +return self.data['pull_request']['html_url'].encode('utf-8') + +def _get_github_username(self): +return self.data['pull_request']['user']['login'].encode('utf-8') + + +class IssueComment(Event): + +def __init__(self, db, data): +self.db = db +self.data = data + +def dispatch(self): +github_username = self._get_github_username() +user_id = self.db.user.filter(None, {'github': github_username}) +if len(user_id) == 1: +
[Tracker-discuss] [issue592] Show GitHub comments on b.p.o
Anish Shah added the comment: Description about this patch: This patch has a handler to handle GitHub PR review/diff comments event. First, it checks if any b.p.o issue is linked to this PR or not. Then, it checks when was the last time a "GitHub" msg was added. If there are no GitHub msg for last "X" minutes (here, 30 minutes), only then this comment is added to b.p.o. issue. ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue592> ___ ___ Tracker-discuss mailing list Tracker-discuss@python.org https://mail.python.org/mailman/listinfo/tracker-discuss Code of Conduct: https://www.python.org/psf/codeofconduct/
[Tracker-discuss] [issue589] Add GitHub PR to b.p.o issues using GitHub webhooks (depends on issue586)
Anish Shah added the comment: > Maybe put the code in with a switch so we can turn it on and off? I'm pretty sure we're going to want it, but not positive. Sorry. I didn't get you. What do you want to turn on and off? ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue589> ___ ___ Tracker-discuss mailing list Tracker-discuss@python.org https://mail.python.org/mailman/listinfo/tracker-discuss Code of Conduct: https://www.python.org/psf/codeofconduct/
[Tracker-discuss] [issue589] Add GitHub PR to b.p.o issues using GitHub webhooks (depends on issue586)
Anish Shah added the comment: Thank you for the review. I will update the patch. @David I can create a new issue if there's no issue number mentioned. But as Brett said that someone might forget to add issue number. I'm currently checking for issue id in PR title, body and issue comments. So, a reviewer/contributor can add a comment "fixes bpoNN" later on. Also, GitHub provides a template system [1] where we can ask the contributor to mention issue number and also whether this is a documentation PR. This might reduce the noise as mentioned by Berker & Brett. But, there will always be someone who won't follow the template system. [1] https://github.com/blog/2111-issue-and-pull-request-templates ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue589> ___ ___ Tracker-discuss mailing list Tracker-discuss@python.org https://mail.python.org/mailman/listinfo/tracker-discuss Code of Conduct: https://www.python.org/psf/codeofconduct/
[Tracker-discuss] [issue587] Link GitHub pull requests in comments (depends on issue 586)
<pre> Anish Shah added the comment: I have updated the patch. :) ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <<a rel="nofollow" href="http://psf.upfronthosting.co.za/roundup/meta/issue587">http://psf.upfronthosting.co.za/roundup/meta/issue587</a>> ___</pre><pre>diff --git a/extensions/local_replace.py b/extensions/local_replace.py index 1dd0e89..b05e3d4 100644 --- a/extensions/local_replace.py +++ b/extensions/local_replace.py @@ -111,6 +111,10 @@ substitutions = [ # if the issue number is too big the db will explode -- limit it to 7 digits issue_re = re.compile(r'(?P<text>(\#|\b(?<![-/_])issue)\s*(?P<id>1?\d{1,6}))\b', re.I) +# PR number, pull request number, pullrequest number +pullrequest_re = re.compile(r'(?P<text>(\b(?<![-/_])(PR|pull\s*request))\s*(?P<pr_no>1?\d{1,6}))\b', +re.I) + class PyDevStringHTMLProperty(StringHTMLProperty): def _hyper_repl(self, match): @@ -142,6 +146,7 @@ class PyDevStringHTMLProperty(StringHTMLProperty): message = cre.sub(replacement, message) # finally add links for issues message = issue_re.sub(self._linkify_issue, message) +message = pullrequest_re.sub(self._linkify_pull_request, message) return message def _linkify_issue(self, match): @@ -165,6 +170,15 @@ class PyDevStringHTMLProperty(StringHTMLProperty): return template % dict(issue_id=issue_id, title=title, status=status, text=text) +def _linkify_pull_request(self, match): +"""Turn a pullrequest (e.g. 'PR 123') to an HTML link""" +template = ('<a href="%(link)s" target="_blank">%(text)s</a>') +pr_no = match.group('pr_no') +text = match.group('text') +base_url = '<a rel="nofollow" href="https://github.com/python/cpython/pull/{}">https://github.com/python/cpython/pull/{}</a>' +pr_url = base_url.format(pr_no) +return template % dict(link=pr_url, text=text) + noise_changes = re.compile('(nosy_count|message_count)\: \d+\.0( -> \d+\.0)?') diff --git a/extensions/test/local_replace_data.txt b/extensions/test/local_replace_data.txt index bdf1eb9..dbedc6c 100644 --- a/extensions/test/local_replace_data.txt +++ b/extensions/test/local_replace_data.txt @@ -234,3 +234,9 @@ see devguide/committing.html#using-several-working-copies see <a href="<a rel="nofollow" href="http://docs.python.org/devguide/committing.html#using-several-working-copies"">http://docs.python.org/devguide/committing.html#using-several-working-copies"</a>;>devguide/committing.html#using-several-working-copies</a> see devguide/committing#using-several-working-copies see <a href="<a rel="nofollow" href="http://docs.python.org/devguide/committing#using-several-working-copies"">http://docs.python.org/devguide/committing#using-several-working-copies"</a>;>devguide/committing#using-several-working-copies</a> +check my pullrequest 1000 on github +check my <a href="<a rel="nofollow" href="https://github.com/python/cpython/pull/1000"">https://github.com/python/cpython/pull/1000"</a>; target="_blank">pullrequest 1000</a> on github +check my PR 1000 on github +check my <a href="<a rel="nofollow" href="https://github.com/python/cpython/pull/1000"">https://github.com/python/cpython/pull/1000"</a>; target="_blank">PR 1000</a> on github +check my pull request 1000 on github +check my <a href="<a rel="nofollow" href="https://github.com/python/cpython/pull/1000"">https://github.com/python/cpython/pull/1000"</a>; target="_blank">pull request 1000</a> on github </pre><pre>___ Tracker-discuss mailing list Tracker-discuss@python.org <a rel="nofollow" href="https://mail.python.org/mailman/listinfo/tracker-discuss">https://mail.python.org/mailman/listinfo/tracker-discuss</a> Code of Conduct: <a rel="nofollow" href="https://www.python.org/psf/codeofconduct/">https://www.python.org/psf/codeofconduct/</a></pre>
[Tracker-discuss] [issue586] Add GitHub Pull Request URL on issue page
Anish Shah added the comment: I have updated the patch according to reviews suggested by @maciej.szulik and @berker.peksag Description:- This patch adds a new table "pull_request" which is used to save GitHub PR URLs. URL can be added manually using "GitHub PR" field on issue's page. --- GitHub PR URL will also be added automatically in two ways - for that, you can have a look at issue589 and issue600 ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue586> ___diff --git a/detectors/pull_request.py b/detectors/pull_request.py new file mode 100644 index 000..6a206e5 --- /dev/null +++ b/detectors/pull_request.py @@ -0,0 +1,35 @@ +# Auditor for GitHub URLs +# Check if it is a valid GitHub Pull Request URL and extract PR number + +import re +import urlparse + + +def validate_github_url(db, cl, nodeid, newvalues): +url = newvalues.get('url', '') +if url == '': +return +parsed_url = urlparse.urlparse(url) +if parsed_url.scheme == '': +url = 'https://' + url +parsed_url = urlparse.urlparse(url) +if parsed_url.scheme not in ('http', 'https'): +raise ValueError("Invalid URL scheme in GitHub PR") +if 'github.com' not in parsed_url.netloc or 'pull' not in parsed_url.path: +raise ValueError("Invalid GitHub PR") +newvalues['url'] = parsed_url.geturl() +regex = re.match(".*/pull/(\d+)", newvalues['url']) +if regex and len(regex.groups()) == 1: +pr_no = regex.groups()[0] +try: +db.pull_request.lookup(pr_no) +raise ValueError("GitHub PR already added to an issue") +except KeyError: +newvalues['pr_no'] = pr_no +else: +raise ValueError("Invalid GitHub PR") + + +def init(db): +db.pull_request.audit('create', validate_github_url) +db.pull_request.audit('set', validate_github_url) diff --git a/html/issue.item.html b/html/issue.item.html index ddc4ec3..17eecd1 100644 --- a/html/issue.item.html +++ b/html/issue.item.html @@ -220,6 +220,14 @@ + + GitHub PR: + + + + + + @@ -273,6 +281,43 @@ + + GitHub Pull Requests + + Link + Author + Date + Edit + Remove + + + + +GitHub PR link + + + + creator's name + + + creation date + + +edit + + + + + + + + + + + diff --git a/schema.py b/schema.py index d91bf7b..c125a5f 100644 --- a/schema.py +++ b/schema.py @@ -173,6 +173,12 @@ hgrepo = Class(db, "hgrepo", patchbranch=String(), ) +pull_request = Class(db, "pull_request", + url=String(), + pr_no=String(),) + +pull_request.setkey("pr_no") + # IssueClass automatically gets these properties in addition to the Class ones: # title = String() # messages = Multilink("msg") @@ -194,7 +200,8 @@ issue = IssueClass(db, "issue", stage=Link('stage'), nosy_count=Number(), message_count=Number(), - hgrepos=Multilink('hgrepo')) + hgrepos=Multilink('hgrepo'), + pull_requests=Multilink('pull_request')) # # TRACKER SECURITY SETTINGS @@ -222,7 +229,7 @@ for r in 'User', 'Developer', 'Coordinator': for cl in ('issue_type', 'severity', 'component', 'version', 'priority', 'stage', 'status', 'resolution', - 'issue', 'keyword', 'hgrepo'): + 'issue', 'keyword', 'hgrepo', 'pull_request'): db.security.addPermissionToRole('User', 'View', cl) db.security.addPermissionToRole('Anonymous', 'View', cl) @@ -233,6 +240,13 @@ p = db.security.addPermission(name='Edit', klass='hgrepo', check=may_edit_hgrepo properties=['url', 'patchbranch']) db.security.addPermissionToRole('User', p) +def may_edit_github_url(db, userid, itemid): +return userid == db.pull_request.get(itemid, "creator") +db.security.addPermissionToRole('User', 'Create', 'pull_request') +p = db.security.addPermission(name='Edit', klass='pull_request', + check=may_edit_github_url, properties=['url']) +db.security.addPermissionToRole('User', p) + class may_view_spam: def __init__(self, klassname): self.klassname = klassname @@ -292,7 +306,7 @@ p = db.security.addPermission(name='Create', klass='issue', properties=('title', 'type', 'components', 'versions', 'severity', - 'messages', 'files', 'nosy', 'hgrepos'), +
[Tracker-discuss] [issue586] Add GitHub Pull Request URL on issue page
Anish Shah added the comment: @berker.peksag Thank you for the review. I will make those changes. > Also, I'm not fan of such a manual work. I would prefer to have a JSON > endpoint > which queries open pull requests on python/cpython and match if > the title of a > pull request contains the issue number. This is the first patch as a part of my GSoC project. You can check issue589 where I'm using GitHub webhooks to link issues automatically. ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue586> ___ ___ Tracker-discuss mailing list Tracker-discuss@python.org https://mail.python.org/mailman/listinfo/tracker-discuss Code of Conduct: https://www.python.org/psf/codeofconduct/
[Tracker-discuss] [issue600] Convert patches to GitHub Pull Request
New submission from Anish Shah: This is an initial patch to convert .patch/.diff files to GitHub Pull Requests. -- files: patch-to-pr.diff messages: 3055 nosy: anish.shah, maciej.szulik priority: feature status: in-progress title: Convert patches to GitHub Pull Request ___ PSF Meta Tracker <metatrac...@psf.upfronthosting.co.za> <http://psf.upfronthosting.co.za/roundup/meta/issue600> ___diff --git a/detectors/patches.py b/detectors/patches.py index 18d3db4..7a27d5f 100644 --- a/detectors/patches.py +++ b/detectors/patches.py @@ -5,16 +5,83 @@ import posixpath import identify_patch +import os +import subprocess +import string +import random +import json +import requests patchtypes = ('.diff', '.patch') sourcetypes = ('.diff', '.patch', '.py') +def create_pull_request(db, head, base, issue_id, issue_title): +endpoint = 'https://api.github.com/repos/AnishShah/cpython/pulls' +access_token = os.environ['ACCESS_TOKEN'] +headers = {'Authorization': 'token {}'.format(access_token)} +data = json.dumps({ +"title": "{}".format(issue_title), +"body": "fixes issue {}".format(issue_id), +"base": base, "head": head}) +response = requests.post(endpoint, headers=headers, data=data) +if not response.ok: +raise Exception('Error generating pull request') +else: +response_body = response.json() +url = response_body['html_url'] +state = response_body['state'] +pr_id = db.github_pullrequest_url.create(url=url, state=state) +issue_pr = db.issue.get(issue_id, 'github_pullrequest_urls') +issue_pr.append(pr_id) +db.issue.set(issue_id, github_pullrequest_urls=issue_pr) +db.commit() + +def git_command(command, path): +process = subprocess.Popen(command, cwd=path, shell=True, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) +out, err = process.communicate() +# err takes stdout +# if err: +# raise Exception(err) + +def git_workflow(db, issue_id, file_id): +path = os.environ['GIT_PATH'] +versions = map(lambda id: (db.version.get(id, 'name'), db.version.get(id, 'order')), + db.issue.get(issue_id, 'versions')) +title = db.issue.get(issue_id, 'title') +commit_msg = 'Fixes issue {} : {}'.format(issue_id, title) +if len(versions) == 0: +parent_branch = "master" +else: +version = versions.pop() +if version[1] == 1: +parent_branch = "master" +else: +parent_branch = version[0].split()[1] +branch_name = ''.join([random.choice(string.ascii_letters) for i in range(random.choice(range(10, 20)))]) +filename = db.file.get(file_id, 'name') +content = db.file.get(file_id, 'content') +fp = open(os.path.join(path, filename), 'wb') +fp.write(content) +fp.close() +git_command("git checkout {}".format(parent_branch), path) +git_command("git checkout -b {}".format(branch_name), path) +git_command("git apply {}".format(filename), path) +git_command("git add -A", path) +git_command("git commit -m \"{}\"".format(commit_msg), path) +git_command("git push origin {}".format(branch_name), path) +git_command("git checkout {}".format(parent_branch), path) +git_command("git branch -D {}".format(branch_name), path) +create_pull_request(db, branch_name, parent_branch, issue_id, title) + + def ispatch(file, types): return posixpath.splitext(file)[1] in types def patches_text_plain(db, cl, nodeid, newvalues): if ispatch(newvalues['name'], sourcetypes): newvalues['type'] = 'text/plain' +# git_workflow(newvalues) def patches_keyword(db, cl, nodeid, newvalues): # Check whether there are any new files @@ -26,6 +93,7 @@ def patches_keyword(db, cl, nodeid, newvalues): for fileid in newfiles: if ispatch(db.file.get(fileid, 'name'), patchtypes): newpatch = True +git_workflow(db, nodeid, fileid) break if newpatch: # Add the patch keyword if its not already there diff --git a/initial_data.py b/initial_data.py index dc0ed4f..a9eee3a 100644 --- a/initial_data.py +++ b/initial_data.py @@ -49,13 +49,12 @@ component.create(name="Windows", order="18") component.create(name="XML", order="19") version = db.getclass('version') -version.create(name='Python 3.1', order='1') -version.create(name='Python 3.0', order='2') -version.create(name='Python 2.7', order='3') -version.create(name='Python 2.6', order='4') -version.create(name='Python 2.5', order='5') -version.create(name='Python 2.4', order='6') -