diff --git a/runbot_merge/models/project.py b/runbot_merge/models/project.py
index e828d29b..57fc1a33 100644
--- a/runbot_merge/models/project.py
+++ b/runbot_merge/models/project.py
@@ -51,6 +51,15 @@ class Project(models.Model):
freeze_id = fields.Many2one('runbot_merge.project.freeze', compute='_compute_freeze')
freeze_reminder = fields.Text()
+ uniquifier = fields.Boolean(
+ default=True,
+ help="Whether to add a uniquifier commit on repositories without PRs"
+ " during staging. The lack of uniquifier can lead to CI conflicts"
+ " as github works off of commits, so it's possible for an"
+ " unrelated build to trigger a failure if somebody is a dummy and"
+ " includes repos they have no commit for."
+ )
+
@api.depends('github_token')
def _compute_identity(self):
s = requests.Session()
diff --git a/runbot_merge/models/stagings_create.py b/runbot_merge/models/stagings_create.py
index 42b1aad5..7e083e0e 100644
--- a/runbot_merge/models/stagings_create.py
+++ b/runbot_merge/models/stagings_create.py
@@ -90,23 +90,11 @@ def try_staging(branch: Branch) -> Optional[Stagings]:
heads = []
commits = []
for repo, it in staging_state.items():
- if it.head != original_heads[repo]:
- # if we staged something for that repo, just create a record for
- # that commit, or flag existing one as to-recheck in case there are
- # already statuses we want to propagate to the staging or something
- env.cr.execute(
- "INSERT INTO runbot_merge_commit (sha, to_check, statuses) "
- "VALUES (%s, true, '{}') "
- "ON CONFLICT (sha) DO UPDATE SET to_check=true "
- "RETURNING id",
- [it.head]
- )
- [commit] = [head] = env.cr.fetchone()
- else:
- # if we didn't stage anything for that repo, create a dummy commit
- # (with a uniquifier to ensure we don't hit a previous version of
- # the same) to ensure the staging head is new and we're building
- # everything
+ if it.head == original_heads[repo] and branch.project_id.uniquifier:
+ # if we didn't stage anything for that repo and uniquification is
+ # enabled, create a dummy commit with a uniquifier to ensure we
+ # don't hit a previous version of the same to ensure the staging
+ # head is new and we're building everything
project = branch.project_id
uniquifier = base64.b64encode(os.urandom(12)).decode('ascii')
dummy_head = it.repo.with_config(check=True).commit_tree(
@@ -135,6 +123,18 @@ For-Commit-Id: {it.head}
)
([commit], [head]) = env.cr.fetchall()
it.head = dummy_head
+ else:
+ # otherwise just create a record for that commit, or flag existing
+ # one as to-recheck in case there are already statuses we want to
+ # propagate to the staging or something
+ env.cr.execute(
+ "INSERT INTO runbot_merge_commit (sha, to_check, statuses) "
+ "VALUES (%s, true, '{}') "
+ "ON CONFLICT (sha) DO UPDATE SET to_check=true "
+ "RETURNING id",
+ [it.head]
+ )
+ [commit] = [head] = env.cr.fetchone()
heads.append(fields.Command.create({
'repository_id': repo.id,
diff --git a/runbot_merge/tests/test_multirepo.py b/runbot_merge/tests/test_multirepo.py
index 3ba105ca..dbae165c 100644
--- a/runbot_merge/tests/test_multirepo.py
+++ b/runbot_merge/tests/test_multirepo.py
@@ -87,9 +87,11 @@ def make_branch(repo, name, message, tree, protect=True):
repo.protect(name)
return c
-def test_stage_one(env, project, repo_a, repo_b, config):
+@pytest.mark.parametrize('uniquifier', [False, True])
+def test_stage_one(env, project, repo_a, repo_b, config, uniquifier):
""" First PR is non-matched from A => should not select PR from B
"""
+ project.uniquifier = uniquifier
project.batch_limit = 1
with repo_a:
@@ -112,7 +114,10 @@ def test_stage_one(env, project, repo_a, repo_b, config):
assert pra_id.state == 'ready'
assert pra_id.staging_id
assert repo_a.commit('staging.master').message.startswith('commit_A_00')
- assert repo_b.commit('staging.master').message.startswith('force rebuild')
+ if uniquifier:
+ assert repo_b.commit('staging.master').message.startswith('force rebuild')
+ else:
+ assert repo_b.commit('staging.master').message == 'initial'
prb_id = to_pr(env, pr_b)
assert prb_id.state == 'ready'
diff --git a/runbot_merge/views/runbot_merge_project.xml b/runbot_merge/views/runbot_merge_project.xml
index 4795b502..5aa49d47 100644
--- a/runbot_merge/views/runbot_merge_project.xml
+++ b/runbot_merge/views/runbot_merge_project.xml
@@ -32,6 +32,7 @@
+