-
Notifications
You must be signed in to change notification settings - Fork 9
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
softwarefactory-project-zuul
merged 8 commits into
packit:main
from
mfocko:feat/process-anitya
Oct 18, 2023
Merged
Pass Anitya #91
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
eb69710
ci: add ruff
mfocko 60244d1
docs: use google-style convention in docstrings
mfocko fdfa0ee
fix: factor out utils
mfocko c0cd70c
fix: factor out callbacks to separate module
mfocko 9c8a76e
feat: pass Anitya to Service
mfocko 4dfeac1
fix: use cached property
mfocko d9e86cf
fix: get package name for unmapped
mfocko da21b17
docs: reword the warning about topic subscriptions
mfocko File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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") | ||
|
||
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, | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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 versionsstable_versions
: duh…versions
: all versions (including stable, newly detected and prereleases; literally all)old_version
(not relevant, but worth mentioning): latest fromversion
, CAN be prereleaseI think we'll need to adjust this in the Service…
There was a problem hiding this comment.
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!
👍