55import uuid
66from datetime import datetime
77from pathlib import Path
8- from typing import Any
98
109import pfzy
1110from discord import Color , Embed , Interaction , app_commands
1211from discord .app_commands import Range
1312from discord .ext .commands import GroupCog
1413from discord .ui import Button , View
15- from githubkit import GitHub
16- from githubkit .exception import GitHubException , RequestFailed
17- from githubkit .rest import SimpleUser
14+ from githubkit .exception import RequestFailed
1815from more_itertools import consecutive_groups , ilen
1916from Pylette import extract_colors # pyright: ignore[reportUnknownVariableType]
2017from yarl import URL
2724 UserGitHubTokens ,
2825 UserLogin ,
2926)
30- from ghutils .utils .discord .embeds import create_issue_embed , set_embed_author
27+ from ghutils .utils .discord .components import RefreshCommitButton , RefreshIssueButton
28+ from ghutils .utils .discord .embeds import (
29+ create_commit_embed ,
30+ create_issue_embed ,
31+ set_embed_author ,
32+ )
3133from ghutils .utils .discord .references import (
3234 CommitReference ,
3335 IssueReference ,
3436 PRReference ,
3537)
3638from ghutils .utils .discord .transformers import RepositoryOption , UserOption
3739from ghutils .utils .discord .visibility import MessageVisibility , respond_with_visibility
38- from ghutils .utils .github import (
39- CommitCheckState ,
40- RepositoryName ,
41- SmartPaginator ,
42- gh_request ,
43- shorten_sha ,
44- )
40+ from ghutils .utils .github import gh_request
4541from ghutils .utils .l10n import translate_text
46- from ghutils .utils .strings import truncate_str
4742
4843logger = logging .getLogger (__name__ )
4944
@@ -61,10 +56,14 @@ async def issue(
6156 reference : IssueReference ,
6257 visibility : MessageVisibility = "private" ,
6358 ):
59+ async with self .bot .github_app (interaction ) as (github , _ ):
60+ button = await RefreshIssueButton .from_reference (github , reference )
61+
6462 await respond_with_visibility (
6563 interaction ,
6664 visibility ,
6765 embed = create_issue_embed (* reference ),
66+ items = [button ],
6867 )
6968
7069 @app_commands .command ()
@@ -75,10 +74,14 @@ async def pr(
7574 reference : PRReference ,
7675 visibility : MessageVisibility = "private" ,
7776 ):
77+ async with self .bot .github_app (interaction ) as (github , _ ):
78+ button = await RefreshIssueButton .from_reference (github , reference )
79+
7880 await respond_with_visibility (
7981 interaction ,
8082 visibility ,
8183 embed = create_issue_embed (* reference ),
84+ items = [button ],
8285 )
8386
8487 @app_commands .command ()
@@ -89,39 +92,17 @@ async def commit(
8992 reference : CommitReference ,
9093 visibility : MessageVisibility = "private" ,
9194 ):
92- repo , commit = reference
93-
9495 async with self .bot .github_app (interaction ) as (github , _ ):
95- state = await _get_commit_check_state (github , repo , commit .sha )
96-
97- short_sha = shorten_sha (commit .sha )
98-
99- message = commit .commit .message
100- description = None
101- if "\n " in message :
102- message , description = message .split ("\n " , maxsplit = 1 )
103- description = truncate_str (description .strip (), 200 )
96+ embed = await create_commit_embed (github , * reference )
97+ button = await RefreshCommitButton .from_reference (github , reference )
10498
105- embed = Embed (
106- title = truncate_str (f"[{ short_sha } ] { message } " , 256 ),
107- description = description ,
108- url = commit .html_url ,
109- color = state .color ,
110- ).set_footer (
111- text = f"{ repo } @{ short_sha } " ,
99+ await respond_with_visibility (
100+ interaction ,
101+ visibility ,
102+ embed = embed ,
103+ items = [button ],
112104 )
113105
114- if (author := commit .commit .author ) and author .date :
115- try :
116- embed .timestamp = datetime .fromisoformat (author .date )
117- except ValueError :
118- pass
119-
120- if isinstance (commit .author , SimpleUser ):
121- set_embed_author (embed , commit .author )
122-
123- await respond_with_visibility (interaction , visibility , embed = embed )
124-
125106 @app_commands .command ()
126107 async def repo (
127108 self ,
@@ -476,72 +457,3 @@ def _discord_date(timestamp: int | float | datetime):
476457 case datetime ():
477458 timestamp = int (timestamp .timestamp ())
478459 return f"<t:{ timestamp } :f> (<t:{ timestamp } :R>)"
479-
480-
481- # we need to look at both checks and commit statuses
482- # https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/about-status-checks#types-of-status-checks-on-github
483- # if anything is in progress, return PENDING
484- # else if anything failed, return FAILURE
485- # else if anything succeeded, return SUCCESS
486- # else return PENDING
487- async def _get_commit_check_state (
488- github : GitHub [Any ],
489- repo : RepositoryName ,
490- sha : str ,
491- ) -> CommitCheckState :
492- state = CommitCheckState .NEUTRAL
493-
494- # checks
495- try :
496- async for suite in SmartPaginator (
497- github .rest .checks .async_list_suites_for_ref ,
498- owner = repo .owner ,
499- repo = repo .repo ,
500- ref = sha ,
501- map_func = lambda resp : resp .parsed_data .check_suites ,
502- limit_func = lambda resp : resp .parsed_data .total_count ,
503- ):
504- match suite .status :
505- case "queued" :
506- # this is the default status
507- # it seems to show up for suites that aren't actually in the UI
508- # so just ignore it
509- pass
510- case "completed" :
511- match suite .conclusion :
512- case "success" :
513- if state is not CommitCheckState .FAILURE :
514- state = CommitCheckState .SUCCESS
515- case "failure" | "timed_out" | "startup_failure" :
516- state = CommitCheckState .FAILURE
517- case _:
518- pass
519- case _:
520- return CommitCheckState .PENDING
521- except GitHubException :
522- pass
523-
524- if state is CommitCheckState .FAILURE :
525- return state
526-
527- # commit statuses
528- # if we get to this point, either all checks passed or there are no checks
529- try :
530- combined_status = await gh_request (
531- github .rest .repos .async_get_combined_status_for_ref (
532- owner = repo .owner ,
533- repo = repo .repo ,
534- ref = sha ,
535- )
536- )
537- match combined_status .state :
538- case "success" :
539- return CommitCheckState .SUCCESS
540- case "failure" :
541- return CommitCheckState .FAILURE
542- case _:
543- pass
544- except GitHubException :
545- pass
546-
547- return state
0 commit comments