Skip to content

Commit

Permalink
Feat/centos anitya (#2348)
Browse files Browse the repository at this point in the history
Feat/centos anitya

Add an event class
 Implement a parser
 Pass around versions in a list (for New Hotness we can have just one version in the list, for Anitya version update fail)
 Do not generate DB entry from the event
 ⚠️ Choosing the correct version

Outcomes from the arch:

Gather more use cases
Require the explicit setting for version mask (for CentOS at least)




 ⚠️ Decide whether to support Fedora for Anitya version update too… right now it's prefiltered for the CentOS

Related to #2068

Reviewed-by: Matej Focko
Reviewed-by: Laura Barcziová
  • Loading branch information
softwarefactory-project-zuul[bot] committed Mar 13, 2024
2 parents 276e736 + 163591f commit 623c117
Show file tree
Hide file tree
Showing 12 changed files with 8,596 additions and 1,943 deletions.
98 changes: 79 additions & 19 deletions packit_service/worker/events/new_hotness.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Copyright Contributors to the Packit project.
# SPDX-License-Identifier: MIT

from abc import abstractmethod
from functools import cached_property
from logging import getLogger
from typing import Optional, Dict

Expand All @@ -15,34 +18,34 @@
logger = getLogger(__name__)


# the decorator is needed in case the DB project event is not created (not valid arguments)
# but we still want to report from pre_check of the PullFromUpstreamHandler
@use_for_job_config_trigger(trigger_type=JobConfigTriggerType.release)
class NewHotnessUpdateEvent(Event):
class AnityaUpdateEvent(Event):
def __init__(
self,
package_name: str,
version: str,
distgit_project_url: str,
bug_id: int,
release_monitoring_project_id: int,
):
super().__init__()

self.package_name = package_name
self.version = version
self.distgit_project_url = distgit_project_url
self.bug_id = bug_id
self.release_monitoring_project_id = release_monitoring_project_id

self._repo_url: Optional[RepoUrl] = None
self._db_project_object: Optional[ProjectReleaseModel]
self._db_project_event: Optional[ProjectEventModel]
self._db_project_object: Optional[ProjectReleaseModel] = None
self._db_project_event: Optional[ProjectEventModel] = None

self._package_config_searched = False
self._package_config: Optional[PackageConfig] = None

@property
def project(self):
if not self._project:
self._project = self.get_project()
return self._project
@abstractmethod
def version(self) -> str:
...

@cached_property
def project(self) -> Optional[GitProject]:
return self.get_project()

def get_project(self) -> Optional[GitProject]:
if not self.distgit_project_url:
Expand Down Expand Up @@ -118,11 +121,9 @@ def project_url(self) -> Optional[str]:
self.packages_config.upstream_project_url if self.packages_config else None
)

@property
@cached_property
def repo_url(self) -> Optional[RepoUrl]:
if not self._repo_url:
self._repo_url = RepoUrl.parse(self.project_url)
return self._repo_url
return RepoUrl.parse(self.project_url)

@property
def repo_namespace(self) -> Optional[str]:
Expand All @@ -145,6 +146,65 @@ def get_dict(self, default_dict: Optional[Dict] = None) -> dict:
d["tag_name"] = self.tag_name
d["repo_name"] = self.repo_name
d["repo_namespace"] = self.repo_namespace
d["version"] = self.version
result = super().get_dict(d)
result.pop("_repo_url")
result.pop("project")
result.pop("repo_url")
return result


# the decorator is needed in case the DB project event is not created (not valid arguments)
# but we still want to report from pre_check of the PullFromUpstreamHandler
@use_for_job_config_trigger(trigger_type=JobConfigTriggerType.release)
class NewHotnessUpdateEvent(AnityaUpdateEvent):
def __init__(
self,
package_name: str,
version: str,
distgit_project_url: str,
bug_id: int,
release_monitoring_project_id: int,
):
super().__init__(
package_name=package_name,
distgit_project_url=distgit_project_url,
release_monitoring_project_id=release_monitoring_project_id,
)
self._version = version
self.bug_id = bug_id

@property
def version(self) -> str:
return self._version


# TODO: Uncomment once it is possible to deduce the version for the sync-release
# action.
# @use_for_job_config_trigger(trigger_type=JobConfigTriggerType.release)
class AnityaVersionUpdateEvent(AnityaUpdateEvent):
def __init__(
self,
package_name: str,
versions: list[str],
distgit_project_url: str,
release_monitoring_project_id: int,
):
super().__init__(
package_name=package_name,
distgit_project_url=distgit_project_url,
release_monitoring_project_id=release_monitoring_project_id,
)

self._versions = versions

@property
def version(self) -> str:
# TODO: Handle here or further down the chain? we should be able to get
# the package config from dist-git and resolve the next version; how are
# we going to choose the version?
# a) latest greatest
# b) next unreleased?
# this can be also influenced by the mask…
#
# It would be ideal to handle here because of the serialization…
raise NotImplementedError()
39 changes: 38 additions & 1 deletion packit_service/worker/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@
PullRequestCommentAction,
)
from packit_service.worker.events.koji import KojiBuildEvent
from packit_service.worker.events.new_hotness import NewHotnessUpdateEvent
from packit_service.worker.events.new_hotness import (
AnityaVersionUpdateEvent,
NewHotnessUpdateEvent,
)
from packit_service.worker.events.pagure import PullRequestFlagPagureEvent
from packit_service.worker.handlers.abstract import MAP_CHECK_PREFIX_TO_HANDLER
from packit_service.worker.helpers.build import CoprBuildJobHelper, KojiBuildJobHelper
Expand Down Expand Up @@ -1570,6 +1573,37 @@ def parse_new_hotness_update_event(event) -> Optional[NewHotnessUpdateEvent]:
release_monitoring_project_id=release_monitoring_project_id,
)

@staticmethod
def parse_anitya_version_update_event(event) -> Optional[AnityaVersionUpdateEvent]:
if "anitya.project.version.update.v2" not in event.get("topic", ""):
return None

# FIXME: Handle Fedora too in case we want to support multiple releases
# such as for Go.
package_name = next(
package["package_name"]
for package in event["message"]["packages"]
if package["distro"] == "CentOS"
)
distgit_project_url = DISTGIT_INSTANCES["centpkg"].distgit_project_url(
package_name
)

# ‹upstream_versions› contain the new releases
versions = nested_get(event, "message", "upstream_versions")

release_monitoring_project_id = nested_get(event, "message", "project", "id")

logger.info(
f"Anitya version update event for package: {package_name}, versions: {versions}"
)
return AnityaVersionUpdateEvent(
package_name=package_name,
versions=versions,
distgit_project_url=distgit_project_url,
release_monitoring_project_id=release_monitoring_project_id,
)

# The .__func__ are needed for Python < 3.10
MAPPING = {
"github": {
Expand Down Expand Up @@ -1599,6 +1633,9 @@ def parse_new_hotness_update_event(event) -> Optional[NewHotnessUpdateEvent]:
"buildsys.task.state.change": parse_koji_task_event.__func__, # type: ignore
"buildsys.build.state.change": parse_koji_build_event.__func__, # type: ignore
"hotness.update.bug.file": parse_new_hotness_update_event.__func__, # type: ignore
"org.release-monitoring.prod.anitya.project.version.update.v2": (
parse_anitya_version_update_event.__func__ # type: ignore
),
},
"testing-farm": {
"results": parse_testing_farm_results_event.__func__, # type: ignore
Expand Down
Loading

0 comments on commit 623c117

Please sign in to comment.