mirror of
https://github.com/odoo/runbot.git
synced 2025-03-27 13:25:47 +07:00
[IMP] mergebot: staging endpoints
- use lingo `staged` and `merged` for clarity (instead of `heads` and `commits`) - convert from json-rpc to regular HTTP to make easier to call - add the staged and merged heads when returning staging data - return more complete objects (rather than a list of ids) when matching stagings based on commits / heads Fixes #1018
This commit is contained in:
parent
89411f968f
commit
7d5c3dcb73
@ -8,6 +8,7 @@ from datetime import datetime, timedelta
|
|||||||
from typing import Callable
|
from typing import Callable
|
||||||
|
|
||||||
import sentry_sdk
|
import sentry_sdk
|
||||||
|
from werkzeug.exceptions import NotFound, UnprocessableEntity
|
||||||
|
|
||||||
from odoo.api import Environment
|
from odoo.api import Environment
|
||||||
from odoo.http import Controller, request, route, Response
|
from odoo.http import Controller, request, route, Response
|
||||||
@ -18,40 +19,56 @@ from .. import utils, github
|
|||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
def staging_dict(staging):
|
||||||
|
return {
|
||||||
|
'id': staging.id,
|
||||||
|
'pull_requests': staging.batch_ids.prs.mapped(lambda p: {
|
||||||
|
'name': p.display_name,
|
||||||
|
'repository': p.repository.name,
|
||||||
|
'number': p.number,
|
||||||
|
}),
|
||||||
|
'merged': staging.commit_ids.mapped('sha'),
|
||||||
|
'staged': staging.head_ids.mapped('sha'),
|
||||||
|
}
|
||||||
|
|
||||||
class MergebotController(Controller):
|
class MergebotController(Controller):
|
||||||
@route('/runbot_merge/stagings', auth='none', type='json')
|
@route('/runbot_merge/stagings', auth='none', type='http', methods=['GET'])
|
||||||
def stagings_for_commits(self, commits=None, heads=None):
|
def stagings_for_commits(self, **kw):
|
||||||
Stagings = request.env(user=1)['runbot_merge.stagings'].sudo()
|
commits = request.httprequest.args.getlist('merged')
|
||||||
if commits:
|
heads = request.httprequest.args.getlist('staged')
|
||||||
stagings = Stagings.for_commits(*commits)
|
if bool(commits) ^ bool(heads):
|
||||||
elif heads:
|
Stagings = request.env(user=1)['runbot_merge.stagings'].sudo()
|
||||||
stagings = Stagings.for_heads(*heads)
|
if commits:
|
||||||
|
stagings = Stagings.for_commits(*commits)
|
||||||
|
else:
|
||||||
|
stagings = Stagings.for_heads(*heads)
|
||||||
|
|
||||||
|
# can pass `?state=` to get stagings in any state
|
||||||
|
if state := request.httprequest.args.get('state', 'success'):
|
||||||
|
stagings = stagings.filtered(lambda s: s.state == state)
|
||||||
|
return request.make_json_response(stagings.mapped(staging_dict))
|
||||||
else:
|
else:
|
||||||
raise ValueError('Must receive one of "commits" or "heads" kwarg')
|
raise UnprocessableEntity("Must receive either `merged` or `staged` query parameters (can receive multiple of either)")
|
||||||
|
|
||||||
return stagings.ids
|
@route('/runbot_merge/stagings/<int:staging>', auth='none', type='http', methods=['GET'])
|
||||||
|
|
||||||
@route('/runbot_merge/stagings/<int:staging>', auth='none', type='json')
|
|
||||||
def prs_for_staging(self, staging):
|
def prs_for_staging(self, staging):
|
||||||
staging = request.env(user=1)['runbot_merge.stagings'].browse(staging)
|
staging = request.env(user=1)['runbot_merge.stagings'].browse(staging).sudo()
|
||||||
return [
|
if not staging.exists:
|
||||||
batch.prs.mapped(lambda p: {
|
raise NotFound()
|
||||||
'name': p.display_name,
|
|
||||||
'repository': p.repository.name,
|
|
||||||
'number': p.number,
|
|
||||||
})
|
|
||||||
for batch in staging.sudo().batch_ids
|
|
||||||
]
|
|
||||||
|
|
||||||
@route('/runbot_merge/stagings/<int:from_staging>/<int:to_staging>', auth='none', type='json')
|
return request.make_json_response(staging_dict(staging))
|
||||||
def prs_for_stagings(self, from_staging, to_staging, include_from=True, include_to=True):
|
|
||||||
|
@route('/runbot_merge/stagings/<int:from_staging>/<int:to_staging>', auth='none', type='http', methods=['GET'])
|
||||||
|
def prs_for_stagings(self, from_staging, to_staging, include_from='1', include_to='1'):
|
||||||
Stagings = request.env(user=1, context={"active_test": False})['runbot_merge.stagings']
|
Stagings = request.env(user=1, context={"active_test": False})['runbot_merge.stagings']
|
||||||
from_staging = Stagings.browse(from_staging)
|
from_staging = Stagings.browse(from_staging)
|
||||||
to_staging = Stagings.browse(to_staging)
|
to_staging = Stagings.browse(to_staging)
|
||||||
|
if not (from_staging.exists() and to_staging.exists()):
|
||||||
|
raise NotFound()
|
||||||
if from_staging.target != to_staging.target:
|
if from_staging.target != to_staging.target:
|
||||||
raise ValueError(f"Stagings must have the same target branch, found {from_staging.target.name} and {to_staging.target.name}")
|
raise UnprocessableEntity(f"Stagings must have the same target branch, found {from_staging.target.name} and {to_staging.target.name}")
|
||||||
if from_staging.id >= to_staging.id:
|
if from_staging.id >= to_staging.id:
|
||||||
raise ValueError("first staging must be older than second staging")
|
raise UnprocessableEntity("first staging must be older than second staging")
|
||||||
|
|
||||||
stagings = Stagings.search([
|
stagings = Stagings.search([
|
||||||
('target', '=', to_staging.target.id),
|
('target', '=', to_staging.target.id),
|
||||||
@ -60,20 +77,7 @@ class MergebotController(Controller):
|
|||||||
('id', '<=' if include_to else '<', to_staging.id),
|
('id', '<=' if include_to else '<', to_staging.id),
|
||||||
], order="id asc")
|
], order="id asc")
|
||||||
|
|
||||||
return [
|
return request.make_json_response([staging_dict(staging) for staging in stagings])
|
||||||
{
|
|
||||||
'staging': staging.id,
|
|
||||||
'prs': [
|
|
||||||
batch.prs.mapped(lambda p: {
|
|
||||||
'name': p.display_name,
|
|
||||||
'repository': p.repository.name,
|
|
||||||
'number': p.number,
|
|
||||||
})
|
|
||||||
for batch in staging.batch_ids
|
|
||||||
]
|
|
||||||
}
|
|
||||||
for staging in stagings
|
|
||||||
]
|
|
||||||
|
|
||||||
@route('/runbot_merge/hooks', auth='none', type='http', csrf=False, methods=['POST'])
|
@route('/runbot_merge/hooks', auth='none', type='http', csrf=False, methods=['POST'])
|
||||||
def index(self) -> Response:
|
def index(self) -> Response:
|
||||||
|
Loading…
Reference in New Issue
Block a user