mirror of
https://github.com/odoo/runbot.git
synced 2025-03-15 23:45:44 +07:00
WIP : runbot error min max version
This commit is contained in:
parent
1ed9278d6e
commit
2b1ddce781
@ -110,6 +110,9 @@ class BuildError(models.Model):
|
|||||||
analogous_ids = fields.One2many('runbot.build.error', compute='_compute_analogous_ids', string="Analogous Errors", help="Analogous Errors based on unique qualifiers")
|
analogous_ids = fields.One2many('runbot.build.error', compute='_compute_analogous_ids', string="Analogous Errors", help="Analogous Errors based on unique qualifiers")
|
||||||
analogous_content_ids= fields.One2many('runbot.build.error.content', compute='_compute_analogous_content_ids', string="Analogous Error Contents", help="Analogous Error contents based on unique qualifiers")
|
analogous_content_ids= fields.One2many('runbot.build.error.content', compute='_compute_analogous_content_ids', string="Analogous Error Contents", help="Analogous Error contents based on unique qualifiers")
|
||||||
|
|
||||||
|
min_version_id = fields.Many2one('runbot.version', string='Min Version', compute='_compute_min_max_version', search='_search_min_version')
|
||||||
|
max_version_id = fields.Many2one('runbot.version', string='Max Version', compute='_compute_min_max_version', search='_search_max_version')
|
||||||
|
|
||||||
# Build error related data
|
# Build error related data
|
||||||
build_error_link_ids = fields.Many2many('runbot.build.error.link', compute=_compute_related_error_content_ids('build_error_link_ids'), search=_search_related_error_content_ids('build_error_link_ids'))
|
build_error_link_ids = fields.Many2many('runbot.build.error.link', compute=_compute_related_error_content_ids('build_error_link_ids'), search=_search_related_error_content_ids('build_error_link_ids'))
|
||||||
unique_build_error_link_ids = fields.Many2many('runbot.build.error.link', compute='_compute_unique_build_error_link_ids')
|
unique_build_error_link_ids = fields.Many2many('runbot.build.error.link', compute='_compute_unique_build_error_link_ids')
|
||||||
@ -234,6 +237,75 @@ class BuildError(models.Model):
|
|||||||
else:
|
else:
|
||||||
record.analogous_content_ids = False
|
record.analogous_content_ids = False
|
||||||
|
|
||||||
|
@api.depends('error_content_ids')
|
||||||
|
def _compute_min_max_version(self):
|
||||||
|
query = SQL(
|
||||||
|
r"""
|
||||||
|
SELECT runbot_build_error.id, MIN(runbot_version.number), MAX(runbot_version.number)
|
||||||
|
FROM runbot_build_error_link
|
||||||
|
JOIN runbot_build_error_content
|
||||||
|
ON runbot_build_error_link.error_content_id = runbot_build_error_content.id
|
||||||
|
JOIN runbot_build_error
|
||||||
|
ON runbot_build_error.id = runbot_build_error_content.error_id
|
||||||
|
JOIN runbot_build
|
||||||
|
ON runbot_build_error_link.build_id = runbot_build.id
|
||||||
|
JOIN runbot_version
|
||||||
|
ON runbot_build.version_id = runbot_version.id
|
||||||
|
WHERE runbot_build.version_id is not null
|
||||||
|
AND runbot_build_error.id IN %s
|
||||||
|
GROUP BY runbot_build_error.id;
|
||||||
|
""",
|
||||||
|
tuple(self.ids)
|
||||||
|
)
|
||||||
|
self.env.cr.execute(query)
|
||||||
|
min_max_by_error_id = {error_id: (vmin, vmax) for error_id,vmin,vmax in self.env.cr.fetchall()}
|
||||||
|
all_versions_by_number = {rec.number:rec.id for rec in self.env['runbot.version'].search([])}
|
||||||
|
for record in self:
|
||||||
|
min_max = min_max_by_error_id.get(record.id, False)
|
||||||
|
record.min_version_id = all_versions_by_number[min_max[0]] if min_max else False
|
||||||
|
record.max_version_id = all_versions_by_number[min_max[1]] if min_max else False
|
||||||
|
|
||||||
|
def _search_min_max(self, version, aggregator):
|
||||||
|
comp = '>=' if aggregator == 'MIN' else '<='
|
||||||
|
query = SQL(
|
||||||
|
rf"""
|
||||||
|
SELECT runbot_build_error.id
|
||||||
|
FROM runbot_build_error_link
|
||||||
|
JOIN runbot_build_error_content
|
||||||
|
ON runbot_build_error_link.error_content_id = runbot_build_error_content.id
|
||||||
|
JOIN runbot_build_error
|
||||||
|
ON runbot_build_error.id = runbot_build_error_content.error_id
|
||||||
|
JOIN runbot_build
|
||||||
|
ON runbot_build_error_link.build_id = runbot_build.id
|
||||||
|
JOIN runbot_version
|
||||||
|
ON runbot_build.version_id = runbot_version.id
|
||||||
|
WHERE runbot_build.version_id is not null
|
||||||
|
GROUP BY runbot_build_error.id
|
||||||
|
HAVING {aggregator}(runbot_version.number) {comp} %s
|
||||||
|
;
|
||||||
|
""",
|
||||||
|
version.number
|
||||||
|
)
|
||||||
|
self.env.cr.execute(query)
|
||||||
|
return [rec[0] for rec in self.env.cr.fetchall()]
|
||||||
|
|
||||||
|
def _search_min_version(self, operator, value):
|
||||||
|
if operator not in ('=', 'ilike'):
|
||||||
|
raise NotImplementedError()
|
||||||
|
if isinstance(value, str):
|
||||||
|
min_version = self.env['runbot.version'].search([('name', operator, value)], limit=1)
|
||||||
|
else:
|
||||||
|
min_version = self.env['runbot.version'].browse(value)
|
||||||
|
return [('id', 'in', self._search_min_max(min_version, 'MIN'))]
|
||||||
|
|
||||||
|
def _search_max_version(self, operator, value):
|
||||||
|
if operator not in ('=', 'ilike'):
|
||||||
|
raise NotImplementedError()
|
||||||
|
if isinstance(value, str):
|
||||||
|
min_version = self.env['runbot.version'].search([('name', operator, value)], limit=1)
|
||||||
|
else:
|
||||||
|
min_version = self.env['runbot.version'].browse(value)
|
||||||
|
return [('id', 'in', self._search_min_max(min_version, 'MAX'))]
|
||||||
|
|
||||||
@api.constrains('test_tags')
|
@api.constrains('test_tags')
|
||||||
def _check_test_tags(self):
|
def _check_test_tags(self):
|
||||||
@ -485,6 +557,8 @@ class BuildErrorContent(models.Model):
|
|||||||
build_ids = fields.Many2many('runbot.build', compute='_compute_build_ids')
|
build_ids = fields.Many2many('runbot.build', compute='_compute_build_ids')
|
||||||
bundle_ids = fields.One2many('runbot.bundle', compute='_compute_bundle_ids')
|
bundle_ids = fields.One2many('runbot.bundle', compute='_compute_bundle_ids')
|
||||||
version_ids = fields.One2many('runbot.version', compute='_compute_version_ids', string='Versions', search='_search_version')
|
version_ids = fields.One2many('runbot.version', compute='_compute_version_ids', string='Versions', search='_search_version')
|
||||||
|
min_version_id = fields.Many2one('runbot.version', compute='_compute_version_ids', string='Min Version', search='_search_min_version')
|
||||||
|
max_version_id = fields.Many2one('runbot.version', compute='_compute_version_ids', string='Max Version')
|
||||||
trigger_ids = fields.Many2many('runbot.trigger', compute='_compute_trigger_ids', string='Triggers', search='_search_trigger_ids')
|
trigger_ids = fields.Many2many('runbot.trigger', compute='_compute_trigger_ids', string='Triggers', search='_search_trigger_ids')
|
||||||
tag_ids = fields.Many2many('runbot.build.error.tag', string='Tags')
|
tag_ids = fields.Many2many('runbot.build.error.tag', string='Tags')
|
||||||
qualifiers = JsonDictField('Qualifiers', index=True)
|
qualifiers = JsonDictField('Qualifiers', index=True)
|
||||||
@ -561,7 +635,10 @@ class BuildErrorContent(models.Model):
|
|||||||
@api.depends('build_ids')
|
@api.depends('build_ids')
|
||||||
def _compute_version_ids(self):
|
def _compute_version_ids(self):
|
||||||
for build_error in self:
|
for build_error in self:
|
||||||
build_error.version_ids = build_error.build_ids.version_id
|
version_ids = build_error.build_ids.mapped('version_id').sorted(lambda rec: rec.number)
|
||||||
|
build_error.version_ids = version_ids
|
||||||
|
build_error.min_version_id = version_ids[0] if version_ids else False
|
||||||
|
build_error.max_version_id = version_ids[-1] if version_ids else False
|
||||||
|
|
||||||
@api.depends('build_ids')
|
@api.depends('build_ids')
|
||||||
def _compute_trigger_ids(self):
|
def _compute_trigger_ids(self):
|
||||||
@ -602,11 +679,9 @@ class BuildErrorContent(models.Model):
|
|||||||
return hashlib.sha256(s.encode()).hexdigest()
|
return hashlib.sha256(s.encode()).hexdigest()
|
||||||
|
|
||||||
def _search_version(self, operator, value):
|
def _search_version(self, operator, value):
|
||||||
exclude_domain = []
|
_logger.info('operator: %s', operator)
|
||||||
if operator == '=':
|
_logger.info('value: %s', value)
|
||||||
exclude_ids = self.env['runbot.build.error'].search([('version_ids', '!=', value)])
|
return [('build_error_link_ids.version_id', operator, value)]
|
||||||
exclude_domain = [('id', 'not in', exclude_ids.ids)]
|
|
||||||
return [('build_error_link_ids.version_id', operator, value)] + exclude_domain
|
|
||||||
|
|
||||||
def _search_trigger_ids(self, operator, value):
|
def _search_trigger_ids(self, operator, value):
|
||||||
return [('build_error_link_ids.trigger_id', operator, value)]
|
return [('build_error_link_ids.trigger_id', operator, value)]
|
||||||
|
@ -345,6 +345,8 @@
|
|||||||
<field name="first_seen_date" string="First Seen" optional="hide" readonly="1"/>
|
<field name="first_seen_date" string="First Seen" optional="hide" readonly="1"/>
|
||||||
<field name="last_seen_date" string="Last Seen" readonly="1" options="{'link_field': 'last_seen_build_id'}"/>
|
<field name="last_seen_date" string="Last Seen" readonly="1" options="{'link_field': 'last_seen_build_id'}"/>
|
||||||
<field name="last_seen_build_id" column_invisible="True"/>
|
<field name="last_seen_build_id" column_invisible="True"/>
|
||||||
|
<field name="min_version_id" optional="hide"/>
|
||||||
|
<field name="max_version_id" optional="hide"/>
|
||||||
<field name="error_count" readonly="1"/>
|
<field name="error_count" readonly="1"/>
|
||||||
<field name="build_count" readonly="1"/>
|
<field name="build_count" readonly="1"/>
|
||||||
<field name="team_id"/>
|
<field name="team_id"/>
|
||||||
@ -401,6 +403,8 @@
|
|||||||
<field name="content"/>
|
<field name="content"/>
|
||||||
<field name="description"/>
|
<field name="description"/>
|
||||||
<field name="version_ids"/>
|
<field name="version_ids"/>
|
||||||
|
<field name="min_version_id"/>
|
||||||
|
<field name="max_version_id"/>
|
||||||
<field name="responsible"/>
|
<field name="responsible"/>
|
||||||
<field name="team_id"/>
|
<field name="team_id"/>
|
||||||
<filter string="Assigned to me" name="my_errors" domain="[('responsible', '=', uid)]"/>
|
<filter string="Assigned to me" name="my_errors" domain="[('responsible', '=', uid)]"/>
|
||||||
|
Loading…
Reference in New Issue
Block a user