Skip to content

Commit 11f3302

Browse files
committed
feature #108 Comment on draft PRs, close them after 60 minutes. (Nyholm)
This PR was merged into the master branch. Discussion ---------- Comment on draft PRs, close them after 60 minutes. If someone open a draft PR, we should ask them to "mark it ready for review". If they dont, we will close the PR. This PR will also fix #70. Ie, dont add labels on PRs in "draft". Commits ------- 610b80c Close draft PRs
2 parents 074528d + 610b80c commit 11f3302

17 files changed

+1181
-4
lines changed

config/services.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ parameters:
1010
- 'App\Subscriber\AutoLabelFromContentSubscriber'
1111
- 'App\Subscriber\MilestoneNewPRSubscriber'
1212
- 'App\Subscriber\WelcomeFirstTimeContributorSubscriber'
13+
- 'App\Subscriber\CloseDraftPRSubscriber'
1314
secret: '%env(SYMFONY_SECRET)%'
1415

1516
symfony/symfony-docs:
@@ -36,6 +37,7 @@ parameters:
3637
- 'App\Subscriber\AutoLabelFromContentSubscriber'
3738
- 'App\Subscriber\MilestoneNewPRSubscriber'
3839
- 'App\Subscriber\WelcomeFirstTimeContributorSubscriber'
40+
- 'App\Subscriber\CloseDraftPRSubscriber'
3941

4042
services:
4143
_defaults:

src/Api/Issue/GithubIssueApi.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ public function open(Repository $repository, string $title, string $body, array
4444
}
4545
}
4646

47+
public function show(Repository $repository, $issueNumber): array
48+
{
49+
return $this->issueApi->show($repository->getVendor(), $repository->getName(), $issueNumber);
50+
}
51+
4752
public function close(Repository $repository, $issueNumber)
4853
{
4954
$this->issueApi->update($repository->getVendor(), $repository->getName(), $issueNumber, ['state' => 'closed']);

src/Api/Issue/IssueApi.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ interface IssueApi
1717
*/
1818
public function open(Repository $repository, string $title, string $body, array $labels);
1919

20+
public function show(Repository $repository, $issueNumber): array;
21+
2022
public function commentOnIssue(Repository $repository, $issueNumber, string $commentBody);
2123

2224
/**

src/Api/Issue/NullIssueApi.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ public function open(Repository $repository, string $title, string $body, array
1010
{
1111
}
1212

13+
public function show(Repository $repository, $issueNumber): array
14+
{
15+
return [];
16+
}
17+
1318
public function commentOnIssue(Repository $repository, $issueNumber, string $commentBody)
1419
{
1520
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Service\TaskHandler;
6+
7+
use App\Api\Issue\IssueApi;
8+
use App\Api\PullRequest\PullRequestApi;
9+
use App\Entity\Task;
10+
use App\Service\RepositoryProvider;
11+
12+
/**
13+
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
14+
*/
15+
class CloseDraftHandler implements TaskHandlerInterface
16+
{
17+
private $issueApi;
18+
private $repositoryProvider;
19+
private $pullRequestApi;
20+
21+
public function __construct(PullRequestApi $pullRequestApi, IssueApi $issueApi, RepositoryProvider $repositoryProvider)
22+
{
23+
$this->issueApi = $issueApi;
24+
$this->repositoryProvider = $repositoryProvider;
25+
$this->pullRequestApi = $pullRequestApi;
26+
}
27+
28+
public function handle(Task $task): void
29+
{
30+
$repository = $this->repositoryProvider->getRepository($task->getRepositoryFullName());
31+
$pr = $this->pullRequestApi->show($repository, $task->getNumber());
32+
33+
if ($pr['draft'] ?? false) {
34+
$this->issueApi->close($repository, $task->getNumber());
35+
}
36+
}
37+
38+
public function supports(Task $task): bool
39+
{
40+
return Task::ACTION_CLOSE_DRAFT === $task->getAction();
41+
}
42+
}

src/Subscriber/AutoLabelFromContentSubscriber.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ public function __construct(LabelApi $labelsApi, LabelNameExtractor $labelExtrac
2626
public function onPullRequest(GitHubEvent $event)
2727
{
2828
$data = $event->getData();
29-
if ('opened' !== $action = $data['action']) {
29+
if (!in_array($data['action'], ['opened', 'ready_for_review']) || ($data['pull_request']['draft'] ?? false)) {
3030
return;
3131
}
32+
3233
$repository = $event->getRepository();
3334

3435
$prNumber = $data['pull_request']['number'];
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
namespace App\Subscriber;
4+
5+
use App\Api\Issue\IssueApi;
6+
use App\Entity\Task;
7+
use App\Event\GitHubEvent;
8+
use App\GitHubEvents;
9+
use App\Service\ComplementGenerator;
10+
use App\Service\TaskScheduler;
11+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
12+
13+
/**
14+
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
15+
*/
16+
class CloseDraftPRSubscriber implements EventSubscriberInterface
17+
{
18+
private $issueApi;
19+
private $complementGenerator;
20+
private $scheduler;
21+
22+
public function __construct(IssueApi $issueApi, ComplementGenerator $complementGenerator, TaskScheduler $scheduler)
23+
{
24+
$this->issueApi = $issueApi;
25+
$this->complementGenerator = $complementGenerator;
26+
$this->scheduler = $scheduler;
27+
}
28+
29+
public function onPullRequest(GitHubEvent $event)
30+
{
31+
$data = $event->getData();
32+
$repository = $event->getRepository();
33+
if ('opened' !== $data['action'] || !($data['pull_request']['draft'] ?? false)) {
34+
return;
35+
}
36+
37+
$number = $data['pull_request']['number'];
38+
$complement = $this->complementGenerator->getPullRequestComplement();
39+
$this->issueApi->commentOnIssue($repository, $number, <<<TXT
40+
Hey!
41+
42+
$complement
43+
44+
Could you please click the "ready for review" button? Or maybe close this PR and open a new one when you are done.
45+
Note that a pull request does not have to be "perfect" or "ready for merge" when you first open it, but it should be ready for a first review.
46+
47+
Cheers!
48+
49+
Carsonbot
50+
TXT
51+
);
52+
53+
// Add a scheduled task to close the PR within 1 hour.
54+
$this->scheduler->runLater($repository, $number, Task::ACTION_CLOSE_DRAFT, new \DateTimeImmutable('+1hour'));
55+
56+
$event->setResponseData([
57+
'pull_request' => $number,
58+
'draft_comment' => true,
59+
]);
60+
}
61+
62+
public static function getSubscribedEvents()
63+
{
64+
return [
65+
GitHubEvents::PULL_REQUEST => 'onPullRequest',
66+
];
67+
}
68+
}

src/Subscriber/MilestoneNewPRSubscriber.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public function onPullRequest(GitHubEvent $event)
3131
{
3232
$data = $event->getData();
3333
$repository = $event->getRepository();
34-
if ('opened' !== $data['action']) {
34+
if (!in_array($data['action'], ['opened', 'ready_for_review']) || ($data['pull_request']['draft'] ?? false)) {
3535
return;
3636
}
3737

src/Subscriber/NeedsReviewNewPRSubscriber.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public function onPullRequest(GitHubEvent $event)
2424
{
2525
$data = $event->getData();
2626
$repository = $event->getRepository();
27-
if ('opened' !== $action = $data['action']) {
27+
if (!in_array($data['action'], ['opened', 'ready_for_review']) || ($data['pull_request']['draft'] ?? false)) {
2828
return;
2929
}
3030

src/Subscriber/WelcomeFirstTimeContributorSubscriber.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public function __construct(IssueApi $commentsApi, PullRequestApi $pullRequestAp
2525
public function onPullRequest(GitHubEvent $event)
2626
{
2727
$data = $event->getData();
28-
if ('opened' !== $data['action']) {
28+
if (!in_array($data['action'], ['opened', 'ready_for_review']) || ($data['pull_request']['draft'] ?? false)) {
2929
return;
3030
}
3131

0 commit comments

Comments
 (0)