mirror of
https://github.com/odoo/runbot.git
synced 2025-03-15 23:45:44 +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
|
||||
|
||||
import sentry_sdk
|
||||
from werkzeug.exceptions import NotFound, UnprocessableEntity
|
||||
|
||||
from odoo.api import Environment
|
||||
from odoo.http import Controller, request, route, Response
|
||||
@ -18,40 +19,56 @@ from .. import utils, github
|
||||
|
||||
_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):
|
||||
@route('/runbot_merge/stagings', auth='none', type='json')
|
||||
def stagings_for_commits(self, commits=None, heads=None):
|
||||
Stagings = request.env(user=1)['runbot_merge.stagings'].sudo()
|
||||
if commits:
|
||||
stagings = Stagings.for_commits(*commits)
|
||||
elif heads:
|
||||
stagings = Stagings.for_heads(*heads)
|
||||
@route('/runbot_merge/stagings', auth='none', type='http', methods=['GET'])
|
||||
def stagings_for_commits(self, **kw):
|
||||
commits = request.httprequest.args.getlist('merged')
|
||||
heads = request.httprequest.args.getlist('staged')
|
||||
if bool(commits) ^ bool(heads):
|
||||
Stagings = request.env(user=1)['runbot_merge.stagings'].sudo()
|
||||
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:
|
||||
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='json')
|
||||
@route('/runbot_merge/stagings/<int:staging>', auth='none', type='http', methods=['GET'])
|
||||
def prs_for_staging(self, staging):
|
||||
staging = request.env(user=1)['runbot_merge.stagings'].browse(staging)
|
||||
return [
|
||||
batch.prs.mapped(lambda p: {
|
||||
'name': p.display_name,
|
||||
'repository': p.repository.name,
|
||||
'number': p.number,
|
||||
})
|
||||
for batch in staging.sudo().batch_ids
|
||||
]
|
||||
staging = request.env(user=1)['runbot_merge.stagings'].browse(staging).sudo()
|
||||
if not staging.exists:
|
||||
raise NotFound()
|
||||
|
||||
@route('/runbot_merge/stagings/<int:from_staging>/<int:to_staging>', auth='none', type='json')
|
||||
def prs_for_stagings(self, from_staging, to_staging, include_from=True, include_to=True):
|
||||
return request.make_json_response(staging_dict(staging))
|
||||
|
||||
@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']
|
||||
from_staging = Stagings.browse(from_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:
|
||||
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:
|
||||
raise ValueError("first staging must be older than second staging")
|
||||
raise UnprocessableEntity("first staging must be older than second staging")
|
||||
|
||||
stagings = Stagings.search([
|
||||
('target', '=', to_staging.target.id),
|
||||
@ -60,20 +77,7 @@ class MergebotController(Controller):
|
||||
('id', '<=' if include_to else '<', to_staging.id),
|
||||
], order="id asc")
|
||||
|
||||
return [
|
||||
{
|
||||
'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
|
||||
]
|
||||
return request.make_json_response([staging_dict(staging) for staging in stagings])
|
||||
|
||||
@route('/runbot_merge/hooks', auth='none', type='http', csrf=False, methods=['POST'])
|
||||
def index(self) -> Response:
|
||||
|
Loading…
Reference in New Issue
Block a user