@@ -176,4 +176,55 @@ def assert_throws(func, exception_class, message=None):
176176 except exception_class :
177177 pass
178178 else :
179- raise AssertionError (message or f"{ func } did not throw { exception_class } " )
179+ raise AssertionError (message or f"{ func } did not throw { exception_class } " )
180+
181+
182+ def fetch_github_node_id (username : str , token : str ) -> str | None :
183+ """Fetch global_node_id for a GitHub username."""
184+ try :
185+ resp = requests .get (
186+ f"https://api.github.com/users/{ username } " ,
187+ headers = {
188+ "Authorization" : f"Bearer { token } " ,
189+ "X-Github-Next-Global-ID" : "1"
190+ }
191+ )
192+ if resp .ok :
193+ return resp .json ().get ('node_id' )
194+ logger .warning (f"Failed to fetch node_id for { username } : { resp .status_code } " )
195+ return None
196+ except Exception as e :
197+ logger .error (f"Error fetching node_id for { username } : { e } " )
198+ return None
199+
200+
201+ def inject_github_node_ids (file : File , token : str ) -> File :
202+ """Inject global_node_id for github and internal_tools if missing."""
203+ if not file .path .startswith ("directory/users/data/" ):
204+ return file
205+
206+ data = yaml .safe_load (file .content )
207+ modified = False
208+
209+ # github.global_node_id
210+ gh_username = data .get ('github' , {}).get ('username' )
211+ if gh_username and not data .get ('github' , {}).get ('global_node_id' ):
212+ node_id = fetch_github_node_id (gh_username , token )
213+ if node_id :
214+ data ['github' ]['global_node_id' ] = node_id
215+ modified = True
216+ logger .info (f"Injected github.global_node_id for { gh_username } " )
217+
218+ # internal_tools.global_node_id
219+ it_username = data .get ('internal_tools' , {}).get ('github_username' )
220+ if it_username and not data .get ('internal_tools' , {}).get ('global_node_id' ):
221+ node_id = fetch_github_node_id (it_username , token )
222+ if node_id :
223+ data ['internal_tools' ]['global_node_id' ] = node_id
224+ modified = True
225+ logger .info (f"Injected internal_tools.global_node_id for { it_username } " )
226+
227+ if modified :
228+ file .content = yaml .dump (data , width = float ('inf' ))
229+
230+ return file
0 commit comments