Merge "Fix mixed canonical/non-canonical project merge" into feature/zuulv3
diff --git a/tests/fixtures/config/tenant-parser/git/common-config/zuul.yaml b/tests/fixtures/config/tenant-parser/git/common-config/zuul.yaml
index e21f967..a28ef54 100644
--- a/tests/fixtures/config/tenant-parser/git/common-config/zuul.yaml
+++ b/tests/fixtures/config/tenant-parser/git/common-config/zuul.yaml
@@ -18,8 +18,10 @@
 - job:
     name: common-config-job
 
+# Use the canonical name here. This should be merged with the org/project1 in
+# the other repo.
 - project:
-    name: org/project1
+    name: review.example.com/org/project1
     check:
       jobs:
         - common-config-job
diff --git a/zuul/configloader.py b/zuul/configloader.py
index e034329..bcb3e49 100644
--- a/zuul/configloader.py
+++ b/zuul/configloader.py
@@ -1162,8 +1162,8 @@
                                                   tenant.config_projects,
                                                   tenant.untrusted_projects,
                                                   cached, tenant)
-        unparsed_config.extend(tenant.config_projects_config)
-        unparsed_config.extend(tenant.untrusted_projects_config)
+        unparsed_config.extend(tenant.config_projects_config, tenant=tenant)
+        unparsed_config.extend(tenant.untrusted_projects_config, tenant=tenant)
         tenant.layout = TenantParser._parseLayout(base, tenant,
                                                   unparsed_config,
                                                   scheduler,
diff --git a/zuul/model.py b/zuul/model.py
index 6426bbe..f3f358b 100644
--- a/zuul/model.py
+++ b/zuul/model.py
@@ -2385,14 +2385,25 @@
         r.semaphores = copy.deepcopy(self.semaphores)
         return r
 
-    def extend(self, conf):
+    def extend(self, conf, tenant=None):
         if isinstance(conf, UnparsedTenantConfig):
             self.pragmas.extend(conf.pragmas)
             self.pipelines.extend(conf.pipelines)
             self.jobs.extend(conf.jobs)
             self.project_templates.extend(conf.project_templates)
             for k, v in conf.projects.items():
-                self.projects.setdefault(k, []).extend(v)
+                name = k
+                # If we have the tenant add the projects to
+                # the according canonical name instead of the given project
+                # name. If it is not found, it's ok to add this to the given
+                # name. We also don't need to throw the
+                # ProjectNotFoundException here as semantic validation occurs
+                # later where it will fail then.
+                if tenant is not None:
+                    trusted, project = tenant.getProject(k)
+                    if project is not None:
+                        name = project.canonical_name
+                self.projects.setdefault(name, []).extend(v)
             self.nodesets.extend(conf.nodesets)
             self.secrets.extend(conf.secrets)
             self.semaphores.extend(conf.semaphores)