mirror of
https://github.com/odoo/runbot.git
synced 2025-03-15 15:35:46 +07:00
[IMP] *: trigger-ify staging cron
The staging cron turns out to be pretty reasonable to trigger, as we already have a handler on the transition of a batch to `not blocked`, which is exactly when we want to create a staging (that and the completion of the previous staging). The batch transition is in a compute which is not awesome, but on the flip side we also cancel active stagings in that exact scenario (if it applies), so that matches. The only real finesse is that one of the tests wants to observe the instant between the end of a staging (and creation of splits) and the start of the next one, which because the staging cron is triggered by the failure of the previous staging is now "atomic", requiring disabling the staging cron, which means the trigger is skipped entirely. So this requires triggering the staging cron by hand.
This commit is contained in:
parent
f367a64481
commit
3ee3e9cc81
@ -7,7 +7,6 @@ import requests
|
||||
@pytest.fixture
|
||||
def default_crons():
|
||||
return [
|
||||
'runbot_merge.staging_cron',
|
||||
'runbot_merge.check_linked_prs_status',
|
||||
]
|
||||
|
||||
|
@ -15,8 +15,8 @@
|
||||
<field name="model_id" ref="model_runbot_merge_project"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">model._create_stagings(True)</field>
|
||||
<field name="interval_number">1</field>
|
||||
<field name="interval_type">minutes</field>
|
||||
<field name="interval_number">6</field>
|
||||
<field name="interval_type">hours</field>
|
||||
<field name="numbercall">-1</field>
|
||||
<field name="doall" eval="False"/>
|
||||
<field name="priority">40</field>
|
||||
|
@ -223,13 +223,15 @@ class Batch(models.Model):
|
||||
failed and f"{failed} have failed CI",
|
||||
]))
|
||||
else:
|
||||
if batch.blocked and batch.cancel_staging:
|
||||
if splits := batch.target.split_ids:
|
||||
splits.unlink()
|
||||
batch.target.active_staging_id.cancel(
|
||||
'unstaged by %s becoming ready',
|
||||
', '.join(batch.prs.mapped('display_name')),
|
||||
)
|
||||
if batch.blocked:
|
||||
self.env.ref("runbot_merge.staging_cron")._trigger()
|
||||
if batch.cancel_staging:
|
||||
if splits := batch.target.split_ids:
|
||||
splits.unlink()
|
||||
batch.target.active_staging_id.cancel(
|
||||
'unstaged by %s becoming ready',
|
||||
', '.join(batch.prs.mapped('display_name')),
|
||||
)
|
||||
batch.blocked = False
|
||||
|
||||
|
||||
|
@ -2067,6 +2067,9 @@ class Stagings(models.Model):
|
||||
self.env.ref("runbot_merge.merge_cron")\
|
||||
._trigger(fields.Datetime.to_datetime(timeout))
|
||||
|
||||
if vals.get('active') is False:
|
||||
self.env.ref("runbot_merge.staging_cron")._trigger()
|
||||
|
||||
return super().write(vals)
|
||||
|
||||
# only depend on staged_at as it should not get modified, but we might
|
||||
|
@ -7,8 +7,6 @@ def module():
|
||||
@pytest.fixture
|
||||
def default_crons():
|
||||
return [
|
||||
# env['runbot_merge.project']._create_stagings()
|
||||
'runbot_merge.staging_cron',
|
||||
# env['runbot_merge.pull_requests']._check_linked_prs_statuses()
|
||||
'runbot_merge.check_linked_prs_status',
|
||||
]
|
||||
|
@ -598,7 +598,7 @@ def test_staging_ci_timeout(env, repo, config, page, update_op: Callable[[int],
|
||||
timeout = env['runbot_merge.project'].search([]).ci_timeout
|
||||
|
||||
pr_id.staging_id.write(update_op(timeout))
|
||||
env.run_crons('runbot_merge.staging_cron')
|
||||
env.run_crons(None)
|
||||
assert pr_id.state == 'error', "timeout should fail the PR"
|
||||
|
||||
dangerbox = pr_page(page, pr).cssselect('.alert-danger span')
|
||||
@ -1248,7 +1248,7 @@ class TestRetry:
|
||||
with repo:
|
||||
pr.post_comment('hansen retry', config['role_' + retrier]['token'])
|
||||
assert pr_id.state == 'ready'
|
||||
env.run_crons('runbot_merge.staging_cron')
|
||||
env.run_crons(None)
|
||||
|
||||
staging_head2 = repo.commit('heads/staging.master')
|
||||
assert staging_head2 != staging_head
|
||||
@ -1281,7 +1281,7 @@ class TestRetry:
|
||||
|
||||
with repo:
|
||||
pr.post_comment('hansen retry', config['role_reviewer']['token'])
|
||||
env.run_crons('runbot_merge.staging_cron')
|
||||
env.run_crons(None)
|
||||
|
||||
with repo:
|
||||
repo.post_status('staging.master', 'success', 'legal/cla')
|
||||
@ -1771,7 +1771,7 @@ commits, I need to know how to merge it:
|
||||
|
||||
c0 = repo.make_commit(m, 'C0', None, tree={'a': 'b'})
|
||||
prx = repo.make_pr(title="gibberish", body="blahblah", target='master', head=c0)
|
||||
env.run_crons('runbot_merge.staging_cron')
|
||||
env.run_crons(None)
|
||||
|
||||
with repo:
|
||||
repo.post_status(prx.head, 'success', 'legal/cla')
|
||||
@ -1813,7 +1813,7 @@ commits, I need to know how to merge it:
|
||||
|
||||
c0 = repo.make_commit(m, 'C0', None, tree={'a': 'b'})
|
||||
prx = repo.make_pr(title="gibberish", body=None, target='master', head=c0)
|
||||
env.run_crons('runbot_merge.staging_cron')
|
||||
env.run_crons(None)
|
||||
|
||||
with repo:
|
||||
repo.post_status(prx.head, 'success', 'legal/cla')
|
||||
@ -3089,7 +3089,7 @@ class TestBatching(object):
|
||||
with repo:
|
||||
repo.post_status('staging.master', 'success', 'ci/runbot')
|
||||
repo.post_status('staging.master', 'success', 'legal/cla')
|
||||
env.run_crons('runbot_merge.staging_cron')
|
||||
env.run_crons(None)
|
||||
assert pr2.state == 'merged'
|
||||
|
||||
class TestReviewing:
|
||||
|
@ -493,7 +493,7 @@ def test_ff_fail(env, project, repo_a, repo_b, config):
|
||||
with repo_a, repo_b:
|
||||
repo_a.post_status('heads/staging.master', 'success')
|
||||
repo_b.post_status('heads/staging.master', 'success')
|
||||
env.run_crons('runbot_merge.staging_cron')
|
||||
env.run_crons(None)
|
||||
assert repo_b.commit('heads/master').id == cn,\
|
||||
"B should still be at the conflicting commit"
|
||||
assert repo_a.commit('heads/master').id == root_a,\
|
||||
|
@ -111,15 +111,17 @@ def test_staging_priority(env, project, repo, config, mode, cutoff, second):
|
||||
# specifically delay creation of new staging to observe the failed
|
||||
# staging's state and the splits
|
||||
model, cron_id = env['ir.model.data'].check_object_reference('runbot_merge', 'staging_cron')
|
||||
env[model].browse([cron_id]).write({
|
||||
'nextcall': (datetime.datetime.utcnow() + datetime.timedelta(minutes=10)).isoformat(" ", "seconds")
|
||||
})
|
||||
staging_cron = env[model].browse([cron_id])
|
||||
staging_cron.active = False
|
||||
|
||||
env.run_crons(None)
|
||||
assert not staging.active
|
||||
assert not env['runbot_merge.stagings'].search([]).active
|
||||
assert env['runbot_merge.split'].search_count([]) == 2
|
||||
|
||||
env.run_crons()
|
||||
staging_cron.active = True
|
||||
# manually trigger that cron, as having the cron disabled prevented the creation of the triggers entirely
|
||||
env.run_crons('runbot_merge.staging_cron')
|
||||
|
||||
# check that st.pr_ids are the PRs we expect
|
||||
st = env['runbot_merge.stagings'].search([])
|
||||
|
Loading…
Reference in New Issue
Block a user