2021-12-08 19:50:23 +07:00
|
|
|
from odoo import models, fields, api
|
|
|
|
from unittest.mock import patch
|
|
|
|
from odoo.tools import mute_logger
|
|
|
|
|
|
|
|
import logging
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
2023-06-20 14:47:20 +07:00
|
|
|
|
2021-12-08 19:50:23 +07:00
|
|
|
class Runbot(models.AbstractModel):
|
|
|
|
_inherit = 'runbot.runbot'
|
|
|
|
|
|
|
|
@api.model
|
|
|
|
@patch('odoo.addons.runbot.models.repo.Remote._github')
|
|
|
|
@patch('odoo.addons.runbot.models.repo.Repo._git')
|
|
|
|
def _create_demo_data(self, mock_git, mock_github):
|
|
|
|
mock_github.return_value = False
|
2023-01-11 00:48:55 +07:00
|
|
|
project = self.env.ref('runbot.main_project')
|
2021-12-08 19:50:23 +07:00
|
|
|
bundles = self.env['runbot.bundle'].browse(
|
|
|
|
self.env['ir.model.data'].search([
|
|
|
|
('module', '=', 'runbot_populate'), ('model', '=', 'runbot.bundle')
|
|
|
|
]).mapped('res_id')
|
2023-01-11 00:48:55 +07:00
|
|
|
).filtered(lambda bundle: bundle.project_id == project)
|
|
|
|
bundles |= project.master_bundle_id
|
2021-12-08 19:50:23 +07:00
|
|
|
bundles = bundles.sorted('is_base', reverse=True)
|
|
|
|
|
2023-01-11 00:48:55 +07:00
|
|
|
existing_bundle = bundles.search([('project_id', '=', project.id)])
|
|
|
|
expected_bundle = bundles | project.dummy_bundle_id
|
|
|
|
|
|
|
|
assert expected_bundle == existing_bundle
|
2021-12-08 19:50:23 +07:00
|
|
|
|
[IMP] runbot: use custom layout and improve views
Runbot layout modifies the website/portal base layout to remove navbar,
footer, overides some custom styles. A lot of assets are loaded but not
used. The only real usefull elements are base assets (bootstrap, ...)
and the login button.
Migrating to the next version of odoo is usually painfull because some
xpath may break, extra element added, or some style change may break the
page, needing to add more and more xpath, css rules, ... for very little
benefits.
This cleanup creates a custom base layout for runbot independant from
base odoo templates.
Also add a breadcrumb, navigation arrow, and improve batch links
2021-12-10 22:09:57 +07:00
|
|
|
if bundles.branch_ids:
|
[IMP] runbot: refactor build error models
The initial idea to link an error to another one was a quick solution
to group them if they where related, but this became challenging
to copute metada regarding errors.
- The displayed error message was not always consistent with the real
root cause/the error that lead here.
- The aggregates (lets says, linked buils ids) could be the one of the
error, or from all error messages. Same for the versions, first seen, ..
This is confusing to knwo what is the leist we are managing and what is
the expecte result to display
Main motivation:
on a standard error page (will be changed to "assignment"), we want to
have the list of error message that is related to this one. We want to
know for each message (a real build error) what is the version,
first seen, ...
This will give more flexibility on the display,
The assigned person/team/test-tags, ... are moved to this model
The appearance data remains on the build error but are aggregate on the
assignation.
2024-09-25 15:29:27 +07:00
|
|
|
_logger.warning('Skipping populate, bundles already have branches')
|
2021-12-08 19:50:23 +07:00
|
|
|
# only populate data if no branch are found
|
|
|
|
return
|
|
|
|
|
|
|
|
if not bundles.branch_ids:
|
|
|
|
pr = True
|
|
|
|
count = 1000
|
|
|
|
for bundle in bundles:
|
|
|
|
_logger.info(bundle.name)
|
|
|
|
for repo in bundle.project_id.repo_ids:
|
|
|
|
main_remote = repo.main_remote_id
|
|
|
|
dev_remote = next((remote for remote in repo.remote_ids if remote != main_remote), main_remote)
|
|
|
|
if bundle.is_base:
|
|
|
|
dev_remote = main_remote
|
|
|
|
self.env['runbot.branch'].create({'remote_id': dev_remote.id, 'name': bundle.name, 'is_pr': False})
|
2022-02-01 14:48:16 +07:00
|
|
|
if not bundle.is_base:
|
2021-12-08 19:50:23 +07:00
|
|
|
mock_github.return_value = {
|
|
|
|
'base': {
|
|
|
|
'ref': bundle.base_id.name
|
|
|
|
},
|
|
|
|
'head': {
|
|
|
|
'label': '%s:%s' % (dev_remote.owner, bundle.name),
|
|
|
|
'repo': {'full_name': '%s/%s' % (dev_remote.owner, dev_remote.repo_name)}
|
2022-11-21 15:11:12 +07:00
|
|
|
},
|
|
|
|
'title': '[IMP] Title',
|
|
|
|
'body': 'Body',
|
2022-11-21 22:45:31 +07:00
|
|
|
'user': {
|
2022-11-21 15:11:12 +07:00
|
|
|
'login': 'Pr author'
|
|
|
|
},
|
2021-12-08 19:50:23 +07:00
|
|
|
}
|
|
|
|
branch = self.env['runbot.branch'].create({
|
|
|
|
'remote_id': main_remote.id,
|
|
|
|
'name': str(count),
|
|
|
|
'is_pr': True,
|
|
|
|
})
|
|
|
|
count += 1
|
2023-06-20 14:47:20 +07:00
|
|
|
branch.flush_recordset()
|
2021-12-08 19:50:23 +07:00
|
|
|
|
2022-02-01 14:48:16 +07:00
|
|
|
if 'partial' in bundle.name:
|
|
|
|
break
|
|
|
|
|
2021-12-08 19:50:23 +07:00
|
|
|
if not bundle.is_base:
|
|
|
|
pr = not pr
|
|
|
|
|
|
|
|
security_config = self.env.ref('runbot_populate.runbot_build_config_security')
|
|
|
|
linting_config = self.env.ref('runbot_populate.runbot_build_config_linting')
|
|
|
|
|
|
|
|
for bundle in bundles:
|
|
|
|
nb_batch = 4 if bundle.sticky else 2
|
|
|
|
for i in range(nb_batch):
|
|
|
|
values = {
|
|
|
|
'last_update': fields.Datetime.now(),
|
|
|
|
'bundle_id': bundle.id,
|
|
|
|
'state': 'preparing',
|
|
|
|
}
|
|
|
|
batch = self.env['runbot.batch'].create(values)
|
|
|
|
bundle.last_batch = batch
|
|
|
|
for repo in bundle.project_id.repo_ids:
|
|
|
|
commit = self.env['runbot.commit']._get('%s00b%s0000ba%s000' % (repo.id, bundle.id, batch.id), repo.id, {
|
|
|
|
'author': 'Author',
|
|
|
|
'author_email': 'author@example.com',
|
|
|
|
'committer': 'Committer',
|
|
|
|
'committer_email': 'committer@example.com',
|
|
|
|
'subject': '[IMP] core: come imp',
|
|
|
|
'date': fields.Datetime.now(),
|
|
|
|
})
|
|
|
|
branches = bundle.branch_ids.filtered(lambda b: b.remote_id.repo_id == repo)
|
|
|
|
for branch in branches:
|
|
|
|
branch.head = commit
|
|
|
|
batch._new_commit(branch)
|
|
|
|
|
|
|
|
def git(command):
|
|
|
|
if command[0] == 'merge-base':
|
|
|
|
_, sha1, sha2 = command
|
2022-02-01 14:48:16 +07:00
|
|
|
return sha1 if sha1 == sha2 else sha2 #if bundle.is_base else '%s_%s' % (sha1, sha2)
|
2021-12-08 19:50:23 +07:00
|
|
|
elif command[0] == 'rev-list':
|
|
|
|
_, _, _, shas = command
|
|
|
|
sha1, sha2 = shas.split('...')
|
|
|
|
return '0\t0' if command[1] == command[2] else '3\t5'
|
|
|
|
elif command[0] == 'diff':
|
|
|
|
_, _, sha1, sha2 = command
|
|
|
|
return '' if sha1 == sha2 else '0 5 _\n1 8 _'
|
|
|
|
else:
|
|
|
|
_logger.info(command)
|
|
|
|
|
|
|
|
mock_git.side_effect = git
|
[IMP] runbot: refactor build error models
The initial idea to link an error to another one was a quick solution
to group them if they where related, but this became challenging
to copute metada regarding errors.
- The displayed error message was not always consistent with the real
root cause/the error that lead here.
- The aggregates (lets says, linked buils ids) could be the one of the
error, or from all error messages. Same for the versions, first seen, ..
This is confusing to knwo what is the leist we are managing and what is
the expecte result to display
Main motivation:
on a standard error page (will be changed to "assignment"), we want to
have the list of error message that is related to this one. We want to
know for each message (a real build error) what is the version,
first seen, ...
This will give more flexibility on the display,
The assigned person/team/test-tags, ... are moved to this model
The appearance data remains on the build error but are aggregate on the
assignation.
2024-09-25 15:29:27 +07:00
|
|
|
batch._prepare()
|
|
|
|
batch._process()
|
2021-12-08 19:50:23 +07:00
|
|
|
if i != nb_batch - 1:
|
|
|
|
for slot in batch.slot_ids:
|
|
|
|
if slot.build_id:
|
|
|
|
build = slot.build_id
|
|
|
|
with mute_logger('odoo.addons.runbot.models.build'):
|
[IMP] runbot: refactor build error models
The initial idea to link an error to another one was a quick solution
to group them if they where related, but this became challenging
to copute metada regarding errors.
- The displayed error message was not always consistent with the real
root cause/the error that lead here.
- The aggregates (lets says, linked buils ids) could be the one of the
error, or from all error messages. Same for the versions, first seen, ..
This is confusing to knwo what is the leist we are managing and what is
the expecte result to display
Main motivation:
on a standard error page (will be changed to "assignment"), we want to
have the list of error message that is related to this one. We want to
know for each message (a real build error) what is the version,
first seen, ...
This will give more flexibility on the display,
The assigned person/team/test-tags, ... are moved to this model
The appearance data remains on the build error but are aggregate on the
assignation.
2024-09-25 15:29:27 +07:00
|
|
|
build._log('******', 'Starting step X', level='SEPARATOR')
|
|
|
|
build._log('******', 'Some log')
|
2021-12-08 19:50:23 +07:00
|
|
|
for config in (linting_config, security_config):
|
|
|
|
child = build._add_child({'config_id': config.id})
|
|
|
|
build._log('create_build', 'created with config %s' % config.name, log_type='subbuild', path=str(child.id))
|
|
|
|
child.local_state = 'done'
|
|
|
|
child.local_result = 'ok'
|
|
|
|
child.description = "Description for security"
|
[IMP] runbot: refactor build error models
The initial idea to link an error to another one was a quick solution
to group them if they where related, but this became challenging
to copute metada regarding errors.
- The displayed error message was not always consistent with the real
root cause/the error that lead here.
- The aggregates (lets says, linked buils ids) could be the one of the
error, or from all error messages. Same for the versions, first seen, ..
This is confusing to knwo what is the leist we are managing and what is
the expecte result to display
Main motivation:
on a standard error page (will be changed to "assignment"), we want to
have the list of error message that is related to this one. We want to
know for each message (a real build error) what is the version,
first seen, ...
This will give more flexibility on the display,
The assigned person/team/test-tags, ... are moved to this model
The appearance data remains on the build error but are aggregate on the
assignation.
2024-09-25 15:29:27 +07:00
|
|
|
build._log('******', 'Step x finished')
|
|
|
|
build._log('******', 'Starting step Y', level='SEPARATOR')
|
|
|
|
if not bundle.sticky:
|
|
|
|
build._log('******', 'Some log', level='ERROR', log_type='server')
|
|
|
|
build._log('******', 'Some log\n with multiple lines', level='ERROR', log_type='server')
|
|
|
|
build._log('******', '**Some** *markdown* [log](%s)', 'http://example.com', log_type='markdown')
|
|
|
|
build._log('******', 'Step x finished', level='SEPARATOR')
|
2021-12-08 19:50:23 +07:00
|
|
|
build.local_state = 'done'
|
|
|
|
build.local_result = 'ok' if bundle.sticky else 'ko'
|
|
|
|
|
|
|
|
batch._process()
|