mirror of
https://github.com/odoo/runbot.git
synced 2025-03-27 13:25:47 +07:00
[IMP] runbot: reinforce version
When updating a bundle and changing the is_base field to True, it creates a new version based on the bundle name. This can potentially breaks builds and moreover, it can breaks the whole runbot when a duplicate version name is created. With this commit: - a constraint on the version name uniqueness is added - the is_base field is now readonky - a version cannot be created by the compute version if the version name does not match the above mentioned regular expression
This commit is contained in:
parent
f26065c4dc
commit
e07fcd6dff
@ -1,7 +1,4 @@
|
|||||||
import time
|
import re
|
||||||
import logging
|
|
||||||
import datetime
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from odoo import models, fields, api, tools
|
from odoo import models, fields, api, tools
|
||||||
@ -30,7 +27,7 @@ class Bundle(models.Model):
|
|||||||
last_done_batch = fields.Many2many('runbot.batch', 'Last batchs', compute='_compute_last_done_batch')
|
last_done_batch = fields.Many2many('runbot.batch', 'Last batchs', compute='_compute_last_done_batch')
|
||||||
|
|
||||||
sticky = fields.Boolean('Sticky', compute='_compute_sticky', store=True, index=True)
|
sticky = fields.Boolean('Sticky', compute='_compute_sticky', store=True, index=True)
|
||||||
is_base = fields.Boolean('Is base', index=True)
|
is_base = fields.Boolean('Is base', index=True, readonly=True)
|
||||||
defined_base_id = fields.Many2one('runbot.bundle', 'Forced base bundle', domain="[('project_id', '=', project_id), ('is_base', '=', True)]")
|
defined_base_id = fields.Many2one('runbot.bundle', 'Forced base bundle', domain="[('project_id', '=', project_id), ('is_base', '=', True)]")
|
||||||
base_id = fields.Many2one('runbot.bundle', 'Base bundle', compute='_compute_base_id', store=True)
|
base_id = fields.Many2one('runbot.bundle', 'Base bundle', compute='_compute_base_id', store=True)
|
||||||
to_upgrade = fields.Boolean('To upgrade', compute='_compute_to_upgrade', store=True, index=False)
|
to_upgrade = fields.Boolean('To upgrade', compute='_compute_to_upgrade', store=True, index=False)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
from odoo import models, fields, api, tools
|
from odoo import models, fields, api, tools
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -25,6 +25,10 @@ class Version(models.Model):
|
|||||||
|
|
||||||
dockerfile_id = fields.Many2one('runbot.dockerfile', default=lambda self: self.env.ref('runbot.docker_default', raise_if_not_found=False))
|
dockerfile_id = fields.Many2one('runbot.dockerfile', default=lambda self: self.env.ref('runbot.docker_default', raise_if_not_found=False))
|
||||||
|
|
||||||
|
_sql_constraints = [
|
||||||
|
('unique_name', 'unique (name)', 'avoid duplicate versions'),
|
||||||
|
]
|
||||||
|
|
||||||
@api.depends('name')
|
@api.depends('name')
|
||||||
def _compute_version_number(self):
|
def _compute_version_number(self):
|
||||||
for version in self:
|
for version in self:
|
||||||
@ -42,6 +46,13 @@ class Version(models.Model):
|
|||||||
model.env.registry.clear_cache()
|
model.env.registry.clear_cache()
|
||||||
return super().create(vals_list)
|
return super().create(vals_list)
|
||||||
|
|
||||||
|
def write(self, values):
|
||||||
|
if 'name' in values:
|
||||||
|
icp = self.env['ir.config_parameter'].sudo()
|
||||||
|
regex = icp.get_param('runbot.runbot_is_base_regex', False)
|
||||||
|
if regex and not re.match(regex, values['name']):
|
||||||
|
raise UserError(f"Version name {values['name']} does not match a valid base name.")
|
||||||
|
|
||||||
def _get(self, name):
|
def _get(self, name):
|
||||||
return self.browse(self._get_id(name))
|
return self.browse(self._get_id(name))
|
||||||
|
|
||||||
@ -49,6 +60,10 @@ class Version(models.Model):
|
|||||||
def _get_id(self, name):
|
def _get_id(self, name):
|
||||||
version = self.search([('name', '=', name)])
|
version = self.search([('name', '=', name)])
|
||||||
if not version:
|
if not version:
|
||||||
|
icp = self.env['ir.config_parameter'].sudo()
|
||||||
|
regex = icp.get_param('runbot.runbot_is_base_regex', False)
|
||||||
|
if regex and not re.match(regex, name):
|
||||||
|
return False
|
||||||
version = self.create({
|
version = self.create({
|
||||||
'name': name,
|
'name': name,
|
||||||
})
|
})
|
||||||
|
@ -15,3 +15,4 @@ from . import test_commit
|
|||||||
from . import test_upgrade
|
from . import test_upgrade
|
||||||
from . import test_dockerfile
|
from . import test_dockerfile
|
||||||
from . import test_host
|
from . import test_host
|
||||||
|
from . import test_bundle
|
||||||
|
28
runbot/tests/test_bundle.py
Normal file
28
runbot/tests/test_bundle.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
from .common import RunbotCase
|
||||||
|
|
||||||
|
class TestBundleCreation(RunbotCase):
|
||||||
|
def test_version_at_bundle_creation(self):
|
||||||
|
saas_name = 'saas-27.2'
|
||||||
|
saas_bundle = self.Bundle.create({
|
||||||
|
'name': saas_name,
|
||||||
|
'project_id': self.project.id
|
||||||
|
})
|
||||||
|
saas_bundle.is_base = True
|
||||||
|
self.assertEqual(saas_bundle.version_id.name, saas_name, 'The bundle version_id should create base version')
|
||||||
|
|
||||||
|
dev_name = 'saas-27.2-brol-bro'
|
||||||
|
dev_bundle = self.Bundle.create({
|
||||||
|
'name': dev_name,
|
||||||
|
'project_id': self.project.id
|
||||||
|
})
|
||||||
|
self.assertEqual(dev_bundle.version_id.name, saas_name)
|
||||||
|
|
||||||
|
self.assertFalse(self.Version.search([('name', '=', dev_name)]), 'A dev bundle should not summon a new version')
|
||||||
|
dev_name = 'saas-27.2-brol-zzz'
|
||||||
|
dev_bundle = self.Bundle.create({
|
||||||
|
'name': dev_name,
|
||||||
|
'project_id': self.project.id,
|
||||||
|
'is_base': True
|
||||||
|
})
|
||||||
|
self.assertFalse(self.Version.search([('name', '=', dev_name)]), 'A dev bundle should not summon a new version, even if is_base is True')
|
||||||
|
self.assertEqual(dev_bundle.version_id.id, False)
|
@ -16,7 +16,7 @@ class TestVersion(RunbotCase):
|
|||||||
|
|
||||||
self.assertGreater(saas_version.number, major_version.number)
|
self.assertGreater(saas_version.number, major_version.number)
|
||||||
|
|
||||||
master_version = self.Version.create({'name': 'master'})
|
master_version = self.Version.search([('name', '=', 'master')])
|
||||||
self.assertEqual(master_version.number, '~')
|
self.assertEqual(master_version.number, '~')
|
||||||
self.assertGreater(master_version.number, saas_version.number)
|
self.assertGreater(master_version.number, saas_version.number)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user