From e9a22510e80a08f0aa798ae82ddbbebbcc5152a4 Mon Sep 17 00:00:00 2001 From: Tobias Henkel Date: Fri, 22 Dec 2017 08:36:12 +0100 Subject: Add implicit project name matching Most project pipelines define jobs for the project they are defined in. However they still need to name the project explicitly which makes actions like repo renaming/movement very difficult. Thus we want to add the project itself as an implicit fallback. Change-Id: I273a2b3b1ba2a50565624553e3898be2da5611de Depends-On: I5af74763fc9c4be395a341f28c6751d22bd46195 --- doc/source/user/config.rst | 3 +- .../git/common-config/playbooks/test-common.yaml | 2 + .../implicit-project/git/common-config/zuul.yaml | 57 +++++++++++++++++ .../implicit-project/git/org_project/.zuul.yaml | 11 ++++ .../git/org_project/playbooks/test-project.yaml | 2 + tests/fixtures/config/implicit-project/main.yaml | 8 +++ tests/unit/test_scheduler.py | 71 ++++++++++++++++++++++ zuul/configloader.py | 2 +- zuul/model.py | 9 ++- 9 files changed, 161 insertions(+), 4 deletions(-) create mode 100644 tests/fixtures/config/implicit-project/git/common-config/playbooks/test-common.yaml create mode 100644 tests/fixtures/config/implicit-project/git/common-config/zuul.yaml create mode 100644 tests/fixtures/config/implicit-project/git/org_project/.zuul.yaml create mode 100644 tests/fixtures/config/implicit-project/git/org_project/playbooks/test-project.yaml create mode 100644 tests/fixtures/config/implicit-project/main.yaml diff --git a/doc/source/user/config.rst b/doc/source/user/config.rst index 916e66ad9..fff673b55 100644 --- a/doc/source/user/config.rst +++ b/doc/source/user/config.rst @@ -1032,11 +1032,12 @@ pipeline. The following attributes may appear in a project: .. attr:: name - :required: The name of the project. If Zuul is configured with two or more unique projects with the same name, the canonical hostname for the project should be included (e.g., `git.example.com/foo`). + If not given it is implicitly derived from the project where this + is defined. .. attr:: templates diff --git a/tests/fixtures/config/implicit-project/git/common-config/playbooks/test-common.yaml b/tests/fixtures/config/implicit-project/git/common-config/playbooks/test-common.yaml new file mode 100644 index 000000000..f679dceae --- /dev/null +++ b/tests/fixtures/config/implicit-project/git/common-config/playbooks/test-common.yaml @@ -0,0 +1,2 @@ +- hosts: all + tasks: [] diff --git a/tests/fixtures/config/implicit-project/git/common-config/zuul.yaml b/tests/fixtures/config/implicit-project/git/common-config/zuul.yaml new file mode 100644 index 000000000..038c412dd --- /dev/null +++ b/tests/fixtures/config/implicit-project/git/common-config/zuul.yaml @@ -0,0 +1,57 @@ +- pipeline: + name: check + manager: independent + post-review: true + trigger: + gerrit: + - event: patchset-created + success: + gerrit: + Verified: 1 + failure: + gerrit: + Verified: -1 + +- pipeline: + name: gate + manager: dependent + success-message: Build succeeded (gate). + trigger: + gerrit: + - event: comment-added + approval: + - Approved: 1 + success: + gerrit: + Verified: 2 + submit: true + failure: + gerrit: + Verified: -2 + start: + gerrit: + Verified: 0 + precedence: high + + +- job: + name: base + parent: null + +- job: + name: test-common + run: playbooks/test-common.yaml + +- project: + check: + jobs: + - test-common + +- project: + name: org/project + check: + jobs: + - test-common + gate: + jobs: + - test-common diff --git a/tests/fixtures/config/implicit-project/git/org_project/.zuul.yaml b/tests/fixtures/config/implicit-project/git/org_project/.zuul.yaml new file mode 100644 index 000000000..bce195cc6 --- /dev/null +++ b/tests/fixtures/config/implicit-project/git/org_project/.zuul.yaml @@ -0,0 +1,11 @@ +- job: + name: test-project + run: playbooks/test-project.yaml + +- project: + check: + jobs: + - test-project + gate: + jobs: + - test-project diff --git a/tests/fixtures/config/implicit-project/git/org_project/playbooks/test-project.yaml b/tests/fixtures/config/implicit-project/git/org_project/playbooks/test-project.yaml new file mode 100644 index 000000000..f679dceae --- /dev/null +++ b/tests/fixtures/config/implicit-project/git/org_project/playbooks/test-project.yaml @@ -0,0 +1,2 @@ +- hosts: all + tasks: [] diff --git a/tests/fixtures/config/implicit-project/main.yaml b/tests/fixtures/config/implicit-project/main.yaml new file mode 100644 index 000000000..208e274b1 --- /dev/null +++ b/tests/fixtures/config/implicit-project/main.yaml @@ -0,0 +1,8 @@ +- tenant: + name: tenant-one + source: + gerrit: + config-projects: + - common-config + untrusted-projects: + - org/project diff --git a/tests/unit/test_scheduler.py b/tests/unit/test_scheduler.py index aacc81e00..6bbf098fb 100755 --- a/tests/unit/test_scheduler.py +++ b/tests/unit/test_scheduler.py @@ -6070,6 +6070,77 @@ class TestSemaphoreMultiTenant(ZuulTestCase): self.assertEqual(B.reported, 1) +class TestImplicitProject(ZuulTestCase): + tenant_config_file = 'config/implicit-project/main.yaml' + + def test_implicit_project(self): + # config project should work with implicit project name + A = self.fake_gerrit.addFakeChange('common-config', 'master', 'A') + self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1)) + + # untrusted project should work with implicit project name + B = self.fake_gerrit.addFakeChange('org/project', 'master', 'A') + self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1)) + + self.waitUntilSettled() + + self.assertEqual(A.data['status'], 'NEW') + self.assertEqual(A.reported, 1) + self.assertEqual(B.data['status'], 'NEW') + self.assertEqual(B.reported, 1) + self.assertHistory([ + dict(name='test-common', result='SUCCESS', changes='1,1'), + dict(name='test-common', result='SUCCESS', changes='2,1'), + dict(name='test-project', result='SUCCESS', changes='2,1'), + ], ordered=False) + + # now test adding a further project in repo + in_repo_conf = textwrap.dedent( + """ + - job: + name: test-project + run: playbooks/test-project.yaml + - job: + name: test2-project + run: playbooks/test-project.yaml + + - project: + check: + jobs: + - test-project + gate: + jobs: + - test-project + + - project: + check: + jobs: + - test2-project + gate: + jobs: + - test2-project + + """) + file_dict = {'.zuul.yaml': in_repo_conf} + C = self.fake_gerrit.addFakeChange('org/project', 'master', 'A', + files=file_dict) + C.addApproval('Code-Review', 2) + self.fake_gerrit.addEvent(C.addApproval('Approved', 1)) + self.waitUntilSettled() + + # change C must be merged + self.assertEqual(C.data['status'], 'MERGED') + self.assertEqual(C.reported, 2) + self.assertHistory([ + dict(name='test-common', result='SUCCESS', changes='1,1'), + dict(name='test-common', result='SUCCESS', changes='2,1'), + dict(name='test-project', result='SUCCESS', changes='2,1'), + dict(name='test-common', result='SUCCESS', changes='3,1'), + dict(name='test-project', result='SUCCESS', changes='3,1'), + dict(name='test2-project', result='SUCCESS', changes='3,1'), + ], ordered=False) + + class TestSemaphoreInRepo(ZuulTestCase): config_file = 'zuul-connections-gerrit-and-github.conf' tenant_config_file = 'config/in-repo/main.yaml' diff --git a/zuul/configloader.py b/zuul/configloader.py index 71c4ccc83..c440a76ff 100644 --- a/zuul/configloader.py +++ b/zuul/configloader.py @@ -852,7 +852,7 @@ class ProjectParser(object): def getSchema(self): project = { - vs.Required('name'): str, + 'name': str, 'description': str, 'templates': [str], 'merge-mode': vs.Any('merge', 'merge-resolve', diff --git a/zuul/model.py b/zuul/model.py index dbae1f296..5127a8c3e 100644 --- a/zuul/model.py +++ b/zuul/model.py @@ -2256,7 +2256,7 @@ class TenantProjectConfig(object): class ProjectConfig(object): - # Represents a project cofiguration + # Represents a project configuration def __init__(self, name, source_context=None): self.name = name # If this is a template, it will have a source_context, but @@ -2435,7 +2435,12 @@ class UnparsedTenantConfig(object): raise ConfigItemMultipleKeysError() key, value = list(item.items())[0] if key == 'project': - name = value['name'] + name = value.get('name') + if not name: + # There is no name defined so implicitly add the name + # of the project where it is defined. + name = value['_source_context'].project.canonical_name + value['name'] = name self.projects.setdefault(name, []).append(value) elif key == 'job': self.jobs.append(value) -- cgit v1.2.1