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