From 2d0a7aa6dc7a85f0908d5e18f7c5c4fba038f3a5 Mon Sep 17 00:00:00 2001 From: Oliver Smith Date: Sun, 17 Mar 2024 21:45:36 +0100 Subject: [PATCH] CI: add more tests for CODEOWNERS (MR 4940) * Parse the file in python and ensure it is ordered alphabetically * Ensure that we have at least as many gitlab nicknames in CODEOWNERS, as there are listed maintainers in main and community devices. This should help with enforcing that every maintainer is also listed in CODEOWNERS, so they can be easily pinged via their gitlab nickname if something for the device they maintain is happening. [ci:skip-build]: already built successfully in CI --- .ci/testcases/test_device.py | 77 ++++++++++++++++++++++++++++++++++-- CODEOWNERS | 1 + 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/.ci/testcases/test_device.py b/.ci/testcases/test_device.py index 3b5236f61..d4d341f7c 100644 --- a/.ci/testcases/test_device.py +++ b/.ci/testcases/test_device.py @@ -1,16 +1,26 @@ #!/usr/bin/env python3 -# Copyright 2021 Oliver Smith +# Copyright 2024 Oliver Smith # SPDX-License-Identifier: GPL-3.0-or-later +import fnmatch import glob +import os import pytest import sys -import os import add_pmbootstrap_to_import_path import pmb.parse import pmb.parse._apkbuild +# Cache for codeowners_parse +codeowners_parsed = {} + +# Don't complain if these nicknames are the only maintainers of an APKBUILD, +# because they are actually a group of people +gitlab_groups = [ + "@sdm845-mainline", +] + def device_dependency_check(apkbuild, path): """ Raise an error if a device package has a dependency that is not allowed @@ -100,23 +110,84 @@ def test_aports_device_kernel(args): path) +def codeowners_parse(args): + global codeowners_parsed + + pattern_prev = None + + with open(f"{args.aports}/CODEOWNERS") as h: + for line in h: + line = line.rstrip() + if not line or line.startswith("#"): + continue + + pattern_nicks = line.split() + assert len(pattern_nicks) > 1, f"CODEOWNERS line without nicks: {line}" + + pattern = pattern_nicks[0] + if pattern.endswith("/"): + pattern += "*" + + nicks = [] + for word in pattern_nicks[1:]: + if word.startswith("@"): + nicks += [word] + codeowners_parsed[pattern] = nicks + + if pattern_prev: + assert pattern_prev <= pattern, "CODEOWNERS: please order entries alphabetically" + pattern_prev = pattern + + +def require_enough_codeowners_entries(args, path, maintainers): + """ + :param path: full path to an APKBUILD (e.g. /home/user/…/APKBUILD) + :param maintainers: list of one or more maintainers + """ + path = os.path.relpath(path, args.aports) + + nicks = set() + for pattern, pattern_nicks in codeowners_parsed.items(): + if fnmatch.fnmatch(path, pattern): + for nick in pattern_nicks: + nicks.add(nick) + + print(f"{path}:") + print(f" APKBUILD: {maintainers}") + print(f" CODEOWNERS: {nicks}") + + if len(nicks) < len(maintainers): + for nick in nicks: + if nick in gitlab_groups: + print(f" -> {nick} is a group") + return + + assert len(nicks) >= len(maintainers), \ + f"{path}: make sure that each maintainer is listed in CODEOWNERS!" + + def test_aports_maintained(args): """ Ensure that aports in /device/{main,community} have "Maintainer:" and - "Co-Maintainer:" (only required for main) listed in their APKBUILDs. + "Co-Maintainer:" (only required for main) listed in their APKBUILDs. Also + check that at least as many are listed in CODEOWNERS. """ + codeowners_parse(args) + for path in glob.iglob(f"{args.aports}/device/main/*/APKBUILD"): if '/firmware-' in path: continue maintainers = pmb.parse._apkbuild.maintainers(path) assert maintainers and len(maintainers) >= 2, \ f"{path} in main needs at least 1 Maintainer and 1 Co-Maintainer" + require_enough_codeowners_entries(args, path, maintainers) for path in glob.iglob(f"{args.aports}/device/community/*/APKBUILD"): if '/firmware-' in path: continue maintainers = pmb.parse._apkbuild.maintainers(path) assert maintainers, f"{path} in community needs at least 1 Maintainer" + require_enough_codeowners_entries(args, path, maintainers) def test_aports_unmaintained(args): diff --git a/CODEOWNERS b/CODEOWNERS index a98e61b73..c9a0fbfed 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,4 +1,5 @@ # https://docs.gitlab.com/ee/user/project/code_owners.html +# Put groups like @sdm845-mainline into test_device.py:gitlab_groups. # Order lines alphabetically! device/*/*-amlogic-s905*/ @vitali64yt