mirror of
https://github.com/odoo/runbot.git
synced 2025-03-27 13:25:47 +07:00
parent
18736d282f
commit
d9661064d6
25
conftest.py
25
conftest.py
@ -402,6 +402,20 @@ class Repo:
|
|||||||
'ignored': True,
|
'ignored': True,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
def add_collaborator(self, login, token):
|
||||||
|
# send invitation to user
|
||||||
|
r = self._session.put('https://api.github.com/repos/{}/collaborators/{}'.format(self.name, login))
|
||||||
|
assert r.ok, r.json()
|
||||||
|
# accept invitation on behalf of user
|
||||||
|
r = requests.patch('https://api.github.com/user/repository_invitations/{}'.format(r.json()['id']), headers={
|
||||||
|
'Authorization': 'token ' + token
|
||||||
|
})
|
||||||
|
assert r.ok, r.json()
|
||||||
|
# sanity check that user is part of collaborators
|
||||||
|
r = self._session.get('https://api.github.com/repos/{}/collaborators'.format(self.name))
|
||||||
|
assert r.ok, r.json()
|
||||||
|
assert any(login == c['login'] for c in r.json())
|
||||||
|
|
||||||
def _get_session(self, token):
|
def _get_session(self, token):
|
||||||
s = self._session
|
s = self._session
|
||||||
if token:
|
if token:
|
||||||
@ -809,15 +823,18 @@ class PR:
|
|||||||
)
|
)
|
||||||
assert r.status_code == 204, r.json()
|
assert r.status_code == 204, r.json()
|
||||||
|
|
||||||
def _set_prop(self, prop, value):
|
def _set_prop(self, prop, value, token=None):
|
||||||
assert self.repo.hook
|
assert self.repo.hook
|
||||||
|
headers = {}
|
||||||
|
if token:
|
||||||
|
headers['Authorization'] = 'token ' + token
|
||||||
r = self.repo._session.patch('https://api.github.com/repos/{}/pulls/{}'.format(self.repo.name, self.number), json={
|
r = self.repo._session.patch('https://api.github.com/repos/{}/pulls/{}'.format(self.repo.name, self.number), json={
|
||||||
prop: value
|
prop: value
|
||||||
})
|
}, headers=headers)
|
||||||
assert 200 <= r.status_code < 300, r.json()
|
assert 200 <= r.status_code < 300, r.json()
|
||||||
|
|
||||||
def open(self):
|
def open(self, token=None):
|
||||||
self._set_prop('state', 'open')
|
self._set_prop('state', 'open', token=token)
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
self._set_prop('state', 'closed')
|
self._set_prop('state', 'closed')
|
||||||
|
@ -192,15 +192,24 @@ def handle_pr(env, event):
|
|||||||
else:
|
else:
|
||||||
return 'Ignored: could not lock rows (probably being merged)'
|
return 'Ignored: could not lock rows (probably being merged)'
|
||||||
|
|
||||||
if event['action'] == 'reopened' and pr_obj.state == 'closed':
|
if event['action'] == 'reopened' :
|
||||||
_logger.info('%s reopening %s', event['sender']['login'], pr_obj.display_name)
|
if pr_obj.state == 'merged':
|
||||||
pr_obj.write({
|
env['runbot_merge.pull_requests.feedback'].create({
|
||||||
'state': 'opened',
|
'repository': pr_obj.repository.id,
|
||||||
# updating the head triggers a revalidation
|
'pull_request': pr_obj.number,
|
||||||
'head': pr['head']['sha'],
|
'close': True,
|
||||||
})
|
'message': "@%s ya silly goose you can't reopen a PR that's been merged PR." % event['sender']['login']
|
||||||
|
})
|
||||||
|
|
||||||
return 'Reopened {}'.format(pr_obj.id)
|
if pr_obj.state == 'closed':
|
||||||
|
_logger.info('%s reopening %s', event['sender']['login'], pr_obj.display_name)
|
||||||
|
pr_obj.write({
|
||||||
|
'state': 'opened',
|
||||||
|
# updating the head triggers a revalidation
|
||||||
|
'head': pr['head']['sha'],
|
||||||
|
})
|
||||||
|
|
||||||
|
return 'Reopened {}'.format(pr_obj.id)
|
||||||
|
|
||||||
_logger.info("Ignoring event %s on PR %s", event['action'], pr['number'])
|
_logger.info("Ignoring event %s on PR %s", event['action'], pr['number'])
|
||||||
return "Not handling {} yet".format(event['action'])
|
return "Not handling {} yet".format(event['action'])
|
||||||
|
@ -962,6 +962,49 @@ def test_reopen_state(env, repo):
|
|||||||
assert pr.state == 'validated', \
|
assert pr.state == 'validated', \
|
||||||
"if a PR is reopened and had a CI'd head, it should be validated immediately"
|
"if a PR is reopened and had a CI'd head, it should be validated immediately"
|
||||||
|
|
||||||
|
def test_reopen_merged_pr(env, repo, config, users):
|
||||||
|
""" Reopening a *merged* PR should cause us to immediately close it again,
|
||||||
|
and insult whoever did it
|
||||||
|
"""
|
||||||
|
with repo:
|
||||||
|
[m] = repo.make_commits(
|
||||||
|
None,
|
||||||
|
repo.Commit('initial', tree={'0': '0'}),
|
||||||
|
ref = 'heads/master'
|
||||||
|
)
|
||||||
|
|
||||||
|
[c] = repo.make_commits(
|
||||||
|
m, repo.Commit('second', tree={'0': '1'}),
|
||||||
|
ref='heads/abranch'
|
||||||
|
)
|
||||||
|
prx = repo.make_pr(target='master', head='abranch')
|
||||||
|
repo.post_status(c, 'success', 'legal/cla')
|
||||||
|
repo.post_status(c, 'success', 'ci/runbot')
|
||||||
|
prx.post_comment('hansen r+', config['role_reviewer']['token'])
|
||||||
|
env.run_crons()
|
||||||
|
|
||||||
|
with repo:
|
||||||
|
repo.post_status('staging.master', 'success', 'legal/cla')
|
||||||
|
repo.post_status('staging.master', 'success', 'ci/runbot')
|
||||||
|
env.run_crons()
|
||||||
|
pr = env['runbot_merge.pull_requests'].search([
|
||||||
|
('repository.name', '=', repo.name),
|
||||||
|
('number', '=', prx.number)
|
||||||
|
])
|
||||||
|
assert prx.state == 'closed'
|
||||||
|
assert pr.state == 'merged'
|
||||||
|
|
||||||
|
repo.add_collaborator(users['other'], config['role_other']['token'])
|
||||||
|
with repo:
|
||||||
|
prx.open(config['role_other']['token'])
|
||||||
|
env.run_crons()
|
||||||
|
assert prx.state == 'closed'
|
||||||
|
assert pr.state == 'merged'
|
||||||
|
assert prx.comments == [
|
||||||
|
(users['reviewer'], 'hansen r+'),
|
||||||
|
(users['user'], "@%s ya silly goose you can't reopen a PR that's been merged PR." % users['other'])
|
||||||
|
]
|
||||||
|
|
||||||
class TestNoRequiredStatus:
|
class TestNoRequiredStatus:
|
||||||
def test_basic(self, env, repo, config):
|
def test_basic(self, env, repo, config):
|
||||||
""" check that mergebot can work on a repo with no CI at all
|
""" check that mergebot can work on a repo with no CI at all
|
||||||
|
Loading…
Reference in New Issue
Block a user