@@ -121,6 +121,66 @@ def add_discussion_comment(discussion_id, body):
121121 )
122122
123123
124+ def find_latest_checkin ():
125+ """Find the most recent Weekly Check-in Discussion."""
126+ owner , name = REPO .split ("/" )
127+ data = graphql (
128+ """
129+ query($owner: String!, $name: String!) {
130+ repository(owner: $owner, name: $name) {
131+ discussions(first: 10, orderBy: {field: CREATED_AT, direction: DESC}) {
132+ nodes {
133+ id
134+ title
135+ }
136+ }
137+ }
138+ }
139+ """ ,
140+ {"owner" : owner , "name" : name },
141+ )
142+ for discussion in data ["repository" ]["discussions" ]["nodes" ]:
143+ if discussion ["title" ].startswith ("Weekly Check-in:" ):
144+ return discussion
145+ return None
146+
147+
148+ def get_discussion_comments (discussion_id ):
149+ """Fetch top-level comments for a Discussion."""
150+ data = graphql (
151+ """
152+ query($id: ID!) {
153+ node(id: $id) {
154+ ... on Discussion {
155+ comments(first: 50) {
156+ nodes {
157+ body
158+ url
159+ }
160+ }
161+ }
162+ }
163+ }
164+ """ ,
165+ {"id" : discussion_id },
166+ )
167+ return data ["node" ]["comments" ]["nodes" ]
168+
169+
170+ def get_previous_thread_links ():
171+ """Map contributors to the previous check-in thread created for them."""
172+ discussion = find_latest_checkin ()
173+ if not discussion :
174+ return {}
175+
176+ links = {}
177+ for comment in get_discussion_comments (discussion ["id" ]):
178+ user = next ((u for u in CONTRIBUTORS if f"@{ u } " in comment ["body" ]), None )
179+ if user :
180+ links [user ] = comment ["url" ]
181+ return links
182+
183+
124184SEARCH_QUERY = """
125185query($q: String!) {
126186 search(query: $q, type: ISSUE, first: 30) {
@@ -293,7 +353,7 @@ def gather_potential_bottlenecks(user, since_date):
293353
294354
295355def format_contributor_comment (
296- user , merged_prs , reviewed_prs , issues_opened , bottlenecks
356+ user , merged_prs , reviewed_prs , issues_opened , bottlenecks , previous_thread_url = None
297357):
298358 """Format the threaded reply for a contributor."""
299359 lines = [f"## { user } " , "" , f"@{ user } " , "" ]
@@ -321,6 +381,16 @@ def format_contributor_comment(
321381 else :
322382 lines .append ("_No activity found._" )
323383
384+ lines .append ("" )
385+ lines .append ("### Last Week" )
386+ if previous_thread_url :
387+ lines .append ("" )
388+ lines .append (
389+ f"Review your previous thread: [Last week's thread]({ previous_thread_url } )"
390+ )
391+ else :
392+ lines .append ("_No previous thread found._" )
393+
324394 if bottlenecks :
325395 lines .append ("" )
326396 lines .append ("_Auto-detected signals:_" )
@@ -333,6 +403,7 @@ def main():
333403 today = datetime .now (timezone .utc )
334404 week_label = today .strftime ("Week of %Y-%m-%d" )
335405 since_date = today - timedelta (days = 7 )
406+ previous_thread_links = get_previous_thread_links ()
336407
337408 dry_run = os .environ .get ("DRY_RUN" )
338409
@@ -342,7 +413,12 @@ def main():
342413 merged_prs , reviewed_prs , issues_opened = gather_activity (user , since_date )
343414 bottlenecks = gather_potential_bottlenecks (user , since_date )
344415 comment_body = format_contributor_comment (
345- user , merged_prs , reviewed_prs , issues_opened , bottlenecks
416+ user ,
417+ merged_prs ,
418+ reviewed_prs ,
419+ issues_opened ,
420+ bottlenecks ,
421+ previous_thread_links .get (user ),
346422 )
347423 comments .append ((user , comment_body ))
348424
0 commit comments