Skip to content

Commit 42df5f3

Browse files
committed
Implement approvers
1 parent 2b3e6b9 commit 42df5f3

2 files changed

Lines changed: 32 additions & 2 deletions

File tree

.github/scripts/merge_pr.php

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
declare(strict_types=1);
44

55
class Context {
6+
public string $actor_id;
67
public string $pr_number;
78
public string $pr_sha;
89
public string $pr_ref;
@@ -20,6 +21,7 @@ function get_context(): Context {
2021
$context = new Context;
2122

2223
$env_mapping = [
24+
'ACTOR_ID' => 'actor_id',
2325
'PR_DESCRIPTION' => 'pr_description',
2426
'PR_NUMBER' => 'pr_number',
2527
'PR_REF' => 'pr_ref',
@@ -167,21 +169,47 @@ function find_release_branches(string $target): array {
167169
return $branches;
168170
}
169171

172+
function fetch_approvers(Context $context) {
173+
$approver_ids = [$context->actor_id, ...preg_split('(\n)', trim(run_command("gh api \"/repos/php/php-src/pulls/22096/reviews\" --jq 'map(select(.state == \"APPROVED\" and .commit_id == \"800d8377b8abea7317ed2e47cb6bc0fd9e0909ea\") | .user.id)[]'")->stdout), flags: PREG_SPLIT_NO_EMPTY)];
174+
$approvers = [];
175+
foreach ($approver_ids as $approver_id) {
176+
$id = $user['id'];
177+
$login = $user['login'];
178+
$user = json_decode(run_command("gh api '/user/$id'")->stdout, true, flags: JSON_THROW_ON_ERROR);
179+
$name = $user['name'] ?? $login;
180+
$email = $user['email'] ?? "{$id}+{$login}@users.noreply.github.com";
181+
$approvers[] = "$name <$email>";
182+
}
183+
return $approvers;
184+
}
185+
170186
function merge_pr_into_target(Context $context): string {
171187
$author = trim(run_command(['git', 'log', '-1', '--format=%an <%ae>', $context->pr_first_sha])->stdout);
172188
$message = "{$context->pr_title} (GH-{$context->pr_number})";
173189
$description = wrap_commit_message($context->pr_description);
174190

175191
$co_authors = preg_split('(\n)', trim(run_command("git log --reverse --format='%an <%ae>' {$context->pr_first_sha}..{$context->pr_sha} | sort | uniq -c | sort -rn | sed 's/^ *[0-9]* //'")->stdout), flags: PREG_SPLIT_NO_EMPTY);
176-
$co_authors = array_filter($co_authors, fn (string $co_author) => strcasecmp($co_author, $author) !== 0 && stripos($description, $co_author) === false);
192+
$co_authors = array_map(fn (string $co_author) => 'Co-authored-by: ' . $co_author, $co_authors);
193+
$co_authors = array_filter($co_authors, fn (string $co_author) => strcasecmp($co_author, 'Co-authored-by: ' . $author) !== 0 && stripos($description, $co_author) === false);
177194
if (count($co_authors)) {
178-
$co_authors = array_map(fn (string $co_author) => 'Co-authored-by: ' . $co_author, $co_authors);
179195
if ($description !== '') {
180196
$description .= "\n\n";
181197
}
182198
$description .= implode("\n", $co_authors);
183199
}
184200

201+
$approvers = fetch_approvers($context);
202+
if (count($approvers)) {
203+
$approvers = array_map(fn (string $pr_approver) => 'Signed-off-by: ' . $pr_approver, $approvers);
204+
$approvers = array_filter($approvers, fn (string $pr_approver) => strcasecmp($pr_approver, 'Signed-off-by: ' . $author) !== 0 && stripos($description, $pr_approver) === false);
205+
if (count($approvers)) {
206+
if ($description !== '') {
207+
$description .= "\n\n";
208+
}
209+
$description .= implode("\n", $approvers);
210+
}
211+
}
212+
185213
run(['git', 'checkout', '-B', $context->target_ref, "refs/remotes/origin/{$context->target_ref}"]);
186214
run(['git', 'merge', '--squash', $context->pr_sha],
187215
failure_message: "Failed to squash PR into {$context->target_ref}.");

.github/workflows/merge_pr.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ jobs:
6161
- name: Merge PR
6262
id: merge
6363
env:
64+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
65+
ACTOR_ID: ${{ github.actor_id }}
6466
PR_NUMBER: ${{ github.event.pull_request.number }}
6567
PR_SHA: ${{ github.event.pull_request.head.sha }}
6668
PR_REF: ${{ github.event.pull_request.head.ref }}

0 commit comments

Comments
 (0)