11<?php
22
3+ declare (strict_types=1 );
4+
35class ProcessResult {
4- public $ status ;
5- public $ stdout ;
6- public $ stderr ;
6+ public int $ status = 0 ;
7+ public string $ stdout = '' ;
8+ public string $ stderr = '' ;
79}
810
11+ /** @param string|list<string> $cmd */
912function run_command (string |array $ cmd , ?string $ failure_message = 'Unexpected error. ' ): ProcessResult {
1013 if (is_array ($ cmd )) {
1114 $ cmd = implode (' ' , array_map ('escapeshellarg ' , $ cmd ));
@@ -65,11 +68,13 @@ function run_command(string|array $cmd, ?string $failure_message = 'Unexpected e
6568 return $ result ;
6669}
6770
71+ /** @param list<string> $args */
6872function try_run (array $ args ): bool {
6973 $ result = run_command ($ args , failure_message: null );
7074 return $ result ->status === 0 ;
7175}
7276
77+ /** @param list<string> $args */
7378function run (array $ args , ?string $ failure_message = null ): bool {
7479 $ result = run_command ($ args , $ failure_message ?? 'Unexpected error. ' );
7580 return $ result ->status === 0 ;
@@ -104,6 +109,7 @@ function find_next_release_branch(string $current): ?string {
104109 return 'master ' ;
105110}
106111
112+ /** @return list<string> */
107113function find_release_branches (string $ target ): array {
108114 $ branches = [$ target ];
109115 while (null !== $ next = find_next_release_branch (end ($ branches ))) {
@@ -124,7 +130,8 @@ function merge_pr_into_target(string $pr_sha, string $pr_first_sha, string $targ
124130 return $ squashed_sha ;
125131}
126132
127- function merge_upwards (array $ branches ) {
133+ /** @param list<string> $branches */
134+ function merge_upwards (array $ branches ): void {
128135 for ($ i = 1 ; $ i < count ($ branches ); $ i ++) {
129136 $ prev = $ branches [$ i - 1 ];
130137 $ current = $ branches [$ i ];
@@ -140,7 +147,7 @@ enum PushPrBranchResult {
140147 case RemoteRejected;
141148}
142149
143- function push_pr_branch (string $ url , string $ branch , string $ new_commit , string $ expected_commit ) {
150+ function push_pr_branch (string $ url , string $ branch , string $ new_commit , string $ expected_commit ): PushPrBranchResult {
144151 $ result = run_command (['git ' , 'push ' , "--force-with-lease= $ branch: $ expected_commit " , $ url , "$ new_commit:refs/heads/ $ branch " ], failure_message: null );
145152 if ($ result ->status === 0 ) {
146153 return PushPrBranchResult::Success;
@@ -151,11 +158,12 @@ function push_pr_branch(string $url, string $branch, string $new_commit, string
151158 }
152159}
153160
161+ /** @param list<string> $branches */
154162function push_release_branches (array $ branches ): bool {
155163 return try_run (['git ' , 'push ' , '--atomic ' , 'origin ' , ...$ branches ]);
156164}
157165
158- function revert_pr_branch (string $ url , string $ branch , string $ new_commit , string $ expected_commit ) {
166+ function revert_pr_branch (string $ url , string $ branch , string $ new_commit , string $ expected_commit ): void {
159167 run_command (['git ' , 'push ' , "--force-with-lease= $ branch: $ expected_commit " , $ url , "$ new_commit:refs/heads/ $ branch " ],
160168 failure_message: 'Failed to push release branches. Reverting PR branch also failed. ' );
161169}
@@ -209,9 +217,11 @@ function main(): int {
209217 if ($ push_pr_branch_result === PushPrBranchResult::Rejected) {
210218 throw new RuntimeException ('PR branch diverged. ' );
211219 } else if ($ push_pr_branch_result === PushPrBranchResult::RemoteRejected) {
212- // Contributor likely unchecked the "Allow edits by maintainers"
213- // checkbox. Resume and close PR manually.
214- file_put_contents ($ github_output , "close_pr=1 \n" , FILE_APPEND );
220+ if ($ github_output !== false ) {
221+ // Contributor likely unchecked the "Allow edits by maintainers"
222+ // checkbox. Resume and close PR manually.
223+ file_put_contents ($ github_output , "close_pr=1 \n" , FILE_APPEND );
224+ }
215225 }
216226 if (!push_release_branches ($ release_branches )) {
217227 revert_pr_branch ($ pr_repo_url , $ pr_ref , $ pr_sha , $ squashed_sha );
0 commit comments