8
8
variables that are available in the Github Action environment. Specifically:
9
9
10
10
* GITHUB_WORKSPACE: directory where the git clone is located
11
+ * GITHUB_SHA: the git commit SHA of the artificial Github PR test merge commit
11
12
* GITHUB_BASE_REF: the git ref for the base branch
12
- * GITHUB_HEAD_REF: the git commit ref of the head branch
13
13
* GITHUB_TOKEN: token authorizing Github API usage
14
14
* GITHUB_REPOSITORY: "org/repo" name of the Github repository of this PR
15
15
* GITHUB_REF: string that includes this Github PR number
16
- * GITHUB_RUN_ID: unique ID for each workflow run
17
- * GITHUB_SERVER_URL: the URL of the GitHub server
18
16
19
- This script tests each git commit between (and not including) GITHUB_HEAD_REF and
17
+ This script tests each git commit between (and not including) GITHUB_SHA and
20
18
GITHUB_BASE_REF multiple ways:
21
19
22
20
1. Ensure that the committer and author do not match any bad patterns (e.g.,
55
53
NACP = "bot:notacherrypick"
56
54
57
55
GITHUB_WORKSPACE = os .environ .get ('GITHUB_WORKSPACE' )
56
+ GITHUB_SHA = os .environ .get ('GITHUB_SHA' )
58
57
GITHUB_BASE_REF = os .environ .get ('GITHUB_BASE_REF' )
59
- GITHUB_HEAD_REF = os .environ .get ('GITHUB_HEAD_REF' )
60
58
GITHUB_TOKEN = os .environ .get ('GITHUB_TOKEN' )
61
59
GITHUB_REPOSITORY = os .environ .get ('GITHUB_REPOSITORY' )
62
60
GITHUB_REF = os .environ .get ('GITHUB_REF' )
63
- GITHUB_RUN_ID = os .environ .get ('GITHUB_RUN_ID' )
64
- GITHUB_SERVER_URL = os .environ .get ('GITHUB_SERVER_URL' )
65
- PR_NUM = os .environ .get ('PR_NUM' )
66
61
67
62
# Sanity check
68
63
if (GITHUB_WORKSPACE is None or
64
+ GITHUB_SHA is None or
69
65
GITHUB_BASE_REF is None or
70
- GITHUB_HEAD_REF is None or
71
66
GITHUB_TOKEN is None or
72
67
GITHUB_REPOSITORY is None or
73
- GITHUB_REF is None or
74
- GITHUB_RUN_ID is None or
75
- GITHUB_SERVER_URL is None or
76
- PR_NUM is None ):
68
+ GITHUB_REF is None ):
77
69
print ("Error: this script is designed to run as a Github Action" )
78
70
exit (1 )
79
71
@@ -93,50 +85,6 @@ def make_commit_message(repo, hash):
93
85
94
86
#----------------------------------------------------------------------------
95
87
96
- """
97
- Iterate through the BAD results, collect the error messages, and send a nicely
98
- formatted comment to the PR.
99
-
100
- For the structure of the results dictionary, see comment for print_results()
101
- below.
102
-
103
- """
104
- def comment_on_pr (pr , results , repo ):
105
- # If there are no BAD results, just return without posting a comment to the
106
- # GitHub PR.
107
- if len (results [BAD ]) == 0 :
108
- return
109
-
110
- comment = "Hello! The Git Commit Checker CI bot found a few problems with this PR:"
111
- for hash , entry in results [BAD ].items ():
112
- comment += f"\n \n **{ hash [:8 ]} : { make_commit_message (repo , hash )} **"
113
- for check_name , message in entry .items ():
114
- if message is not None :
115
- comment += f"\n * *{ check_name } : { message } *"
116
- comment_footer = "\n \n Please fix these problems and, if necessary, force-push new commits back up to the PR branch. Thanks!"
117
-
118
- # GitHub says that 65536 characters is the limit of comment messages, so
119
- # check if our comment is over that limit. If it is, truncate it to fit, and
120
- # add a message explaining with a link to the full error list.
121
- comment_char_limit = 65536
122
- if len (comment + comment_footer ) >= comment_char_limit :
123
- run_url = f"{ GITHUB_SERVER_URL } /{ GITHUB_REPOSITORY } /actions/runs/{ GITHUB_RUN_ID } ?check_suite_focus=true"
124
- truncation_message = f"\n \n **Additional errors could not be shown...\n [Please click here for a full list of errors.]({ run_url } )**"
125
- # Cut the comment down so we can get the comment itself, and the new
126
- # message in.
127
- comment = comment [:(comment_char_limit - len (comment_footer + truncation_message ))]
128
- # In case a newline gets split in half, remove the leftover '\' (if
129
- # there is one). (This is purely an aesthetics choice).
130
- comment = comment .rstrip ("\\ " )
131
- comment += truncation_message
132
-
133
- comment += comment_footer
134
- pr .create_issue_comment (comment )
135
-
136
- return
137
-
138
- #----------------------------------------------------------------------------
139
-
140
88
"""
141
89
The results dictionary is in the following format:
142
90
@@ -294,15 +242,15 @@ def _is_entirely_submodule_updates(repo, commit):
294
242
#----------------------------------------------------------------------------
295
243
296
244
def check_all_commits (config , repo ):
297
- # Get a list of commits that we'll be examining. Use the programmatic form
298
- # of "git log GITHUB_BASE_REF..GITHUB_HEAD_REF" (i.e., "git log
299
- # ^GITHUB_BASE_REF GITHUB_HEAD_REF") to do the heavy lifting to find that
300
- # set of commits. Because we're using pull_request_target, GITHUB_BASE_REF
301
- # is already checked out. GITHUB_HEAD_REF has never been checked out, so we
302
- # specify "origin/{GITHUB_HEAD_REF}".
245
+ # Get a list of commits that we'll be examining. Use the progromatic form
246
+ # of "git log GITHUB_BASE_REF..GITHUB_SHA" (i.e., "git log ^GITHUB_BASE_REF
247
+ # GITHUB_SHA") to do the heavy lifting to find that set of commits.
303
248
git_cli = git .cmd .Git (GITHUB_WORKSPACE )
304
- hashes = git_cli .log (f"--pretty=format:%h" ,
305
- f"{ GITHUB_BASE_REF } ..origin/{ GITHUB_HEAD_REF } " ).splitlines ()
249
+ hashes = git_cli .log (f"--pretty=format:%h" , f"origin/{ GITHUB_BASE_REF } ..{ GITHUB_SHA } " ).splitlines ()
250
+
251
+ # The first entry in the list will be the artificial Github merge commit for
252
+ # this PR. We don't want to examine this commit.
253
+ del hashes [0 ]
306
254
307
255
#------------------------------------------------------------------------
308
256
@@ -344,7 +292,15 @@ def check_all_commits(config, repo):
344
292
If "bot:notacherrypick" is in the PR description, then disable the
345
293
cherry-pick message requirement.
346
294
"""
347
- def check_github_pr_description (config , pr ):
295
+ def check_github_pr_description (config ):
296
+ g = Github (GITHUB_TOKEN )
297
+ repo = g .get_repo (GITHUB_REPOSITORY )
298
+
299
+ # Extract the PR number from GITHUB_REF
300
+ match = re .search ("/(\d+)/" , GITHUB_REF )
301
+ pr_num = int (match .group (1 ))
302
+ pr = repo .get_pull (pr_num )
303
+
348
304
if pr .body and NACP in pr .body :
349
305
config ['cherry pick required' ] = False
350
306
@@ -378,17 +334,11 @@ def load_config():
378
334
379
335
def main ():
380
336
config = load_config ()
337
+ check_github_pr_description (config )
381
338
382
- g = Github (GITHUB_TOKEN )
383
- github_repo = g .get_repo (GITHUB_REPOSITORY )
384
- pr_num = int (PR_NUM )
385
- pr = github_repo .get_pull (pr_num )
386
- check_github_pr_description (config , pr )
387
-
388
- local_repo = git .Repo (GITHUB_WORKSPACE )
389
- results , hashes = check_all_commits (config , local_repo )
390
- print_results (results , local_repo , hashes )
391
- comment_on_pr (pr , results , local_repo )
339
+ repo = git .Repo (GITHUB_WORKSPACE )
340
+ results , hashes = check_all_commits (config , repo )
341
+ print_results (results , repo , hashes )
392
342
393
343
if len (results [BAD ]) == 0 :
394
344
print ("\n Test passed: everything was good!" )
0 commit comments