@@ -258,34 +258,95 @@ def user_can_push(gh, org, repo, username, addons_dir, target_branch):
258258 if result :
259259 return True
260260
261- other_branches = config .MAINTAINER_CHECK_ODOO_RELEASES
261+ other_branches = list ( config .MAINTAINER_CHECK_ODOO_RELEASES )
262262 if target_branch in other_branches :
263263 other_branches .remove (target_branch )
264264
265265 return is_maintainer_other_branches (
266- org , repo , username , modified_addons , other_branches
266+ org , repo , username , modified_addons , other_branches , gh = gh
267267 )
268268
269269
270- def is_maintainer_other_branches (org , repo , username , modified_addons , other_branches ):
270+ def _get_manifest_from_api (gh_repo , addon , branch , manifest_file ):
271+ """Read an addon manifest from a GitHub branch using the authenticated API.
272+
273+ Returns the parsed manifest dict, or None if the file does not exist or
274+ cannot be read.
275+ """
276+ path = f"{ addon } /{ manifest_file } "
277+ try :
278+ file_contents = gh_repo .file_contents (path , ref = branch )
279+ except Exception as e :
280+ _logger .debug ("Could not read %s@%s via GitHub API: %s" , path , branch , e )
281+ return None
282+ if file_contents is None :
283+ return None
284+ try :
285+ return parse_manifest (file_contents .content )
286+ except Exception as e :
287+ _logger .warning (
288+ "Failed to parse manifest %s@%s from GitHub API: %s" , path , branch , e
289+ )
290+ return None
291+
292+
293+ def _get_manifest_from_raw (org , repo , addon , branch , manifest_file ):
294+ """Fallback to read an addon manifest from github raw URLs.
295+
296+ Returns the parsed manifest dict, or None if the file does not exist or
297+ cannot be read.
298+ """
299+ url = f"https://github.com/{ org } /{ repo } /raw/{ branch } /{ addon } /{ manifest_file } "
300+ _logger .debug ("Looking for maintainers in %s" , url )
301+ try :
302+ r = requests .get (
303+ url , allow_redirects = True , headers = {"Cache-Control" : "no-cache" }
304+ )
305+ except requests .RequestException as e :
306+ _logger .warning ("Failed to fetch %s: %s" , url , e )
307+ return None
308+ if not r .ok :
309+ return None
310+ try :
311+ return parse_manifest (r .content )
312+ except Exception as e :
313+ _logger .warning ("Failed to parse manifest from %s: %s" , url , e )
314+ return None
315+
316+
317+ def is_maintainer_other_branches (
318+ org , repo , username , modified_addons , other_branches , gh = None
319+ ):
320+ """Check if username is maintainer of modified_addons in any configured branch.
321+
322+ When an authenticated GitHub session is available, the GitHub contents API
323+ is used instead of unauthenticated raw.githubusercontent.com requests. This
324+ avoids rate-limiting and transient network errors that could spuriously deny
325+ maintainer privileges during migrations.
326+ """
327+ gh_repo = None
328+ if gh is not None :
329+ try :
330+ gh_repo = gh .repository (org , repo )
331+ except Exception as e :
332+ _logger .warning ("Could not get repository %s/%s from API: %s" , org , repo , e )
333+
271334 for addon in modified_addons :
272335 is_maintainer = False
273336 for branch in other_branches :
274337 manifest_file = (
275338 "__openerp__.py" if float (branch ) < 10.0 else "__manifest__.py"
276339 )
277- url = (
278- f"https://github.com/{ org } /{ repo } /raw/{ branch } /{ addon } /{ manifest_file } "
279- )
280- _logger .debug ("Looking for maintainers in %s" , url )
281- r = requests .get (
282- url , allow_redirects = True , headers = {"Cache-Control" : "no-cache" }
283- )
284- if r .ok :
285- manifest = parse_manifest (r .content )
286- if username in manifest .get ("maintainers" , []):
287- is_maintainer = True
288- break
340+ manifest = None
341+ if gh_repo is not None :
342+ manifest = _get_manifest_from_api (gh_repo , addon , branch , manifest_file )
343+ if manifest is None :
344+ manifest = _get_manifest_from_raw (
345+ org , repo , addon , branch , manifest_file
346+ )
347+ if manifest and username in manifest .get ("maintainers" , []):
348+ is_maintainer = True
349+ break
289350
290351 if not is_maintainer :
291352 return False
0 commit comments