From eb4636f483854bc11c864d3ca1bea87f3f5113a0 Mon Sep 17 00:00:00 2001 From: Tony Breeds Date: Fri, 30 Jun 2023 14:00:42 +1000 Subject: [PATCH] Exclude projects under the distributed leadership model Currently there are 2 leadership types "distributed" and the Default/unspecified which we treat as the long established PTL model. Projects that have selected to use the "distributed" model do not require a PTL election and in fact projects under this model should reject a PTL nomination as the correct process involves a change the governance repo. This change updates 'create-directories' to exclude those projects, and also updates the ci checks to fail PTL nominations for "distributed" projects. Change-Id: Ib4a2ce1e4ee74e8e9a49975017e14172b4d1f576 --- .../cmds/ci_check_all_candidate_files.py | 16 ++++++++ openstack_election/cmds/create_directories.py | 7 +++- .../tests/cmds/test_ci_checks.py | 40 +++++++++++++++++++ openstack_election/utils.py | 5 +++ 4 files changed, 67 insertions(+), 1 deletion(-) diff --git a/openstack_election/cmds/ci_check_all_candidate_files.py b/openstack_election/cmds/ci_check_all_candidate_files.py index deab27b8..56c25f09 100755 --- a/openstack_election/cmds/ci_check_all_candidate_files.py +++ b/openstack_election/cmds/ci_check_all_candidate_files.py @@ -44,6 +44,21 @@ def validate_filename(filepath): return is_valid +def validate_project(filepath, projects): + print('Validate the project requires a PTL') + print('-----------------------------------') + + project_name = utils.get_project(filepath) + leadership_type = projects.get(project_name, {}).get("leadership_type") + is_valid = leadership_type not in ["distributed"] + + print('Project Name: %s [%s]' % (project_name, filepath)) + print('Leadership Type: %s %s' % (leadership_type, + {True: 'PASS', False: 'FAIL'}[is_valid])) + print('') + return is_valid + + def validate_member(filepath, verbose=0): print('Validate email address is OSF member') print('------------------------------------') @@ -148,6 +163,7 @@ def main(): candidate_ok = True candidate_ok &= validate_filename(filepath) + candidate_ok &= validate_project(filepath, projects) candidate_ok &= validate_member(filepath, verbose=args.verbose) if candidate_ok: diff --git a/openstack_election/cmds/create_directories.py b/openstack_election/cmds/create_directories.py index eef23372..20b63a41 100755 --- a/openstack_election/cmds/create_directories.py +++ b/openstack_election/cmds/create_directories.py @@ -22,7 +22,12 @@ def main(): base_dir = "candidates/%s" % utils.conf['release'] projects = utils.get_projects() - project_list = list(projects.keys()) + project_list = [] + for project_name, project_data in projects.items(): + # leadership_type is an optional property and currently (2023-06-29) + # the only valid enumeration is 'distributed'. + if project_data.get("leadership_type", "") not in ["distributed"]: + project_list.append(project_name) project_list.sort() for project in project_list + ["TC"]: dpath = "%s/%s" % (base_dir, utils.name2dir(project)) diff --git a/openstack_election/tests/cmds/test_ci_checks.py b/openstack_election/tests/cmds/test_ci_checks.py index a46e196b..163de5a8 100644 --- a/openstack_election/tests/cmds/test_ci_checks.py +++ b/openstack_election/tests/cmds/test_ci_checks.py @@ -10,6 +10,10 @@ # License for the specific language governing permissions and limitations # under the License. +import os +import textwrap +import yaml + from unittest import mock from openstack_election.cmds import ci_check_all_candidate_files @@ -51,3 +55,39 @@ class TestFindModifiedCandidateFiles(base.ElectionTestCase): filenames = \ ci_check_all_candidate_files.find_modified_candidate_files() self.assertEqual(expected_filenames, filenames) + + +class TestValidateProject(base.ElectionTestCase): + projects_str = textwrap.dedent(""" + --- + project: + ptl: + name: PTL Name + email: ptl@example.com + irc: ptl_nic + distributed_project: + leadership_type: distributed + """) + fake_projects = yaml.safe_load(projects_str) + + def test_ptl_project(self): + file_path = os.path.join("...", utils.CANDIDATE_PATH, + "project/candidate@email") + is_ok = \ + ci_check_all_candidate_files.validate_project(file_path, + self.fake_projects) + + self.assertTrue(is_ok) + + # A project with a "distributed" leadership_type should not have + # candidates + def test_distributed_project(self): + file_path = os.path.join("...", utils.CANDIDATE_PATH, + "distributed_project/candidate@email") + is_ok = \ + ci_check_all_candidate_files.validate_project(file_path, + self.fake_projects) + + self.assertFalse(is_ok) + +# TODO(tonyb): Add more validate_* tests here diff --git a/openstack_election/utils.py b/openstack_election/utils.py index a650046b..4a32155d 100644 --- a/openstack_election/utils.py +++ b/openstack_election/utils.py @@ -176,6 +176,11 @@ def get_email(filepath): return os.path.basename(filepath) +def get_project(filepath): + path = os.path.dirname(filepath) + return os.path.basename(path) + + def get_gerrit_account(email): accounts = gerrit_query('%s/accounts/' % (GERRIT_BASE), params={'q': email, 'o': ['DETAILS']})