From 91c3f4def62e7dfba11f34838ce6ab601c63f846 Mon Sep 17 00:00:00 2001 From: Daniel Diblik <8378124+danmyway@users.noreply.github.com> Date: Wed, 20 Mar 2024 19:19:49 +0100 Subject: [PATCH] Warn if build non existent (#35) * Refactor copr_api, modify nargs * refactor get_info() in copr_api module * add warning, when referenced build is not found in the query * modify reference and build_id nargs to accept only one option * warn and exit when build_id doesn't point to correct project/package and/or the state of the build is failed * Add docstring, append changelog Signed-off-by: Daniel Diblik --------- Signed-off-by: Daniel Diblik --- CHANGELOG.md | 1 + src/dispatch/__init__.py | 4 +- src/dispatch/copr_api.py | 111 +++++++++++++++++++++++++++++---------- src/report/__main__.py | 7 +-- 4 files changed, 91 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea0b753..559337e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Calendar Versioning](https://calver.org).
- `-u/--uefi` test option to request target with UEFI boot mode - CentOS Stream 8 target - `--parallel-limit` limit of plans to be run in parallel, default 42 +- query for task ID, warn and exit if build doesn't match requested test artifact ### Changed - `-c/--compose` to `-t/--target` diff --git a/src/dispatch/__init__.py b/src/dispatch/__init__.py index db49c70..780b9d6 100644 --- a/src/dispatch/__init__.py +++ b/src/dispatch/__init__.py @@ -113,7 +113,7 @@ def get_arguments(args=None): reference.add_argument( "-ref", "--reference", - nargs="+", + nargs=1, help=f"""{FormatText.bold}Mutually exclusive with respect to --task-id.{FormatText.end} For brew: Specify the reference version to find the correct artifact (e.g. 0.1-2, 0.1.2). For copr: Specify the pull request reference to find the correct artifact (e.g. pr123, main, master, ...).""", @@ -122,7 +122,7 @@ def get_arguments(args=None): reference.add_argument( "-id", "--task-id", - nargs="+", + nargs=1, help=f"""{FormatText.bold}Mutually exclusive with respect to --reference.{FormatText.end} For brew: Specify the TASK ID for required brew build. {FormatText.bold}NOTE: Double check, that you are passing TASK ID for copr builds, not BUILD ID otherwise testing farm will not install the package.{FormatText.end} diff --git a/src/dispatch/copr_api.py b/src/dispatch/copr_api.py index 4985177..f2039ae 100644 --- a/src/dispatch/copr_api.py +++ b/src/dispatch/copr_api.py @@ -1,10 +1,11 @@ #!/usr/bin/env python3 +import sys from datetime import datetime from copr.v3 import BuildProxy from dispatch import dispatch_globals -from dispatch import get_arguments, get_compose_mapping, get_logging +from dispatch import get_arguments, get_compose_mapping, get_logging, FormatText SESSION = BuildProxy(dispatch_globals.COPR_CONFIG) LOGGER = get_logging() @@ -13,16 +14,39 @@ def get_info(package, repository, reference, composes): + """ + Get information about a COPR build for a specific package and reference. + + Args: + package (str): The name of the package for which to get information. + repository (str): The name of the Copr repository containing the package build. + reference (str, int): The reference for the package build. This can be either a commit reference + (e.g., "master", "main") or a pull request ID (e.g., "pull/123"). + composes (list): A list of strings representing the target distributions for the COPR build. + + Returns: + tuple: A tuple containing two elements: + - A list of dictionaries containing build information for each target distribution. + - The build reference used for selecting the COPR build. + """ owner = "@oamg" info = [] - build_reference = None + build_reference = reference[0] pr_baseurl = f"https://github.com/oamg/{package}/pull/" if ARGS.reference: - query = SESSION.get_list(owner, repository) - for build_reference in reference: - if build_reference == "master" or build_reference == "main": + def _get_correct_build_list(): + """ + Get a clean list of COPR builds that match the specified reference. + + Returns: + list: A list of COPR builds that match the specified reference. + """ + clean_build_list = [] + query = SESSION.get_list(owner, repository) + + if build_reference in ["master", "main"]: LOGGER.info( f"Getting copr build info for referenced {build_reference}." ) @@ -31,35 +55,54 @@ def get_info(package, repository, reference, composes): f"Getting copr build info for referenced {str.upper(build_reference)}." ) LOGGER.info(f"LINK: {pr_baseurl}{build_reference[2:]}") - - for build in query: - # Parse only correct packages - if build.source_package["name"] == package: - build = build - else: - continue - - # Get build with pull request number + for build_munch in query: if ( - build.source_package["version"] is None - or build.state == "failed" - or build_reference not in build.source_package["version"] - ): - continue - for build_info in get_build_dictionary( - build, repository, package, composes + build_munch.state != "failed" + and build_munch.source_package["name"] == package + and build_munch.source_package["version"] is not None + and build_reference in build_munch.source_package["version"] ): - info.append(build_info) - break + clean_build_list.append(build_munch) - elif ARGS.task_id: - for build_reference in reference: - LOGGER.info(f"Getting copr build info for referenced ID {build_reference}.") - build = SESSION.get(build_reference) + if not clean_build_list: + LOGGER.warning( + f"{FormatText.yellow+FormatText.bold}No build with given {build_reference} found!{FormatText.end}" + ) + + return clean_build_list + + for build_munch in _get_correct_build_list(): + build = build_munch for build_info in get_build_dictionary( build, repository, package, composes ): info.append(build_info) + # Break so just the latest is selected + break + + elif ARGS.task_id: + build = None + LOGGER.info(f"Getting copr build info for referenced ID {build_reference}.") + build_munch = SESSION.get(build_reference) + if build_munch.source_package["name"] != package: + LOGGER.critical(f"There seems to be some mismatch with the build ID!") + LOGGER.critical( + f"The ID points to owner: {build_munch.ownername}, project: {build_munch.projectname}" + ) + LOGGER.critical(f"Exiting.") + sys.exit(99) + elif build_munch.state == "failed": + LOGGER.critical( + f"{FormatText.red+FormatText.bold}The build with the given ID failed!{FormatText.end}" + ) + LOGGER.critical( + f"{FormatText.red+FormatText.bold}Please provide valid build ID.{FormatText.end}" + ) + LOGGER.critical(f"{FormatText.red+FormatText.bold}Exiting.{FormatText.end}") + else: + build = build_munch + for build_info in get_build_dictionary(build, repository, package, composes): + info.append(build_info) return info, build_reference @@ -67,6 +110,20 @@ def get_info(package, repository, reference, composes): def get_build_dictionary( build, repository, package, composes, source_release=None, target_release=None ): + """ + Get the dictionary containing build information for each target distribution. + + Args: + build: The COPR build object. + repository (str): The COPR repository name. + package (str): The name of the package. + composes (list): A list of strings representing the target distributions for the COPR build. + source_release (str, optional): The source release version. Defaults to None. + target_release (str, optional): The target release version. Defaults to None. + + Returns: + list: A list of dictionaries containing build information for each target distribution. + """ build_info = [] build_baseurl = ( f"https://copr.fedorainfracloud.org/coprs/g/oamg/{repository}/build/" diff --git a/src/report/__main__.py b/src/report/__main__.py index 1329a82..b91a132 100644 --- a/src/report/__main__.py +++ b/src/report/__main__.py @@ -124,7 +124,7 @@ def parse_request_xunit(request_url_list=None, tasks_source=None, skip_pass=Fals request_state = request.json()["state"].upper() request_uuid = request.json()["id"] request_target = request.json()["environments_requested"][0]["os"]["compose"] - request_arch = request.json()["environments_requested"][0]['arch'] + request_arch = request.json()["environments_requested"][0]["arch"] request_datetime_created = request.json()["created"] request_datetime_parsed = request_datetime_created.split(".")[0] @@ -231,7 +231,9 @@ def parse_request_xunit(request_url_list=None, tasks_source=None, skip_pass=Fals # it consist of only the plan name testsuite_name = elem.xpath("./@name")[0].split(":")[-1] try: - testsuite_arch = elem.xpath("./testing-environment/property[@name='arch']/@value")[0] + testsuite_arch = elem.xpath( + "./testing-environment/property[@name='arch']/@value" + )[0] except IndexError: testsuite_arch = elem.xpath("./@name")[0].split(":")[1] testsuite_result = elem.xpath("./@result")[0].upper() @@ -433,7 +435,6 @@ def build_table(): if ARGS.split_planname: planname_split_index = ARGS.split_planname - def _gen_row(uuid="", target="", arch="", testplan="", testcase="", result=""): if "UUID" in fields: yield uuid