diff --git a/environment.sample b/environment.sample index ff75553a..93f1a9f2 100644 --- a/environment.sample +++ b/environment.sample @@ -34,6 +34,9 @@ ODOO_PASSWORD= # Number of days before the proposal can be marked as "Approved" #MIN_PR_AGE=5 +# Color of the github label that contains the name of the module +#MODULE_LABEL_COLOR=#ffc + # Coma separated list of task to run # By default all configured tasks are run. # Available tasks: diff --git a/src/oca_github_bot/config.py b/src/oca_github_bot/config.py index b1b886c8..869208ab 100644 --- a/src/oca_github_bot/config.py +++ b/src/oca_github_bot/config.py @@ -101,6 +101,8 @@ def func_wrapper(*args, **kwargs): APPROVALS_REQUIRED = int(os.environ.get("APPROVALS_REQUIRED", "2")) MIN_PR_AGE = int(os.environ.get("MIN_PR_AGE", "5")) +MODULE_LABEL_COLOR = os.environ.get("MODULE_LABEL_COLOR", "#ffc") + dist_publisher = MultiDistPublisher() SIMPLE_INDEX_ROOT = os.environ.get("SIMPLE_INDEX_ROOT") if SIMPLE_INDEX_ROOT: diff --git a/src/oca_github_bot/tasks/label_modified_addons.py b/src/oca_github_bot/tasks/label_modified_addons.py index d89c9a16..d9b44760 100644 --- a/src/oca_github_bot/tasks/label_modified_addons.py +++ b/src/oca_github_bot/tasks/label_modified_addons.py @@ -2,14 +2,16 @@ # Distributed under the MIT License (http://opensource.org/licenses/MIT). from .. import github -from ..config import switchable +from ..config import MODULE_LABEL_COLOR, switchable from ..manifest import git_modified_addons from ..process import check_call from ..queue import task +from ..utils import compute_module_label_name from ..version_branch import is_main_branch_bot_branch def _label_modified_addons(gh, org, repo, pr, dry_run): + gh_repo = gh.repository(org, repo) gh_pr = gh.pull_request(org, repo, pr) target_branch = gh_pr.base.ref pr_branch = f"tmp-pr-{pr}" @@ -23,7 +25,22 @@ def _label_modified_addons(gh, org, repo, pr, dry_run): if not modified_addons: return gh_issue = github.gh_call(gh_pr.issue) - new_labels = {f"addon:{modified_addon}" for modified_addon in modified_addons} + + new_labels = set() + for modified_addon in modified_addons: + label_name = compute_module_label_name(modified_addon) + # We create label at repo level, because it is possible to + # to set description in create_label() function + # (and not in issue.add_labels()) + if label_name not in [x.name for x in gh_repo.labels()] and not dry_run: + github.gh_call( + gh_repo.create_label, + name=label_name, + description=f"Module {modified_addon}", + color=MODULE_LABEL_COLOR.replace("#", ""), + ) + new_labels.add(label_name) + if is_main_branch_bot_branch(target_branch): new_labels.add(f"series:{target_branch}") new_labels = new_labels - {label.name for label in gh_issue.labels()} diff --git a/src/oca_github_bot/utils.py b/src/oca_github_bot/utils.py index bd76d6d8..fdeaf61e 100644 --- a/src/oca_github_bot/utils.py +++ b/src/oca_github_bot/utils.py @@ -1,6 +1,7 @@ # Copyright (c) ACSONE SA/NV 2021 # Distributed under the MIT License (http://opensource.org/licenses/MIT). +import hashlib import re import shlex import time @@ -8,6 +9,12 @@ from . import config +# Max size allowed by github for label name +_MAX_LABEL_SIZE = 50 +# Size of the hash, added at the end of the label name +# if module name is too long +_HASH_SIZE = 5 + def hide_secrets(s: str) -> str: # TODO do we want to hide other secrets ? @@ -33,3 +40,24 @@ def retry_on_exception( def cmd_to_str(cmd: Sequence[str]) -> str: return shlex.join(str(c) for c in cmd) + + +def compute_module_label_name(module_name: str) -> str: + """To avoid error if label name is too long + we cut big label, and finish by a hash of the module name. + (The full module name will be present in the description). + Short module name exemple : + - module : 'web_responsive' + - label : 'mod:web_responsive' + Long module name exemple : + - module : 'account_invoice_supplierinfo_update_triple_discount' + - label : 'mod:account_invoice_supplierinfo_update_trip bf3f3' + """ + label_name = f"mod:{module_name}" + if len(label_name) > _MAX_LABEL_SIZE: + module_hash = hashlib.sha256(bytes(module_name, "utf-8")).hexdigest() + label_name = ( + f"{label_name[:(_MAX_LABEL_SIZE - (_HASH_SIZE + 1))]}" + f" {module_hash[:_HASH_SIZE]}" + ) + return label_name diff --git a/tests/test_utils.py b/tests/test_utils.py index b3baf49b..6b28b236 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -5,7 +5,12 @@ import pytest -from oca_github_bot.utils import cmd_to_str, hide_secrets, retry_on_exception +from oca_github_bot.utils import ( + cmd_to_str, + compute_module_label_name, + hide_secrets, + retry_on_exception, +) from .common import set_config @@ -98,3 +103,11 @@ def func_that_raises(): ) def test_cmd_to_str(cmd, expected): assert cmd_to_str(cmd) == expected + + +def test_compute_module_label_name(): + assert compute_module_label_name("web_responsive") == "mod:web_responsive" + assert ( + compute_module_label_name("account_invoice_supplierinfo_update_triple_discount") + == "mod:account_invoice_supplierinfo_update_trip bf3f3" + )