diff --git a/runbot_merge/controllers/__init__.py b/runbot_merge/controllers/__init__.py index 49a6323b..3c15a50c 100644 --- a/runbot_merge/controllers/__init__.py +++ b/runbot_merge/controllers/__init__.py @@ -166,6 +166,16 @@ def handle_pr(env, event): # don't marked merged PRs as closed (!!!) if event['action'] == 'closed' and pr_obj.state != 'merged': + # ignore if the PR is already being updated in a separate transaction + # (most likely being merged?) + env.cr.execute(''' + SELECT id FROM runbot_merge_pull_requests + WHERE id = %s AND state != 'merged' + FOR UPDATE SKIP LOCKED; + ''', [pr_obj.id]) + if not env.cr.fetchall(): + return 'Ignored: could not lock rows (probably being merged)' + env.cr.execute(''' UPDATE runbot_merge_pull_requests SET state = 'closed' diff --git a/runbot_merge/data/merge_cron.xml b/runbot_merge/data/merge_cron.xml index c3e225a3..091efa08 100644 --- a/runbot_merge/data/merge_cron.xml +++ b/runbot_merge/data/merge_cron.xml @@ -3,7 +3,7 @@ Check for progress of PRs & Stagings code - model._check_progress() + model._check_progress(True) 1 minutes -1 diff --git a/runbot_merge/models/pull_requests.py b/runbot_merge/models/pull_requests.py index 4285e9bd..d1998fc0 100644 --- a/runbot_merge/models/pull_requests.py +++ b/runbot_merge/models/pull_requests.py @@ -61,13 +61,17 @@ class Project(models.Model): "will lead to webhook rejection. Should only use ASCII." ) - def _check_progress(self): + def _check_progress(self, commit=False): for project in self.search([]): for staging in project.mapped('branch_ids.active_staging_id'): staging.check_status() + if commit: + self.env.cr.commit() for branch in project.branch_ids: branch.try_staging() + if commit: + self.env.cr.commit() # I have no idea why this is necessary for tests to pass, the only # DB update done not through the ORM is when receiving a notification