2323import zipfile
2424from io import BytesIO
2525from pathlib import Path
26- from typing import Any , Dict , Optional , Tuple
26+ from typing import Any , Optional , Tuple
2727
2828import click
2929import urllib3
3434else :
3535 from typing_extensions import Final , Literal
3636
37- COMMENT_BODY_FILE : Final = ".pr-comment-body.md "
37+ COMMENT_FILE : Final = ".pr-comment.json "
3838DIFF_STEP_NAME : Final = "Generate HTML diff report"
3939DOCS_URL : Final = (
4040 "https://black.readthedocs.io/en/latest/"
@@ -55,19 +55,16 @@ def set_output(name: str, value: str) -> None:
5555 print (f"::set-output name={ name } ::{ value } " )
5656
5757
58- def http_get (
59- url : str ,
60- is_json : bool = True ,
61- headers : Optional [Dict [str , str ]] = None ,
62- ** kwargs : Any ,
63- ) -> Any :
64- headers = headers or {}
58+ def http_get (url : str , is_json : bool = True , ** kwargs : Any ) -> Any :
59+ headers = kwargs .get ("headers" ) or {}
6560 headers ["User-Agent" ] = USER_AGENT
6661 if "github" in url :
6762 if GH_API_TOKEN :
6863 headers ["Authorization" ] = f"token { GH_API_TOKEN } "
6964 headers ["Accept" ] = "application/vnd.github.v3+json"
70- r = http .request ("GET" , url , headers = headers , ** kwargs )
65+ kwargs ["headers" ] = headers
66+
67+ r = http .request ("GET" , url , ** kwargs )
7168 if is_json :
7269 data = json .loads (r .data .decode ("utf-8" ))
7370 else :
@@ -199,8 +196,9 @@ def config(
199196@click .argument ("target" , type = click .Path (exists = True , path_type = Path ))
200197@click .argument ("baseline-sha" )
201198@click .argument ("target-sha" )
199+ @click .argument ("pr-num" , type = int )
202200def comment_body (
203- baseline : Path , target : Path , baseline_sha : str , target_sha : str
201+ baseline : Path , target : Path , baseline_sha : str , target_sha : str , pr_num : int
204202) -> None :
205203 # fmt: off
206204 cmd = [
@@ -225,45 +223,43 @@ def comment_body(
225223 f"[**What is this?**]({ DOCS_URL } ) | [Workflow run]($workflow-run-url) |"
226224 " [diff-shades documentation](https://github.com/ichard26/diff-shades#readme)"
227225 )
228- print (f"[INFO]: writing half-completed comment body to { COMMENT_BODY_FILE } " )
229- with open (COMMENT_BODY_FILE , "w" , encoding = "utf-8" ) as f :
230- f . write ( body )
226+ print (f"[INFO]: writing comment details to { COMMENT_FILE } " )
227+ with open (COMMENT_FILE , "w" , encoding = "utf-8" ) as f :
228+ json . dump ({ " body" : body , "pr-number" : pr_num }, f )
231229
232230
233231@main .command ("comment-details" , help = "Get PR comment resources from a workflow run." )
234232@click .argument ("run-id" )
235233def comment_details (run_id : str ) -> None :
236234 data = http_get (f"https://api.github.com/repos/{ REPO } /actions/runs/{ run_id } " )
237- if data ["event" ] != "pull_request" :
235+ if data ["event" ] != "pull_request" or data [ "conclusion" ] == "cancelled" :
238236 set_output ("needs-comment" , "false" )
239237 return
240238
241239 set_output ("needs-comment" , "true" )
242- pulls = data ["pull_requests" ]
243- assert len (pulls ) == 1
244- pr_number = pulls [0 ]["number" ]
245- set_output ("pr-number" , str (pr_number ))
246-
247- jobs_data = http_get (data ["jobs_url" ])
248- assert len (jobs_data ["jobs" ]) == 1 , "multiple jobs not supported nor tested"
249- job = jobs_data ["jobs" ][0 ]
240+ jobs = http_get (data ["jobs_url" ])["jobs" ]
241+ assert len (jobs ) == 1 , "multiple jobs not supported nor tested"
242+ job = jobs [0 ]
250243 steps = {s ["name" ]: s ["number" ] for s in job ["steps" ]}
251244 diff_step = steps [DIFF_STEP_NAME ]
252245 diff_url = job ["html_url" ] + f"#step:{ diff_step } :1"
253246
254247 artifacts_data = http_get (data ["artifacts_url" ])["artifacts" ]
255248 artifacts = {a ["name" ]: a ["archive_download_url" ] for a in artifacts_data }
256- body_url = artifacts [COMMENT_BODY_FILE ]
257- body_zip = BytesIO (http_get (body_url , is_json = False ))
258- with zipfile .ZipFile (body_zip ) as zfile :
259- with zfile .open (COMMENT_BODY_FILE ) as rf :
260- body = rf .read ().decode ("utf-8" )
249+ comment_url = artifacts [COMMENT_FILE ]
250+ comment_zip = BytesIO (http_get (comment_url , is_json = False ))
251+ with zipfile .ZipFile (comment_zip ) as zfile :
252+ with zfile .open (COMMENT_FILE ) as rf :
253+ comment_data = json .loads (rf .read ().decode ("utf-8" ))
254+
255+ set_output ("pr-number" , str (comment_data ["pr-number" ]))
256+ body = comment_data ["body" ]
261257 # It's more convenient to fill in these fields after the first workflow is done
262258 # since this command can access the workflows API (doing it in the main workflow
263259 # while it's still in progress seems impossible).
264260 body = body .replace ("$workflow-run-url" , data ["html_url" ])
265261 body = body .replace ("$job-diff-url" , diff_url )
266- # # https://github.community/t/set-output-truncates-multiline-strings/16852/3
262+ # https://github.community/t/set-output-truncates-multiline-strings/16852/3
267263 escaped = body .replace ("%" , "%25" ).replace ("\n " , "%0A" ).replace ("\r " , "%0D" )
268264 set_output ("comment-body" , escaped )
269265
0 commit comments