change status when WIP prefix is removed (#73090)
This commit is contained in:
parent
75633e9a2b
commit
48f4c83008
|
@ -91,9 +91,6 @@ def get_handler(payload):
|
|||
return handle_pull_request_approved, 'pull_request.approved'
|
||||
return None, None
|
||||
if payload.get('action') == 'edited' and payload.get('pull_request'):
|
||||
if payload['pull_request']['title'].lower().startswith('wip:'):
|
||||
return handle_pull_request_draft, 'pull_request.draft'
|
||||
|
||||
return handle_pull_request_edited, 'pull_request.edited'
|
||||
if (
|
||||
payload.get('action') == 'closed'
|
||||
|
@ -159,13 +156,14 @@ def make_handler(*actions):
|
|||
def inner(issue, payload, project):
|
||||
if is_excluded_project(project):
|
||||
logging.info('Issue belongs to excluded project %s', project.id)
|
||||
return
|
||||
return False
|
||||
flat_payload = flatten(payload)
|
||||
for action in actions:
|
||||
try:
|
||||
action(issue, flat_payload)
|
||||
except Abort:
|
||||
return
|
||||
return False
|
||||
return True
|
||||
|
||||
return inner
|
||||
|
||||
|
@ -226,6 +224,17 @@ def skip_if_notes_include(field, reason):
|
|||
return inner
|
||||
|
||||
|
||||
def skip_unless_notes_include(text, reason):
|
||||
def inner(issue, payload):
|
||||
for entry in issue.journals:
|
||||
if text in entry.notes:
|
||||
break
|
||||
else:
|
||||
raise Abort(reason)
|
||||
|
||||
return inner
|
||||
|
||||
|
||||
def skip_if_status(status):
|
||||
def inner(issue, payload):
|
||||
if issue.status.id == status:
|
||||
|
@ -234,6 +243,14 @@ def skip_if_status(status):
|
|||
return inner
|
||||
|
||||
|
||||
def skip_if_not_status(status):
|
||||
def inner(issue, payload):
|
||||
if issue.status.id != status:
|
||||
raise Abort(f'Issue not in status {status}')
|
||||
|
||||
return inner
|
||||
|
||||
|
||||
def set_value_if_empty(field, value):
|
||||
def inner(issue, payload):
|
||||
if not payload.get(field):
|
||||
|
@ -257,25 +274,43 @@ handle_pull_request_opened_draft = make_handler(
|
|||
save(),
|
||||
)
|
||||
|
||||
handle_pull_request_edited = make_handler(
|
||||
skip_if_notes_include('pull_request_url', 'Pull request already linked in issue'),
|
||||
assign_to('pull_request_user_username'),
|
||||
set_status(REDMINE_STATUSES['En cours'], unless=CLOSED_STATUSES),
|
||||
add_note(
|
||||
'{pull_request_user_full_name} ({pull_request_user_username}) a lié une pull request sur Gitea concernant cette demande :\n\n* URL : {pull_request_url}\n* Titre : {pull_request_title}\n* Modifications : {pull_request_url}/files'
|
||||
),
|
||||
save(),
|
||||
)
|
||||
|
||||
handle_pull_request_draft = make_handler(
|
||||
skip_if_status(REDMINE_STATUSES['En cours']),
|
||||
skip_if_not_draft,
|
||||
set_status(REDMINE_STATUSES['En cours'], unless=CLOSED_STATUSES),
|
||||
add_note(
|
||||
'{pull_request_user_full_name} ({pull_request_user_username}) a commencé à travailler sur une pull request sur Gitea concernant cette demande :\n\n* URL : {pull_request_url}\n* Titre : {pull_request_title}\n* Modifications : {pull_request_url}/files'
|
||||
),
|
||||
save(),
|
||||
)
|
||||
def handle_pull_request_edited(issue, payload, project):
|
||||
if payload['pull_request']['title'].lower().startswith('wip:'):
|
||||
func = make_handler(
|
||||
skip_if_status(REDMINE_STATUSES['En cours']),
|
||||
skip_if_not_draft,
|
||||
set_status(REDMINE_STATUSES['En cours'], unless=CLOSED_STATUSES),
|
||||
add_note(
|
||||
'{pull_request_user_full_name} ({pull_request_user_username}) a commencé à travailler sur une pull request sur Gitea concernant cette demande :\n\n* URL : {pull_request_url}\n* Titre : {pull_request_title}\n* Modifications : {pull_request_url}/files'
|
||||
),
|
||||
save(),
|
||||
)
|
||||
return func(issue, payload, project)
|
||||
|
||||
# maybe it was wip and is no more
|
||||
func = make_handler(
|
||||
skip_if_not_status(REDMINE_STATUSES['En cours']),
|
||||
skip_unless_notes_include('Titre : WIP', 'Pull request do not mention a draft title'),
|
||||
set_status(REDMINE_STATUSES['Solution proposée']),
|
||||
save(),
|
||||
)
|
||||
if func(issue, payload, project) is True:
|
||||
# the issue was changed, stop now.
|
||||
return
|
||||
|
||||
# default behaviour
|
||||
func = make_handler(
|
||||
skip_if_notes_include('pull_request_url', 'Pull request already linked in issue'),
|
||||
assign_to('pull_request_user_username'),
|
||||
set_status(REDMINE_STATUSES['En cours'], unless=CLOSED_STATUSES),
|
||||
add_note(
|
||||
'{pull_request_user_full_name} ({pull_request_user_username}) a lié une pull request sur Gitea concernant cette demande :\n\n* URL : {pull_request_url}\n* Titre : {pull_request_title}\n* Modifications : {pull_request_url}/files'
|
||||
),
|
||||
save(),
|
||||
)
|
||||
return func(issue, payload, project)
|
||||
|
||||
|
||||
handle_pull_request_merged = make_handler(
|
||||
set_status(REDMINE_STATUSES['Résolu'], unless=CLOSED_STATUSES),
|
||||
|
|
54
test_app.py
54
test_app.py
|
@ -28,8 +28,8 @@ def client():
|
|||
),
|
||||
(
|
||||
{'action': 'edited', 'pull_request': {'title': 'WIP: something'}},
|
||||
gitea_redmine.handle_pull_request_draft,
|
||||
'pull_request.draft',
|
||||
gitea_redmine.handle_pull_request_edited,
|
||||
'pull_request.edited',
|
||||
),
|
||||
(
|
||||
{'action': 'reviewed', 'review': {"type": "pull_request_review_approved"}},
|
||||
|
@ -201,6 +201,53 @@ def test_handle_pull_request_edited(mocker):
|
|||
issue.save.assert_called_once()
|
||||
|
||||
|
||||
def test_handle_pull_request_edited_wip_removal(mocker):
|
||||
redmine_user = mocker.Mock(id=42)
|
||||
get_redmine_user = mocker.patch.object(gitea_redmine, 'get_redmine_user', return_value=redmine_user)
|
||||
|
||||
payload = {
|
||||
"action": "opened",
|
||||
"number": 2,
|
||||
"pull_request": {
|
||||
"id": 7,
|
||||
"url": "https://gitea.entrouvert.org/entrouvert/gitea-redmine/pulls/2",
|
||||
"number": 2,
|
||||
"user": {
|
||||
"id": 7,
|
||||
"login": "testuser",
|
||||
"full_name": "Test User",
|
||||
"email": "test_user@noreply.gitea.entrouvert.org",
|
||||
"username": "testuser",
|
||||
},
|
||||
"title": "WIP: Foo",
|
||||
"body": "...",
|
||||
},
|
||||
}
|
||||
project = mocker.Mock()
|
||||
project.parent = None
|
||||
issue = mocker.Mock(journals=[])
|
||||
gitea_redmine.handle_pull_request_opened_draft(issue, payload, project)
|
||||
|
||||
assert issue.assigned_to_id == redmine_user.id
|
||||
assert issue.status_id == gitea_redmine.REDMINE_STATUSES['En cours']
|
||||
issue.save.assert_called_once()
|
||||
|
||||
issue.status.id = issue.status_id
|
||||
issue.journals = [
|
||||
mocker.Mock(notes='* URL : %(url)s\n* Titre : %(title)s' % payload['pull_request']),
|
||||
]
|
||||
payload['action'] = 'edited'
|
||||
payload['pull_request']['title'] = 'Foo' # remove WIP: prefix
|
||||
gitea_redmine.handle_pull_request_edited(issue, payload, project)
|
||||
assert issue.status_id == gitea_redmine.REDMINE_STATUSES['Solution proposée']
|
||||
assert issue.save.call_count == 2
|
||||
|
||||
# another webhook call, do not change issue
|
||||
issue.status.id = issue.status_id
|
||||
gitea_redmine.handle_pull_request_edited(issue, payload, project)
|
||||
assert issue.save.call_count == 2
|
||||
|
||||
|
||||
def test_handle_pull_request_draft(mocker):
|
||||
payload = {
|
||||
"action": "edited",
|
||||
|
@ -223,7 +270,7 @@ def test_handle_pull_request_draft(mocker):
|
|||
project = mocker.Mock()
|
||||
project.parent = None
|
||||
issue = mocker.Mock(journals=[])
|
||||
gitea_redmine.handle_pull_request_draft(issue, payload, project)
|
||||
gitea_redmine.handle_pull_request_edited(issue, payload, project)
|
||||
|
||||
assert issue.status_id == gitea_redmine.REDMINE_STATUSES['En cours']
|
||||
assert issue.notes == (
|
||||
|
@ -241,6 +288,7 @@ def test_handle_pull_request_edited_already_linked_does_nothing(mocker):
|
|||
"action": "edited",
|
||||
"pull_request": {
|
||||
"url": "https://gitea.entrouvert.org/entrouvert/gitea-redmine/pulls/2",
|
||||
"title": "Foo",
|
||||
},
|
||||
}
|
||||
project = mocker.Mock()
|
||||
|
|
Loading…
Reference in New Issue