mirror of
https://github.com/odoo/runbot.git
synced 2025-03-15 15:35:46 +07:00
parent
18736d282f
commit
d9661064d6
25
conftest.py
25
conftest.py
@ -402,6 +402,20 @@ class Repo:
|
||||
'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):
|
||||
s = self._session
|
||||
if token:
|
||||
@ -809,15 +823,18 @@ class PR:
|
||||
)
|
||||
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
|
||||
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={
|
||||
prop: value
|
||||
})
|
||||
}, headers=headers)
|
||||
assert 200 <= r.status_code < 300, r.json()
|
||||
|
||||
def open(self):
|
||||
self._set_prop('state', 'open')
|
||||
def open(self, token=None):
|
||||
self._set_prop('state', 'open', token=token)
|
||||
|
||||
def close(self):
|
||||
self._set_prop('state', 'closed')
|
||||
|
@ -192,15 +192,24 @@ def handle_pr(env, event):
|
||||
else:
|
||||
return 'Ignored: could not lock rows (probably being merged)'
|
||||
|
||||
if event['action'] == 'reopened' and 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'],
|
||||
})
|
||||
if event['action'] == 'reopened' :
|
||||
if pr_obj.state == 'merged':
|
||||
env['runbot_merge.pull_requests.feedback'].create({
|
||||
'repository': pr_obj.repository.id,
|
||||
'pull_request': pr_obj.number,
|
||||
'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'])
|
||||
return "Not handling {} yet".format(event['action'])
|
||||
|
@ -962,6 +962,49 @@ def test_reopen_state(env, repo):
|
||||
assert pr.state == 'validated', \
|
||||
"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:
|
||||
def test_basic(self, env, repo, config):
|
||||
""" check that mergebot can work on a repo with no CI at all
|
||||
|
Loading…
Reference in New Issue
Block a user