11use crate :: {
22 github:: { Event , IssuesAction , IssuesEvent } ,
33 handlers:: Context ,
4+ interactions:: EditIssueBody ,
45} ;
56
7+ #[ derive( Debug , PartialEq , Eq , serde:: Serialize , serde:: Deserialize , Default ) ]
8+ struct RenderedLinkData {
9+ rendered_link : String ,
10+ }
11+
612pub async fn handle ( ctx : & Context , event : & Event ) -> anyhow:: Result < ( ) > {
713 let e = if let Event :: Issue ( e) = event {
814 e
915 } else {
1016 return Ok ( ( ) ) ;
1117 } ;
1218
19+ if !e. issue . is_pr ( ) {
20+ return Ok ( ( ) ) ;
21+ }
22+
1323 let repo = e. issue . repository ( ) ;
1424 let prefix = match ( & * repo. organization , & * repo. repository ) {
1525 ( "rust-lang" , "rfcs" ) => "text/" ,
@@ -25,32 +35,47 @@ pub async fn handle(ctx: &Context, event: &Event) -> anyhow::Result<()> {
2535}
2636
2737async fn add_rendered_link ( ctx : & Context , e : & IssuesEvent , prefix : & str ) -> anyhow:: Result < ( ) > {
28- if e. action == IssuesAction :: Opened {
38+ if e. action == IssuesAction :: Opened
39+ || e. action == IssuesAction :: Closed
40+ || e. action == IssuesAction :: Reopened
41+ {
42+ let edit = EditIssueBody :: new ( & e. issue , "RENDERED_LINK" ) ;
43+ let current_data: Option < RenderedLinkData > = edit. current_data ( ) ;
44+
2945 let files = e. issue . files ( & ctx. github ) . await ?;
3046
3147 if let Some ( file) = files. iter ( ) . find ( |f| f. filename . starts_with ( prefix) ) {
32- if !e. issue . body . contains ( "[Rendered]" ) {
33- // This URL should be stable while the PR is open, even if the
34- // user pushes new commits.
35- //
36- // It will go away if the user deletes their branch, or if
37- // they reset it (such as if they created a PR from master).
38- // That should usually only happen after the PR is closed.
39- // During the closing process, the closer should update the
40- // Rendered link to the new location (which we should
41- // automate!).
42- let head = e. issue . head . as_ref ( ) . unwrap ( ) ;
43- let url = format ! (
44- "https://github.com/{}/blob/{}/{}" ,
45- head. repo. full_name, head. git_ref, file. filename
46- ) ;
47- e. issue
48- . edit_body (
49- & ctx. github ,
50- & format ! ( "{}\n \n [Rendered]({})" , e. issue. body, url) ,
51- )
52- . await ?;
53- }
48+ let mut current_data = current_data. unwrap_or_default ( ) ;
49+ let head = e. issue . head . as_ref ( ) . unwrap ( ) ;
50+
51+ // This URL should be stable while the PR is open, even if the
52+ // user pushes new commits.
53+ //
54+ // It will go away if the user deletes their branch, or if
55+ // they reset it (such as if they created a PR from master).
56+ // That should usually only happen after the PR is closed
57+ // a which point we switch to a SHA-based url.
58+ current_data. rendered_link = format ! (
59+ "https://github.com/{}/blob/{}/{}" ,
60+ head. repo. full_name,
61+ if e. action == IssuesAction :: Closed {
62+ & head. sha
63+ } else {
64+ & head. git_ref
65+ } ,
66+ file. filename
67+ ) ;
68+
69+ edit. apply (
70+ & ctx. github ,
71+ format ! ( "[Rendered]({})" , & current_data. rendered_link) ,
72+ current_data,
73+ )
74+ . await ?;
75+ } else if let Some ( mut current_data) = current_data {
76+ // No render link to show, but one previously, so remove it
77+ current_data. rendered_link = String :: new ( ) ;
78+ edit. apply ( & ctx. github , String :: new ( ) , current_data) . await ?;
5479 }
5580 }
5681
0 commit comments