@@ -101,6 +101,48 @@ class Parser:
101101 we need to have method inside the `Parser` class to create objects defined in `event.py`.
102102 """
103103
104+ @staticmethod
105+ def is_forgejo_event (event : dict ) -> bool :
106+ """
107+ Detect if an event is from Forgejo based on platform-specific fields.
108+ Forgejo events have additional fields that GitHub events don't have.
109+ """
110+
111+ # Check for Forgejo-specific fields in user objects
112+ def has_forgejo_user_fields (user_obj ):
113+ if not isinstance (user_obj , dict ):
114+ return False
115+ forgejo_fields = {
116+ "login_name" ,
117+ "source_id" ,
118+ "full_name" ,
119+ "is_admin" ,
120+ "last_login" ,
121+ "created" ,
122+ "restricted" ,
123+ "active" ,
124+ "prohibit_login" ,
125+ "location" ,
126+ "pronouns" ,
127+ "website" ,
128+ "description" ,
129+ "visibility" ,
130+ "followers_count" ,
131+ "following_count" ,
132+ "starred_repos_count" ,
133+ "username" ,
134+ }
135+ return any (field in user_obj for field in forgejo_fields )
136+
137+ return (
138+ has_forgejo_user_fields (event .get ("user" ))
139+ or has_forgejo_user_fields (nested_get (event , "pull_request" , "user" ))
140+ or has_forgejo_user_fields (nested_get (event , "comment" , "user" ))
141+ or has_forgejo_user_fields (nested_get (event , "issue" , "user" ))
142+ or has_forgejo_user_fields (event .get ("pusher" ))
143+ or has_forgejo_user_fields (event .get ("sender" ))
144+ )
145+
104146 @staticmethod
105147 def parse_event (
106148 event : dict ,
@@ -159,6 +201,23 @@ def parse_event(
159201 logger .warning ("No event to process!" )
160202 return None
161203
204+ # Check if this is a Forgejo event and prioritize Forgejo parsers
205+ # We have to prioritize Forgejo events as they are similar in structure
206+ # to github event payloads and hence can accidentally be parsed as
207+ # Github objects.
208+ is_forgejo = Parser .is_forgejo_event (event )
209+
210+ if is_forgejo :
211+ forgejo_parsers = (
212+ Parser .parse_forgejo_push_event ,
213+ Parser .parse_forgejo_pr_event ,
214+ Parser .parse_forgejo_comment_event ,
215+ )
216+ for parser in forgejo_parsers :
217+ forgejo_response = parser (event )
218+ if forgejo_response :
219+ return forgejo_response
220+
162221 for response in (
163222 parser (event )
164223 for parser in (
@@ -191,9 +250,6 @@ def parse_event(
191250 Parser .parse_openscanhub_task_started_event ,
192251 Parser .parse_commit_comment_event ,
193252 Parser .parse_pagure_pull_request_event ,
194- Parser .parse_forgejo_push_event ,
195- Parser .parse_forgejo_pr_event ,
196- Parser .parse_forgejo_comment_event ,
197253 )
198254 ):
199255 if response :
@@ -290,11 +346,6 @@ def parse_pr_event(event) -> Optional[github.pr.Action]:
290346 """Look into the provided event and see if it's one for a new github PR."""
291347 if not event .get ("pull_request" ):
292348 return None
293-
294- # Skip Forgejo events - they should be handled by parse_forgejo_pr_event
295- repository_url = nested_get (event , "repository" , "html_url" ) or ""
296- if "forgejo.org" in repository_url :
297- return None
298349
299350 pr_id = event .get ("number" )
300351 action = event .get ("action" )
@@ -535,11 +586,6 @@ def parse_github_push_event(event) -> Optional[github.push.Commit]:
535586 """
536587 Look into the provided event and see if it's one for a new push to the github branch.
537588 """
538- # Skip Forgejo events - they should be handled by parse_forgejo_push_event
539- repository_url = nested_get (event , "repository" , "html_url" ) or ""
540- if "forgejo.org" in repository_url :
541- return None
542-
543589 raw_ref = event .get ("ref" )
544590 before = event .get ("before" )
545591 pusher = nested_get (event , "pusher" , "name" )
@@ -608,11 +654,6 @@ def parse_pull_request_comment_event(
608654 # but it's needed when called from parse_event().
609655 if not nested_get (event , "issue" , "pull_request" ):
610656 return None
611-
612- # Skip Forgejo events - they should be handled by parse_forgejo_comment_event
613- repository_url = nested_get (event , "repository" , "html_url" ) or ""
614- if "forgejo.org" in repository_url :
615- return None
616657
617658 pr_id = nested_get (event , "issue" , "number" )
618659 action = event .get ("action" )
@@ -665,12 +706,6 @@ def parse_issue_comment_event(event) -> Optional[github.issue.Comment]:
665706 # but it's needed when called from parse_event().
666707 if nested_get (event , "issue" , "pull_request" ):
667708 return None
668-
669- # Skip Forgejo events - they should be handled by parse_forgejo_comment_event
670- repository_url = nested_get (event , "repository" , "html_url" ) or ""
671- if "forgejo.org" in repository_url :
672- return None
673-
674709 issue_id = nested_get (event , "issue" , "number" )
675710 action = event .get ("action" )
676711 if action != "created" or not issue_id :
@@ -1886,7 +1921,7 @@ def parse_forgejo_push_event(event: dict) -> Optional[forgejo.push.Commit]:
18861921 raw_ref = event .get ("ref" )
18871922 before = event .get ("before" )
18881923 after = event .get ("after" )
1889- pusher = nested_get (event , "pusher" , "login" ) or nested_get ( event , "pusher" , "name" )
1924+ pusher = nested_get (event , "pusher" , "login" )
18901925
18911926 if not (raw_ref and after and before and pusher ):
18921927 return None
@@ -1898,7 +1933,6 @@ def parse_forgejo_push_event(event: dict) -> Optional[forgejo.push.Commit]:
18981933 return None
18991934
19001935 # Number of commits introduced by this push
1901- commits = event .get ("commits" ) or []
19021936 num_commits = event .get ("total_commits" )
19031937
19041938 # Strip the ref prefix to get the branch/tag name
@@ -1936,7 +1970,6 @@ def parse_forgejo_pr_event(event: dict) -> Optional[forgejo.pr.Action]:
19361970 Parse Forgejo PR action events, only triggering for relevant actions.
19371971 Supported actions: 'opened', 'reopened', 'synchronize'.
19381972 Skips others like 'closed'.
1939-
19401973 """
19411974 action_str = event .get ("action" )
19421975 # Only trigger for these actions
@@ -2011,9 +2044,13 @@ def parse_forgejo_comment_event(
20112044
20122045 if is_pr :
20132046 # For PR comments, extract repo info from pull_request section
2014- base_repo_namespace = nested_get (event , "pull_request" , "head" , "repo" , "owner" , "login" )
2047+ base_repo_namespace = nested_get (
2048+ event , "pull_request" , "head" , "repo" , "owner" , "login"
2049+ )
20152050 base_repo_name = nested_get (event , "pull_request" , "head" , "repo" , "name" )
2016- target_repo_namespace = nested_get (event , "pull_request" , "base" , "repo" , "owner" , "login" )
2051+ target_repo_namespace = nested_get (
2052+ event , "pull_request" , "base" , "repo" , "owner" , "login"
2053+ )
20172054 else :
20182055 # For issue comments, extract from repository section
20192056 base_repo_namespace = nested_get (event , "repository" , "owner" , "login" )
@@ -2034,10 +2071,12 @@ def parse_forgejo_comment_event(
20342071 return None
20352072
20362073 if is_pr :
2074+ base_ref = nested_get (event , "pull_request" , "head" , "ref" )
2075+ commit_sha = nested_get (event , "pull_request" , "head" , "sha" )
20372076 return forgejo .pr .Comment (
20382077 action = PullRequestCommentAction [action ],
20392078 pr_id = issue_id ,
2040- base_ref = "" ,
2079+ base_ref = base_ref ,
20412080 base_repo_namespace = base_repo_namespace ,
20422081 base_repo_name = base_repo_name ,
20432082 target_repo_namespace = target_repo_namespace ,
@@ -2046,11 +2085,11 @@ def parse_forgejo_comment_event(
20462085 actor = user_login ,
20472086 comment = comment ,
20482087 comment_id = comment_id ,
2049- commit_sha = None ,
2088+ commit_sha = commit_sha ,
20502089 )
20512090 # For issue comments, get the default branch
20522091 default_branch = nested_get (event , "repository" , "default_branch" ) or "main"
2053-
2092+
20542093 return forgejo .issue .Comment (
20552094 action = IssueCommentAction [action ],
20562095 issue_id = issue_id ,
0 commit comments