Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass Anitya #91

Merged
merged 8 commits into from
Oct 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,6 @@ repos:
- id: detect-private-key
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/PyCQA/flake8
rev: 6.1.0
hooks:
- id: flake8
args:
- --max-line-length=100
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.5.1
hooks:
Expand All @@ -40,3 +34,9 @@ repos:
args:
- https://github.com/packit/packit-service-fedmsg.git
stages: [manual, push]
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.0.291
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
178 changes: 178 additions & 0 deletions packit_service_fedmsg/callbacks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# Copyright Contributors to the Packit project.
# SPDX-License-Identifier: MIT

from dataclasses import dataclass
from os import getenv
from typing import Callable

from packit_service_fedmsg.utils import nested_get, specfile_changed


@dataclass
class CallbackResult:
"""
Represents the result of the callback on the Fedora Messaging event.

Attributes:
msg: Message to be logged in the Fedora Messaging listener.
pass_to_service: Boolean value that represents whether the event should
be passed to the worker for further processing or not.

Defaults to `True`.
"""

msg: str
pass_to_service: bool = True


def get_callback(topic: str) -> Callable[[str, dict, str], CallbackResult]:
return MAPPING.get(topic, _dummy)


def _dummy(topic: str, event: dict, packit_user: str) -> CallbackResult:
return CallbackResult(
msg=f"[IGNORE] Unknown message of topic '{topic}'",
pass_to_service=False,
)


def _copr(topic: str, event: dict, packit_user: str) -> CallbackResult:
if event.get("user") != packit_user:
return CallbackResult(
msg=f"[Copr] Copr build is not managed by Packit (`{packit_user}`) user.",
pass_to_service=False,
)

return CallbackResult(msg=f"[Copr] {event.get('what')}")


def _koji(topic: str, event: dict, packit_user: str) -> CallbackResult:
# TODO: accept builds run by other owners as well
# (For the `bodhi_update` job.)
if event.get("owner") != packit_user:
return CallbackResult(
msg=f"[Koji] Koji build not built by {packit_user}.",
pass_to_service=False,
)

if "buildsys.build.state" in topic:
what = (
f"[Koji] build:{event.get('build_id')} task:{event.get('task_id')}"
f" {event.get('old')}->{event.get('new')}"
)

# SAFETY: It's either ‹build.state› or ‹task.state›, as they are the topics
# handled by this callback, therefore ‹what› **will** be declared one way or
# another.
if "buildsys.task.state" in topic: # scratch build
what = f"[Koji] id:{event.get('id')} {event.get('old')}->{event.get('new')}"

return CallbackResult(msg=what)


def _fedora_dg_push(topic: str, event: dict, packit_user: str) -> CallbackResult:
if getenv("PROJECT", "").startswith("packit") and not specfile_changed(
event,
):
return CallbackResult(
msg="[Fedora DG] No specfile change, ignoring the push.",
pass_to_service=False,
)

if commit := event.get("commit"):
what = f"{commit.get('repo')} {commit.get('rev')}@{commit.get('branch')}"
else:
what = "Couldn't get commit out of the event."

return CallbackResult(msg=f"[Fedora DG] Passing push: {what}")


def _fedora_dg_pr_flag(topic: str, event: dict, packit_user: str) -> CallbackResult:
if nested_get(event, "pullrequest", "user", "name") != packit_user:
return CallbackResult(
msg=f"[Fedora DG] Flag changed in a PR not created by {packit_user}, ignoring.",
pass_to_service=False,
)

return CallbackResult(
msg=(
"[Fedora DG] Flag on "
f"{nested_get(event, 'pullrequest', 'project', 'fullname')}"
f" changed to '{nested_get(event, 'flag', 'comment')}'"
),
)


def _fedora_dg_pr_comment(topic: str, event: dict, packit_user: str) -> CallbackResult:
project = nested_get(event, "pullrequest", "project", "fullname")
comments = nested_get(event, "pullrequest", "comments")
last_comment = comments[-1]
return CallbackResult(
msg=(
f"[Fedora DG] For {project}"
f" new comment: '{last_comment['comment']}'"
f" from {last_comment['user']['name']}"
),
)


def _fedora_dg_pr_closed(topic: str, event: dict, packit_user: str) -> CallbackResult:
project = nested_get(event, "pullrequest", "project", "fullname")

if not nested_get(event, "pullrequest", "merged"):
return CallbackResult(
msg=f"[Fedora DG] Pull request in {project} was closed, ignoring.",
pass_to_service=False,
)

return CallbackResult(
msg=f"[Fedora DG] Merged pull request in {project}.",
)


def _hotness_bugzilla(topic: str, event: dict, packit_user: str) -> CallbackResult:
package = event.get("package")
version = nested_get(event, "trigger", "msg", "project", "version")

return CallbackResult(
msg=f"[Hotness] New update of package {package} to version {version}.",
)


def _anitya_version_update(topic: str, event: dict, packit_user: str) -> CallbackResult:
package = None
for p in nested_get(event, "message", "packages"):
if p.get("distro") == "CentOS":
package = p.get("package_name")
break

if package is None:
project = nested_get(event, "project", "name")
return CallbackResult(
msg=f"[Anitya] CentOS mapping is not configured for {project}, ignoring.",
pass_to_service=False,
)

new_versions = nested_get(event, "message", "project", "upstream_versions")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how will this work if there are multiple new versions? Could you point me to the docs explaining these, e.g. "upstream_versions" vs "version" (and maybe add a comment with this link please)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good question, open for discussion IMO 😂 docs

I think this applies mainly to the upstreams that keep multiple running branches (like kernel, maybe Java (? even though they have separate RPM packages for that)).

OTOH this is something that I can see used with CentOS specifically, because if there are multiple major/minor releases maintained, user should be able to specify some tag filtering in sense of “I want to follow this branch instead of the latest one”.

Given this example, these are the relevant fields:

  • upstream_versions: which are apparently the newly detected versions
  • stable_versions: duh…
  • versions: all versions (including stable, newly detected and prereleases; literally all)
  • old_version (not relevant, but worth mentioning): latest from version, CAN be prerelease

I think we'll need to adjust this in the Service…

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, got it, thanks for the explanation!

I think we'll need to adjust this in the Service

👍


return CallbackResult(
msg=f"[Anitya] New versions of package {package}: '{', '.join(new_versions)}'",
)


# [WARNING]
# Configuration of the topics to listen to needs to be changed in
# a respective fedora.toml.j2 (https://github.com/packit/deployment/tree/main/secrets)
MAPPING = {
"org.fedoraproject.prod.copr.build.end": _copr,
"org.fedoraproject.prod.copr.build.start": _copr,
"org.fedoraproject.prod.buildsys.task.state.change": _koji,
"org.fedoraproject.prod.buildsys.build.state.change": _koji,
"org.fedoraproject.prod.git.receive": _fedora_dg_push,
"org.fedoraproject.prod.pagure.pull-request.flag.added": _fedora_dg_pr_flag,
"org.fedoraproject.prod.pagure.pull-request.flag.updated": _fedora_dg_pr_flag,
"org.fedoraproject.prod.pagure.pull-request.comment.added": _fedora_dg_pr_comment,
"org.fedoraproject.prod.pagure.pull-request.closed": _fedora_dg_pr_closed,
"org.fedoraproject.prod.hotness.update.bug.file": _hotness_bugzilla,
"org.release-monitoring.prod.anitya.project.version.update.v2": _anitya_version_update,
}
Loading