@@ -29,6 +29,8 @@ class GitHubActionsEnv(TypedDict):
2929 GITHUB_EVENT_NAME : str
3030 GITHUB_REPOSITORY : str
3131 GITHUB_SHA : str
32+ GITHUB_REF_TYPE : str
33+ GITHUB_REF : str
3234
3335
3436job_tmp_dir = os .environ .get ('JOB_TMP_DIR' , '.' )
@@ -67,6 +69,8 @@ class ActionInputs(TypedDict):
6769 INPUT_TARGET : str
6870 INPUT_REPLACE : str
6971
72+ class WorkflowException (Exception ):
73+ """An exception that should result in an error in the workflow log"""
7074
7175def plan_identifier (action_inputs : ActionInputs ) -> str :
7276 def mask_backend_config () -> Optional [str ]:
@@ -164,7 +168,7 @@ def github_api_request(method: str, *args, **kwargs) -> requests.Response:
164168 limit_reset = datetime .datetime .fromtimestamp (int (response .headers ['X-RateLimit-Reset' ]))
165169 sys .stdout .write (message )
166170 sys .stdout .write (f' Try again when the rate limit resets at { limit_reset } UTC.\n ' )
167- exit (1 )
171+ sys . exit (1 )
168172
169173 if message != 'Resource not accessible by integration' :
170174 sys .stdout .write (message )
@@ -206,20 +210,42 @@ def find_pr(actions_env: GitHubActionsEnv) -> PrUrl:
206210
207211 """
208212
209- with open (actions_env ['GITHUB_EVENT_PATH' ]) as f :
210- event = json .load (f )
213+ event : Optional [Dict [str , Any ]]
214+
215+ if os .path .isfile (actions_env ['GITHUB_EVENT_PATH' ]):
216+ with open (actions_env ['GITHUB_EVENT_PATH' ]) as f :
217+ event = json .load (f )
218+ else :
219+ debug ('Event payload is not available' )
220+ event = None
211221
212222 event_type = actions_env ['GITHUB_EVENT_NAME' ]
213223
214- if event_type in ['pull_request' , 'pull_request_review_comment' , 'pull_request_target' , 'pull_request_review' ]:
215- return cast (PrUrl , event ['pull_request' ]['url' ])
224+ if event_type in ['pull_request' , 'pull_request_review_comment' , 'pull_request_target' , 'pull_request_review' , 'issue_comment' ]:
225+
226+ if event is not None :
227+ # Pull pr url from event payload
228+
229+ if event_type in ['pull_request' , 'pull_request_review_comment' , 'pull_request_target' , 'pull_request_review' ]:
230+ return cast (PrUrl , event ['pull_request' ]['url' ])
216231
217- elif event_type == 'issue_comment' :
232+ if event_type == 'issue_comment' :
233+
234+ if 'pull_request' in event ['issue' ]:
235+ return cast (PrUrl , event ['issue' ]['pull_request' ]['url' ])
236+ else :
237+ raise WorkflowException ('This comment is not for a PR. Add a filter of `if: github.event.issue.pull_request`' )
218238
219- if 'pull_request' in event ['issue' ]:
220- return cast (PrUrl , event ['issue' ]['pull_request' ]['url' ])
221239 else :
222- raise Exception ('This comment is not for a PR. Add a filter of `if: github.event.issue.pull_request`' )
240+ # Event payload is not available
241+
242+ if actions_env .get ('GITHUB_REF_TYPE' ) == 'branch' :
243+ if match := re .match (r'refs/pull/(\d+)/' , actions_env .get ('GITHUB_REF' , '' )):
244+ return cast (PrUrl , f'{ actions_env ["GITHUB_API_URL" ]} /repos/{ actions_env ["GITHUB_REPOSITORY" ]} /pulls/{ match .group (1 )} ' )
245+
246+ raise WorkflowException (f'Event payload is not available at the GITHUB_EVENT_PATH { actions_env ["GITHUB_EVENT_PATH" ]!r} . ' +
247+ f'This is required when run by { event_type } events. The environment has not been setup properly by the actions runner. ' +
248+ 'This can happen when the runner is running in a container' )
223249
224250 elif event_type == 'push' :
225251 repo = actions_env ['GITHUB_REPOSITORY' ]
@@ -233,10 +259,10 @@ def prs() -> Iterable[Dict[str, Any]]:
233259 if pr ['merge_commit_sha' ] == commit :
234260 return cast (PrUrl , pr ['url' ])
235261
236- raise Exception (f'No PR found in { repo } for commit { commit } (was it pushed directly to the target branch?)' )
262+ raise WorkflowException (f'No PR found in { repo } for commit { commit } (was it pushed directly to the target branch?)' )
237263
238264 else :
239- raise Exception (f"The { event_type } event doesn\' t relate to a Pull Request." )
265+ raise WorkflowException (f"The { event_type } event doesn\' t relate to a Pull Request." )
240266
241267
242268def current_user (actions_env : GitHubActionsEnv ) -> str :
@@ -416,10 +442,11 @@ def save_step_cache(**kwargs) -> None:
416442
417443def main () -> None :
418444 if len (sys .argv ) < 2 :
419- print (f'''Usage:
445+ sys . stdout . write (f'''Usage:
420446 STATUS="<status>" { sys .argv [0 ]} plan <plan.txt
421447 STATUS="<status>" { sys .argv [0 ]} status
422- { sys .argv [0 ]} get >plan.txt''' )
448+ { sys .argv [0 ]} get >plan.txt
449+ ''' )
423450
424451 debug (repr (sys .argv ))
425452
@@ -436,7 +463,11 @@ def main() -> None:
436463 pr_url = step_cache ['pr_url' ]
437464 debug (f'pr_url from step cache: { pr_url } ' )
438465 else :
439- pr_url = find_pr (env )
466+ try :
467+ pr_url = find_pr (env )
468+ except WorkflowException as e :
469+ sys .stdout .write ('\n ' + str (e ) + '\n ' )
470+ sys .exit (1 )
440471 debug (f'discovered pr_url: { pr_url } ' )
441472
442473 if step_cache .get ('pr_url' ) == pr_url and step_cache .get ('issue_url' ) is not None :
@@ -473,14 +504,14 @@ def main() -> None:
473504
474505 elif sys .argv [1 ] == 'status' :
475506 if plan is None :
476- exit (1 )
507+ sys . exit (1 )
477508 else :
478509 body = format_body (action_inputs , plan , status , collapse_threshold )
479510 comment_url = update_comment (issue_url , comment_url , body , only_if_exists )
480511
481512 elif sys .argv [1 ] == 'get' :
482513 if plan is None :
483- exit (1 )
514+ sys . exit (1 )
484515
485516 with open (sys .argv [2 ], 'w' ) as f :
486517 f .write (plan )
0 commit comments