diff --git a/alws/crud/build_node.py b/alws/crud/build_node.py index 8a51a7c78..98c4a7b94 100644 --- a/alws/crud/build_node.py +++ b/alws/crud/build_node.py @@ -29,10 +29,7 @@ from alws.schemas import build_node_schema from alws.schemas.build_node_schema import BuildDoneArtifact from alws.utils.github_integration_helper import ( - find_issues_by_build_id, - find_issues_by_record_id, - get_github_client, - move_issues, + move_issue_to_testing, ) from alws.utils.ids import get_random_unique_version from alws.utils.modularity import IndexWrapper, RpmArtifact @@ -469,25 +466,12 @@ def append_errata_package(_, errata_package, artifact, rpm_info): rpm_info, ) errata_record_ids.add(errata_package.errata_record_id) - if settings.github_integration_enabled: + if settings.github_integration_enabled and errata_record_ids: try: - github_client = await get_github_client() - issues = await find_issues_by_record_id( - github_client=github_client, + await move_issue_to_testing( record_ids=list(errata_record_ids), + build_id=build_id, ) - issues.extend( - await find_issues_by_build_id( - github_client=github_client, - build_ids=[build_id], - ) - ) - if issues: - await move_issues( - github_client=github_client, - issues=issues, - status=GitHubIssueStatus.TESTING.value, - ) except Exception as err: logging.exception( "Cannot move issue to the Testing section: %s", diff --git a/alws/crud/errata.py b/alws/crud/errata.py index 488b710f2..d3c9cd173 100644 --- a/alws/crud/errata.py +++ b/alws/crud/errata.py @@ -510,7 +510,8 @@ async def get_matching_albs_packages( errata_package: models.NewErrataPackage, prod_repos_cache, module, -) -> List[models.ErrataToALBSPackage]: +) -> Tuple[List[models.ErrataToALBSPackage], dict]: + package_type = {} items_to_insert = [] # We're going to check packages that match name-version-clean_release # Note that clean_release doesn't include the .module... str, we match: @@ -540,17 +541,24 @@ async def get_matching_albs_packages( errata_package.source_srpm = src_nevra.name items_to_insert.append(mapping) errata_package.albs_packages.append(mapping) - return items_to_insert + package_type["type"] = "prod" + return items_to_insert, package_type # If we couldn't find any pkg in production repos # we'll look for every package that matches name-version # inside the ALBS, this is, build_task_artifacts. name_query = f"{errata_package.name}-{errata_package.version}" - query = select(models.BuildTaskArtifact).where( - and_( - models.BuildTaskArtifact.type == "rpm", - models.BuildTaskArtifact.name.startswith(name_query), + query = ( + select(models.BuildTaskArtifact) + .where( + and_( + models.BuildTaskArtifact.type == "rpm", + models.BuildTaskArtifact.name.startswith(name_query), + ) + ) + .options( + selectinload(models.BuildTaskArtifact.build_task), ) ) # If the errata record references a module, then we'll get @@ -568,7 +576,11 @@ async def get_matching_albs_packages( result = (await db.execute(query)).scalars().all() - pulp_pkg_ids = [get_uuid_from_pulp_href(pkg.href) for pkg in result] + pulp_pkg_ids = [] + build_ids = set() + for pkg in result: + pulp_pkg_ids.append(get_uuid_from_pulp_href(pkg.href)) + build_ids.add(pkg.build_task.build_id) pkg_fields = [ RpmPackage.content_ptr_id, RpmPackage.name, @@ -609,7 +621,11 @@ async def get_matching_albs_packages( items_to_insert.append(mapping) errata_package.albs_packages.append(mapping) errata_record_ids.add(errata_package.errata_record_id) - return items_to_insert + package_type = { + "type": "build", + "build_ids": list(build_ids) + } + return items_to_insert, package_type async def create_errata_record(db: AsyncSession, errata: BaseErrataRecord): @@ -738,6 +754,7 @@ async def create_errata_record(db: AsyncSession, errata: BaseErrataRecord): False, db_errata.module, ) + pkg_types = [] for package in errata.packages: db_package = models.NewErrataPackage( name=package.name, @@ -751,11 +768,11 @@ async def create_errata_record(db: AsyncSession, errata: BaseErrataRecord): db_errata.packages.append(db_package) items_to_insert.append(db_package) # Create ErrataToAlbsPackages - items_to_insert.extend( - await get_matching_albs_packages( - db, db_package, prod_repos_cache, db_errata.module - ) + matching_packages, pkg_type = await get_matching_albs_packages( + db, db_package, prod_repos_cache, db_errata.module ) + pkg_types.append(pkg_type) + items_to_insert.extend(matching_packages) db.add_all(items_to_insert) await db.commit() @@ -774,6 +791,8 @@ async def create_errata_record(db: AsyncSession, errata: BaseErrataRecord): platform_name=platform.name, severity=errata.severity, packages=errata.packages, + platform_id=errata.platform_id, + find_packages_types=pkg_types, ) except Exception as err: logging.exception( @@ -1690,13 +1709,12 @@ async def reset_matched_errata_packages(record_id: str, session: AsyncSession): ) ) for package in record.packages: - items_to_insert.extend( - await get_matching_albs_packages( - session, - package, - prod_repos_cache, - record.module, - ) + matching_packages, _ = await get_matching_albs_packages( + session, + package, + prod_repos_cache, + record.module, ) + items_to_insert.extend(matching_packages) session.add_all(items_to_insert) await session.commit() diff --git a/alws/utils/github_integration_helper.py b/alws/utils/github_integration_helper.py index f16545135..a2af40a21 100644 --- a/alws/utils/github_integration_helper.py +++ b/alws/utils/github_integration_helper.py @@ -4,15 +4,7 @@ from albs_github.graphql.client import IntegrationsGHGraphQLClient from alws.config import settings - -__all__ = [ - 'get_github_client', - 'find_issues_by_record_id', - 'find_issues_by_repo_name', - 'move_issues', - 'create_github_issue', - 'set_build_id_to_issues', -] +from alws.constants import GitHubIssueStatus async def get_github_client() -> IntegrationsGHGraphQLClient: @@ -55,14 +47,17 @@ async def find_issues_by_repo_name( ) -> typing.List[dict]: issue_ids = [] for name in repo_names: - query = f"{name} in:title,body" + query = f"conflict for {name} in:title" issue_ids.extend( await get_github_issue_content_ids(github_client, query) ) issue_ids = set(issue_ids) project_issues = await github_client.get_project_content_issues() filtered_issues = [] - valid_statuses = ["Todo", "In Development"] + valid_statuses = [ + GitHubIssueStatus.TODO.value, + GitHubIssueStatus.DEVELOPMENT.value, + ] for issue_id in list(issue_ids): project_issue = project_issues[issue_id] if project_issue.fields["Status"]["value"] in valid_statuses: @@ -112,33 +107,25 @@ async def set_build_id_to_issues( ): for issue in issues: issue_id = issue["id"] + if "Build URL" in issue["fields"]: + continue + url = urljoin(settings.frontend_baseurl, f"build/{build_id}") await github_client.set_text_field( issue_id=issue_id, field_name="Build URL", field_value=url, ) + comment = f"Build: {build_id}" + await github_client.create_comment(item_id=issue_id, body=comment) -async def move_issues( +async def find_issues( github_client: IntegrationsGHGraphQLClient, - issues: list, - status: str, -): - for issue in issues: - issue_id = issue["id"] - await github_client.set_issue_status( - issue_id=issue_id, - status=status, - ) - - -async def close_issues( record_ids: typing.Optional[typing.List[str]] = None, build_ids: typing.Optional[typing.List[str]] = None, ): issues = [] - github_client = await get_github_client() if record_ids: issues.extend( await find_issues_by_record_id( @@ -153,11 +140,89 @@ async def close_issues( build_ids=build_ids, ) ) + return issues + + +async def move_issue_to_testing( + build_id: str, + record_ids: typing.List[str], +): + github_client = await get_github_client() + issues = await find_issues( + github_client=github_client, + record_ids=record_ids, + build_ids=[build_id], + ) + issues = await filter_issues( + issues=filter_issues, + valid_statuses=[ + GitHubIssueStatus.TODO.value, + GitHubIssueStatus.DEVELOPMENT.value, + GitHubIssueStatus.BUILDING.value, + ], + ) + await set_build_id_to_issues( + github_client=github_client, + issues=issues, + build_id=build_id, + ) + await move_issues( + github_client=github_client, + issues=issues, + status=GitHubIssueStatus.TESTING.value, + ) + + +async def filter_issues( + issues: list, + valid_statuses: typing.Optional[list] = None, + platform: typing.Optional[str] = None, +): + filtered = [] + for issue in issues: + condition = [] + if valid_statuses: + condition.append( + issue["fields"]["Status"]["value"] in valid_statuses + ) + if platform: + condition.append(issue["fields"]["Platform"]["value"] == platform) + if all(condition): + filtered.append(issue) + return filtered + + +async def move_issues( + github_client: IntegrationsGHGraphQLClient, + issues: list, + status: str, +): + for issue in issues: + issue_id = issue["id"] + await github_client.set_issue_status( + issue_id=issue_id, + status=status, + ) + + +async def close_issues( + record_ids: typing.Optional[typing.List[str]] = None, + build_ids: typing.Optional[typing.List[str]] = None, +): + issues = [] + github_client = await get_github_client() + issues = await find_issues( + github_client=github_client, + record_ids=record_ids, + build_ids=build_ids, + ) for issue in issues: issue_id = issue["content"]["id"] await github_client.close_issue( issue_id=issue_id, ) + comment = f"{record_ids} is released" + await github_client.create_comment(item_id=issue_id, body=comment) async def get_github_issue_content_ids( @@ -182,6 +247,8 @@ async def create_github_issue( platform_name: str, severity: str, packages: list, + platform_id: str, + find_packages_types: typing.Optional[list] = None, ): packages_section = "\n".join( (f"{p.name}-{p.version}-{p.release}.{p.arch}" for p in packages) @@ -198,5 +265,43 @@ async def create_github_issue( issue_title, issue_body ) await client.set_issue_platform(project_item_id, platform_name) + errata_url = urljoin( + settings.frontend_baseurl, + f"/errata?id={advisory_id}&platform_id={platform_id}", + ) + await client.set_text_field( + issue_id=project_item_id, + field_name="Errata URL", + field_value=errata_url, + ) await client.set_text_field(project_item_id, 'Upstream ID', original_id) await client.set_text_field(project_item_id, 'AlmaLinux ID', advisory_id) + comment = f"Errata created in ALBS: {errata_url}" + await client.create_comment(item_id=issue_id, body=comment) + if not find_packages_types: + comment = "Can not find packages in any repos" + await client.create_comment(item_id=issue_id, body=comment) + return + + comments = set() + build_ids = set() + for pack in find_packages_types: + if pack["type"] == "build": + for build_id in pack["build_ids"]: + build_ids.add(build_id) + else: + comments.add("Find packages in prod repos") + for build_id in build_ids: + await client.set_text_field( + issue_id=project_item_id, + field_name="Build URL", + field_value=url, + ) + url = urljoin(settings.frontend_baseurl, f"build/{build_id}") + comments.add(f"Find packages in Build: {url}") + for comment in comments: + await client.create_comment(item_id=issue_id, body=comment) + await client.set_issue_status( + issue_id=issue_id, + status=GitHubIssueStatus.TESTING.value, + )