23
23
import zipfile
24
24
from io import BytesIO
25
25
from pathlib import Path
26
- from typing import Any , Dict , Optional , Tuple
26
+ from typing import Any , Optional , Tuple
27
27
28
28
import click
29
29
import urllib3
34
34
else :
35
35
from typing_extensions import Final , Literal
36
36
37
- COMMENT_BODY_FILE : Final = ".pr-comment-body.md "
37
+ COMMENT_FILE : Final = ".pr-comment.json "
38
38
DIFF_STEP_NAME : Final = "Generate HTML diff report"
39
39
DOCS_URL : Final = (
40
40
"https://black.readthedocs.io/en/latest/"
@@ -55,19 +55,16 @@ def set_output(name: str, value: str) -> None:
55
55
print (f"::set-output name={ name } ::{ value } " )
56
56
57
57
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 {}
65
60
headers ["User-Agent" ] = USER_AGENT
66
61
if "github" in url :
67
62
if GH_API_TOKEN :
68
63
headers ["Authorization" ] = f"token { GH_API_TOKEN } "
69
64
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 )
71
68
if is_json :
72
69
data = json .loads (r .data .decode ("utf-8" ))
73
70
else :
@@ -199,8 +196,9 @@ def config(
199
196
@click .argument ("target" , type = click .Path (exists = True , path_type = Path ))
200
197
@click .argument ("baseline-sha" )
201
198
@click .argument ("target-sha" )
199
+ @click .argument ("pr-num" , type = int )
202
200
def 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
204
202
) -> None :
205
203
# fmt: off
206
204
cmd = [
@@ -225,45 +223,43 @@ def comment_body(
225
223
f"[**What is this?**]({ DOCS_URL } ) | [Workflow run]($workflow-run-url) |"
226
224
" [diff-shades documentation](https://github.com/ichard26/diff-shades#readme)"
227
225
)
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 )
231
229
232
230
233
231
@main .command ("comment-details" , help = "Get PR comment resources from a workflow run." )
234
232
@click .argument ("run-id" )
235
233
def comment_details (run_id : str ) -> None :
236
234
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" :
238
236
set_output ("needs-comment" , "false" )
239
237
return
240
238
241
239
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 ]
250
243
steps = {s ["name" ]: s ["number" ] for s in job ["steps" ]}
251
244
diff_step = steps [DIFF_STEP_NAME ]
252
245
diff_url = job ["html_url" ] + f"#step:{ diff_step } :1"
253
246
254
247
artifacts_data = http_get (data ["artifacts_url" ])["artifacts" ]
255
248
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" ]
261
257
# It's more convenient to fill in these fields after the first workflow is done
262
258
# since this command can access the workflows API (doing it in the main workflow
263
259
# while it's still in progress seems impossible).
264
260
body = body .replace ("$workflow-run-url" , data ["html_url" ])
265
261
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
267
263
escaped = body .replace ("%" , "%25" ).replace ("\n " , "%0A" ).replace ("\r " , "%0D" )
268
264
set_output ("comment-body" , escaped )
269
265
0 commit comments