Skip to content

Commit 32c5276

Browse files
committed
Make sure we are actually closing issues too
1 parent 2ee79eb commit 32c5276

File tree

7 files changed

+104
-2
lines changed

7 files changed

+104
-2
lines changed

config/services.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ services:
8383

8484
Github\Api\Issue\Comments:
8585
factory: ['@Github\Api\Issue', comments]
86+
calls:
87+
- [ 'setPerPage', [ 100 ] ]
8688

8789
App\Api\Issue\IssueApi: '@App\Api\Issue\GithubIssueApi'
8890
App\Api\Label\LabelApi: '@App\Api\Label\GithubLabelApi'

src/Api/Issue/GithubIssueApi.php

+8
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ public function open(Repository $repository, string $title, string $body, array
4444
}
4545
}
4646

47+
public function lastCommentWasMadeByBot(Repository $repository, $number): bool
48+
{
49+
$allComments = $this->issueCommentApi->all($repository->getVendor(), $repository->getName(), $number);
50+
$lastComment = $allComments[count($allComments) - 1] ?? [];
51+
52+
return $this->botUsername === ($lastComment['user']['login'] ?? null);
53+
}
54+
4755
public function close(Repository $repository, $issueNumber)
4856
{
4957
$this->issueApi->update($repository->getVendor(), $repository->getName(), $issueNumber, ['state' => 'closed']);

src/Api/Issue/IssueApi.php

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ public function open(Repository $repository, string $title, string $body, array
1919

2020
public function commentOnIssue(Repository $repository, $issueNumber, string $commentBody);
2121

22+
public function lastCommentWasMadeByBot(Repository $repository, $number): bool;
23+
2224
/**
2325
* Close an issue or a pull request.
2426
*/

src/Api/Issue/NullIssueApi.php

+5
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ public function commentOnIssue(Repository $repository, $issueNumber, string $com
1414
{
1515
}
1616

17+
public function lastCommentWasMadeByBot(Repository $repository, $number): bool
18+
{
19+
return false;
20+
}
21+
1722
public function close(Repository $repository, $issueNumber)
1823
{
1924
}

src/Command/CloseStaleIssuesCommand.php

+7-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
namespace App\Command;
44

55
use App\Api\Issue\IssueApi;
6+
use App\Entity\Task;
67
use App\Service\RepositoryProvider;
8+
use App\Service\TaskScheduler;
79
use Symfony\Component\Console\Command\Command;
810
use Symfony\Component\Console\Input\InputArgument;
911
use Symfony\Component\Console\Input\InputInterface;
@@ -19,12 +21,14 @@ class CloseStaleIssuesCommand extends Command
1921
protected static $defaultName = 'app:issue:close-stale';
2022
private $repositoryProvider;
2123
private $issueApi;
24+
private $scheduler;
2225

23-
public function __construct(RepositoryProvider $repositoryProvider, IssueApi $issueApi)
26+
public function __construct(RepositoryProvider $repositoryProvider, IssueApi $issueApi, TaskScheduler $scheduler)
2427
{
2528
parent::__construct();
2629
$this->repositoryProvider = $repositoryProvider;
2730
$this->issueApi = $issueApi;
31+
$this->scheduler = $scheduler;
2832
}
2933

3034
protected function configure()
@@ -57,7 +61,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
5761
TXT
5862
);
5963

60-
// TODO add a scheduled task to process this issue again after 2 weeks
64+
// add a scheduled task to process this issue again after 2 weeks
65+
$this->scheduler->runLater($repository, $issue['number'], Task::ACTION_CLOSE_STALE, new \DateTimeImmutable('+2weeks'));
6166
}
6267

6368
return 0;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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\Label\LabelApi;
9+
use App\Api\PullRequest\PullRequestApi;
10+
use App\Entity\Task;
11+
use App\Service\RepositoryProvider;
12+
13+
/**
14+
* @author Tobias Nyholm <[email protected]>
15+
*/
16+
class CloseStaleIssuesHandler implements TaskHandlerInterface
17+
{
18+
private $issueApi;
19+
private $repositoryProvider;
20+
private $labelApi;
21+
22+
public function __construct(LabelApi $labelApi, IssueApi $issueApi, RepositoryProvider $repositoryProvider)
23+
{
24+
$this->issueApi = $issueApi;
25+
$this->repositoryProvider = $repositoryProvider;
26+
$this->labelApi = $labelApi;
27+
}
28+
29+
/**
30+
* Close the issue if the last comment was made by the bot and if "Keep open" label does not exist.
31+
*/
32+
public function handle(Task $task): void
33+
{
34+
$repository = $this->repositoryProvider->getRepository($task->getRepositoryFullName());
35+
$labels = $this->labelApi->getIssueLabels($task->getNumber(), $repository);
36+
if (in_array('Keep open', $labels)) {
37+
return;
38+
}
39+
40+
if ($this->issueApi->lastCommentWasMadeByBot($repository, $task->getNumber())) {
41+
$this->issueApi->close($repository, $task->getNumber());
42+
}
43+
}
44+
45+
public function supports(Task $task): bool
46+
{
47+
return Task::ACTION_CLOSE_STALE === $task->getAction();
48+
}
49+
}

src/Service/TaskScheduler.php

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Service;
6+
7+
use App\Entity\Task;
8+
use App\Model\Repository;
9+
use App\Repository\TaskRepository;
10+
11+
/**
12+
* Schedule a job to run later.
13+
*
14+
* @author Tobias Nyholm <[email protected]>
15+
*/
16+
class TaskScheduler
17+
{
18+
private $taskRepo;
19+
20+
public function __construct(TaskRepository $taskRepo)
21+
{
22+
$this->taskRepo = $taskRepo;
23+
}
24+
25+
public function runLater(Repository $repository, $number, int $action, \DateTimeImmutable $checkAt)
26+
{
27+
$task = new Task($repository->getFullName(), $number, $action, $checkAt);
28+
$this->taskRepo->persist($task);
29+
$this->taskRepo->flush();
30+
}
31+
}

0 commit comments

Comments
 (0)