2121import datetime
2222import logging
2323
24- from typing import Any , Callable , DefaultDict , Dict , List , Optional , Tuple , Union
24+ from typing import Any , Callable , DefaultDict , Dict , List , Optional , Union
2525from dateutil import parser
2626import requests
2727from src import github_domain
@@ -203,18 +203,51 @@ def get_pull_request_dict_with_timestamp(
203203 assignee ['created_at' ] = parser .parse (event ['created_at' ])
204204 return pr_dict
205205
206-
207206@check_token
208- def _get_discussion_data (
207+ def _get_repository_id (
209208 org_name : str ,
210209 repo_name : str ,
211- discussion_category : str ,
212- discussion_title : str ,
213- ) -> Tuple [str , int ]:
214- """Fetch discussion data from api and return corresponding discussion id and
215- discussion number.
210+ ) -> str :
211+ """Fetch repository id from given org and repo and return the id."""
212+
213+ query = """
214+ query ($org_name: String!, $repository: String!) {
215+ repository(owner: $org_name, name: $repository) {
216+ id
217+ }
218+ }
216219 """
217220
221+ variables = {
222+ 'org_name' : org_name ,
223+ 'repository' : repo_name
224+ }
225+
226+ response = requests .post (
227+ GITHUB_GRAPHQL_URL ,
228+ json = {'query' : query , 'variables' : variables },
229+ headers = _get_request_headers (),
230+ timeout = TIMEOUT_SECS
231+ )
232+ data = response .json ()
233+
234+ repository_id : str = (
235+ data ['data' ]['repository' ]['id' ])
236+
237+ if repository_id is None :
238+ raise builtins .BaseException (
239+ f'{ org_name } /{ repo_name } doesn\' t exist.' )
240+
241+ return repository_id
242+
243+ @check_token
244+ def _get_category_id (
245+ org_name : str ,
246+ repo_name : str ,
247+ discussion_category : str
248+ ) -> str :
249+ """Fetch discussion category id from given category name and return the id."""
250+
218251 # The following query is written in GraphQL and is being used to fetch the category
219252 # ids and titles from the GitHub discussions. To learn more, check this out
220253 # https://docs.github.com/en/graphql.
@@ -244,7 +277,7 @@ def _get_discussion_data(
244277 )
245278 data = response .json ()
246279
247- category_id = None
280+ category_id : Optional [ str ] = None
248281 discussion_categories = (
249282 data ['data' ]['repository' ]['discussionCategories' ]['nodes' ])
250283
@@ -257,6 +290,21 @@ def _get_discussion_data(
257290 raise builtins .BaseException (
258291 f'{ discussion_category } category is missing in GitHub Discussion.' )
259292
293+ assert category_id is not None
294+ return category_id
295+
296+ @check_token
297+ def _get_discussion_ids (
298+ org_name : str ,
299+ repo_name : str ,
300+ discussion_category : str ,
301+ ) -> List [str ]:
302+ """Fetch discussion data from api and return corresponding discussion id and
303+ discussion number.
304+ """
305+
306+ category_id = _get_category_id (org_name , repo_name , discussion_category )
307+
260308 # The following query is written in GraphQL and is being used to fetch discussions
261309 # from a particular GitHub discussion category. This helps to find out the discussion
262310 # where we want to comment. To learn more, check this out
@@ -289,62 +337,34 @@ def _get_discussion_data(
289337 timeout = TIMEOUT_SECS
290338 )
291339 data = response .json ()
292- discussion_id = None
293340
294341 discussions = data ['data' ]['repository' ]['discussions' ]['nodes' ]
342+ discussion_ids = [
343+ discussion ['id' ] for discussion in discussions if discussion ['id' ] is not None
344+ ]
295345
296- for discussion in discussions :
297- if discussion ['title' ] == discussion_title :
298- discussion_id = discussion ['id' ]
299- discussion_number = discussion ['number' ]
300- break
301346
302- if discussion_id is None :
303- raise builtins .BaseException (
304- f'Discussion with title { discussion_title } not found, please create a '
305- 'discussion with that title.' )
306-
307- return discussion_id , discussion_number
308-
309-
310- def _get_past_time (days : int = 60 ) -> str :
311- """Returns the subtraction of current time and the arg passed in days."""
312- return (
313- datetime .datetime .now (
314- datetime .timezone .utc ) - datetime .timedelta (days = days )).strftime (
315- '%Y-%m-%dT%H:%M:%SZ' )
347+ if not discussion_ids :
348+ logging .info ('No existing discussions found' )
316349
350+ return discussion_ids
317351
318- def _get_old_comment_ids (
319- org_name : str ,
320- repo_name : str ,
321- discussion_number : int
322- ) -> List [str ]:
323- """Return the old comment ids."""
352+ def _delete_discussion (discussion_id : str ) -> None :
353+ """Delete the GitHub Discussion comment related to the comment id."""
324354
325- # The following query is written in GraphQL and is being used to fetch the oldest 50
326- # comments in a existing GitHub discussions. Assuming that, this workflow will run
327- # twice every week, we will may not have more than 50 comments to delete. To learn
328- # more, check this out https://docs.github.com/en/graphql.
329355 query = """
330- query ($org_name: String!, $repository: String!, $discussion_number: Int!) {
331- repository(owner: $org_name, name: $repository) {
332- discussion(number: $discussion_number) {
333- comments(first: 50) {
334- nodes {
335- id
336- createdAt
337- }
338- }
356+ mutation deleteDiscussion($discussion_id: ID!) {
357+ deleteDiscussion(input: {id: $discussion_id}) {
358+ clientMutationId,
359+ discussion {
360+ title
339361 }
340362 }
341363 }
342364 """
343365
344366 variables = {
345- 'org_name' : org_name ,
346- 'repository' : repo_name ,
347- 'discussion_number' : discussion_number
367+ 'discussion_id' : discussion_id
348368 }
349369
350370 response = requests .post (
@@ -353,76 +373,50 @@ def _get_old_comment_ids(
353373 headers = _get_request_headers (),
354374 timeout = TIMEOUT_SECS
355375 )
356-
357376 response .raise_for_status ()
358- data = response .json ()
359-
360- comment_ids : List [str ] = []
361-
362- discussion_comments = (
363- data ['data' ]['repository' ]['discussion' ]['comments' ]['nodes' ]
364- )
365-
366- # Delete comments posted before this time.
367- delete_comments_before_in_days = _get_past_time (DELETE_COMMENTS_BEFORE_IN_DAYS )
368-
369- for comment in discussion_comments :
370- if comment ['createdAt' ] < delete_comments_before_in_days :
371- comment_ids .append (comment ['id' ])
372- else :
373- break
374-
375- return comment_ids
376377
377378
378- def _delete_comment (comment_id : str ) -> None :
379- """Delete the GitHub Discussion comment related to the comment id."""
380-
381- query = """
382- mutation deleteComment($comment_id: ID!) {
383- deleteDiscussionComment(input: {id: $comment_id}) {
384- clientMutationId
385- comment {
386- bodyText
387- }
388- }
389- }
390- """
391-
392- variables = {
393- 'comment_id' : comment_id
394- }
379+ @check_token
380+ def delete_discussions (
381+ org_name : str ,
382+ repo_name : str ,
383+ discussion_category : str ,
384+ ) -> None :
385+ """Delete all existing discussions in the given discussion category."""
395386
396- response = requests .post (
397- GITHUB_GRAPHQL_URL ,
398- json = {'query' : query , 'variables' : variables },
399- headers = _get_request_headers (),
400- timeout = TIMEOUT_SECS
401- )
402- response .raise_for_status ()
387+ discussion_ids = _get_discussion_ids (
388+ org_name , repo_name , discussion_category )
403389
390+ for discussion_id in discussion_ids :
391+ _delete_discussion (discussion_id )
404392
405- def _post_comment (discussion_id : str , message : str ) -> None :
406- """Post the given message in an existing discussion."""
393+ @check_token
394+ def create_discussion (
395+ org_name : str ,
396+ repo_name : str ,
397+ discussion_category : str ,
398+ discussion_title : str ,
399+ discussion_body : str
400+ ) -> None :
401+ """Create a new discussion with the given title and body in the given discussion category."""
407402
408- # The following code is written in GraphQL and is being used to perform a mutation
409- # operation. More specifically, we are using it to comment in GitHub discussion to
410- # let reviewers know about some of their pending tasks. To learn more, check this out:
411- # https://docs.github.com/en/graphql.
403+ category_id = _get_category_id (org_name , repo_name , discussion_category )
404+ repo_id = _get_repository_id (org_name , repo_name )
412405 query = """
413- mutation post_comment($discussion_id: ID!, $comment: String!) {
414- addDiscussionComment(input: {discussionId: $discussion_id, body: $comment}) {
415- clientMutationId
416- comment {
406+ mutation createDiscussion($repo_id: ID!, $category_id: ID!, $title: String!, $body: String!) {
407+ createDiscussion(input: {repositoryId: $repo_id, categoryId: $category_id, title: $title, body: $body}) {
408+ discussion {
417409 id
418410 }
419411 }
420412 }
421413 """
422414
423415 variables = {
424- 'discussion_id' : discussion_id ,
425- 'comment' : message
416+ 'repo_id' : repo_id ,
417+ 'category_id' : category_id ,
418+ 'title' : discussion_title ,
419+ 'body' : discussion_body
426420 }
427421
428422 response = requests .post (
@@ -431,38 +425,5 @@ def _post_comment(discussion_id: str, message: str) -> None:
431425 headers = _get_request_headers (),
432426 timeout = TIMEOUT_SECS
433427 )
434- response .raise_for_status ()
435-
436428
437- @check_token
438- def delete_discussion_comments (
439- org_name : str ,
440- repo_name : str ,
441- discussion_category : str ,
442- discussion_title : str
443- ) -> None :
444- """Delete old comments from GitHub Discussion."""
445-
446- _ , discussion_number = _get_discussion_data (
447- org_name , repo_name , discussion_category , discussion_title )
448-
449- comment_ids = _get_old_comment_ids (org_name , repo_name , discussion_number )
450-
451- for comment_id in comment_ids :
452- _delete_comment (comment_id )
453-
454-
455- @check_token
456- def add_discussion_comments (
457- org_name : str ,
458- repo_name : str ,
459- discussion_category : str ,
460- discussion_title : str ,
461- message : str
462- ) -> None :
463- """Add comments in an existing GitHub discussion."""
464-
465- discussion_id , _ = _get_discussion_data (
466- org_name , repo_name , discussion_category , discussion_title )
467-
468- _post_comment (discussion_id , message )
429+ response .raise_for_status ()
0 commit comments