Skip to content

Commit d4d2cbc

Browse files
committed
feature #134 Add warning when PR is opened to an unsupported branch (Nyholm)
This PR was squashed before being merged into the master branch. Discussion ---------- Add warning when PR is opened to an unsupported branch This will fix #126 TODO: - [x] Add tests Commits ------- 16f946c Add warning when PR is opened to an unsupported branch
2 parents ef8ca12 + 16f946c commit d4d2cbc

File tree

5 files changed

+218
-3
lines changed

5 files changed

+218
-3
lines changed

config/services.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ parameters:
1111
- 'App\Subscriber\MilestoneNewPRSubscriber'
1212
- 'App\Subscriber\WelcomeFirstTimeContributorSubscriber'
1313
- 'App\Subscriber\CloseDraftPRSubscriber'
14+
- 'App\Subscriber\UnsupportedBranchSubscriber'
1415
- 'App\Subscriber\RemoveStalledLabelOnCommentSubscriber'
1516
secret: '%env(SYMFONY_SECRET)%'
1617

@@ -23,6 +24,7 @@ parameters:
2324
- 'App\Subscriber\NeedsReviewNewPRSubscriber'
2425
- 'App\Subscriber\BugLabelNewIssueSubscriber'
2526
- 'App\Subscriber\AutoLabelFromContentSubscriber'
27+
- 'App\Subscriber\UnsupportedBranchSubscriber'
2628
- 'subscriber.symfony_docs.milestone'
2729
- 'App\Subscriber\RemoveStalledLabelOnCommentSubscriber'
2830
secret: '%env(SYMFONY_DOCS_SECRET)%'
@@ -40,6 +42,7 @@ parameters:
4042
- 'App\Subscriber\MilestoneNewPRSubscriber'
4143
- 'App\Subscriber\WelcomeFirstTimeContributorSubscriber'
4244
- 'App\Subscriber\CloseDraftPRSubscriber'
45+
- 'App\Subscriber\UnsupportedBranchSubscriber'
4346
- 'App\Subscriber\RemoveStalledLabelOnCommentSubscriber'
4447

4548
services:

src/Service/SymfonyVersionProvider.php

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public function __construct(HttpClientInterface $httpClient, CacheInterface $cac
2626
$this->cache = $cache;
2727
}
2828

29-
public function getCurrentVersion()
29+
public function getCurrentVersion(): string
3030
{
3131
$httpClient = $this->httpClient;
3232

@@ -40,9 +40,25 @@ public function getCurrentVersion()
4040
$version = $defaultValue;
4141
}
4242

43-
$item->expiresAfter($version === $defaultValue ? 300 : 604800);
43+
$item->expiresAfter($version === $defaultValue ? 300 : 86400);
4444

4545
return $version;
4646
});
4747
}
48+
49+
/**
50+
* @throws \RuntimeException
51+
*/
52+
public function getSupportedVersions(): array
53+
{
54+
$response = $this->httpClient->request('GET', 'https://symfony.com/releases.json');
55+
$data = $response->toArray(true);
56+
$versions = $data['supported_versions'] ?? null;
57+
58+
if (is_array($versions) && count($versions) > 0) {
59+
return $versions;
60+
}
61+
62+
throw new \RuntimeException('Could not fetch supported versions');
63+
}
4864
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
3+
namespace App\Subscriber;
4+
5+
use App\Api\Issue\IssueApi;
6+
use App\Event\GitHubEvent;
7+
use App\GitHubEvents;
8+
use App\Service\ComplementGenerator;
9+
use App\Service\SymfonyVersionProvider;
10+
use Psr\Log\LoggerInterface;
11+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
12+
13+
/**
14+
* @author Tobias Nyholm <[email protected]>
15+
*/
16+
class UnsupportedBranchSubscriber implements EventSubscriberInterface
17+
{
18+
private $symfonyVersionProvider;
19+
private $issueApi;
20+
private $complementGenerator;
21+
private $logger;
22+
23+
public function __construct(SymfonyVersionProvider $symfonyVersionProvider, IssueApi $issueApi, ComplementGenerator $complementGenerator, LoggerInterface $logger)
24+
{
25+
$this->symfonyVersionProvider = $symfonyVersionProvider;
26+
27+
$this->issueApi = $issueApi;
28+
$this->complementGenerator = $complementGenerator;
29+
$this->logger = $logger;
30+
}
31+
32+
/**
33+
* Sets milestone on PRs that target non-default branch.
34+
*/
35+
public function onPullRequest(GitHubEvent $event)
36+
{
37+
$data = $event->getData();
38+
if (!in_array($data['action'], ['opened', 'ready_for_review']) || ($data['pull_request']['draft'] ?? false)) {
39+
return;
40+
}
41+
42+
$targetBranch = $data['pull_request']['base']['ref'];
43+
if ($targetBranch === $data['repository']['default_branch']) {
44+
return;
45+
}
46+
47+
try {
48+
$validBranches = $this->symfonyVersionProvider->getSupportedVersions();
49+
} catch (\Throwable $e) {
50+
$this->logger->error('Failed to get valid branches', ['exception' => $e]);
51+
52+
return;
53+
}
54+
55+
if (in_array($targetBranch, $validBranches)) {
56+
return;
57+
}
58+
59+
$number = $data['pull_request']['number'];
60+
$complement = $this->complementGenerator->getPullRequestComplement();
61+
$validBranchesString = implode(', ', $validBranches);
62+
$this->issueApi->commentOnIssue($event->getRepository(), $number, <<<TXT
63+
Hey!
64+
65+
$complement
66+
67+
But you have made this PR towards a branch that is not maintained anymore. :/
68+
Could you update the [PR base branch](https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/changing-the-base-branch-of-a-pull-request) to target one of these branches instead? $validBranchesString.
69+
70+
Cheers!
71+
72+
Carsonbot
73+
TXT
74+
);
75+
76+
$event->setResponseData([
77+
'pull_request' => $number,
78+
'unsupported_branch' => $targetBranch,
79+
]);
80+
}
81+
82+
public static function getSubscribedEvents()
83+
{
84+
return [
85+
GitHubEvents::PULL_REQUEST => 'onPullRequest',
86+
];
87+
}
88+
}

tests/Controller/WebhookControllerTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public function getTests()
5252
'On pull request opened' => [
5353
'pull_request',
5454
'pull_request.opened.json',
55-
['pull_request' => 3, 'status_change' => 'needs_review', 'pr_labels' => ['Console', 'Bug']],
55+
['pull_request' => 3, 'status_change' => 'needs_review', 'pr_labels' => ['Console', 'Bug'], 'unsupported_branch' => '2.5'],
5656
],
5757
'On draft pull request opened' => [
5858
'pull_request',
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<?php
2+
3+
namespace App\Tests\Subscriber;
4+
5+
use App\Api\Issue\IssueApi;
6+
use App\Api\Issue\NullIssueApi;
7+
use App\Event\GitHubEvent;
8+
use App\GitHubEvents;
9+
use App\Model\Repository;
10+
use App\Service\ComplementGenerator;
11+
use App\Service\SymfonyVersionProvider;
12+
use App\Subscriber\UnsupportedBranchSubscriber;
13+
use PHPUnit\Framework\TestCase;
14+
use Psr\Log\NullLogger;
15+
use Symfony\Component\EventDispatcher\EventDispatcher;
16+
17+
class UnsupportedBranchSubscriberTest extends TestCase
18+
{
19+
/**
20+
* @var IssueApi
21+
*/
22+
private $issueApi;
23+
24+
/**
25+
* @var Repository
26+
*/
27+
private $repository;
28+
29+
/**
30+
* @var EventDispatcher
31+
*/
32+
private $dispatcher;
33+
34+
protected function setUp()
35+
{
36+
$this->issueApi = $this->createMock(NullIssueApi::class);
37+
$symfonyVersionProvider = $this->getMockBuilder(SymfonyVersionProvider::class)
38+
->disableOriginalConstructor()
39+
->setMethods(['getSupportedVersions'])
40+
->getMock();
41+
$symfonyVersionProvider->method('getSupportedVersions')->willReturn(['4.4', '5.1']);
42+
43+
$subscriber = new UnsupportedBranchSubscriber($symfonyVersionProvider, $this->issueApi, new ComplementGenerator(), new NullLogger());
44+
$this->repository = new Repository('carsonbot-playground', 'symfony', null);
45+
46+
$this->dispatcher = new EventDispatcher();
47+
$this->dispatcher->addSubscriber($subscriber);
48+
}
49+
50+
public function testOnPullRequestOpen()
51+
{
52+
$this->issueApi->expects($this->once())
53+
->method('commentOnIssue');
54+
55+
$event = new GitHubEvent([
56+
'action' => 'opened',
57+
'pull_request' => [
58+
'number' => 1234,
59+
'base' => ['ref' => '4.3'],
60+
],
61+
'repository' => [
62+
'default_branch' => '5.x',
63+
],
64+
], $this->repository);
65+
66+
$this->dispatcher->dispatch($event, GitHubEvents::PULL_REQUEST);
67+
$responseData = $event->getResponseData();
68+
69+
$this->assertCount(2, $responseData);
70+
$this->assertSame(1234, $responseData['pull_request']);
71+
$this->assertSame('4.3', $responseData['unsupported_branch']);
72+
}
73+
74+
public function testOnPullRequestOpenDefaultBranch()
75+
{
76+
$this->issueApi->expects($this->never())
77+
->method('commentOnIssue');
78+
79+
$event = new GitHubEvent([
80+
'action' => 'opened',
81+
'pull_request' => [
82+
'number' => 1234,
83+
'base' => ['ref' => '4.4'],
84+
],
85+
'repository' => [
86+
'default_branch' => '5.x',
87+
],
88+
], $this->repository);
89+
90+
$this->dispatcher->dispatch($event, GitHubEvents::PULL_REQUEST);
91+
$responseData = $event->getResponseData();
92+
$this->assertEmpty($responseData);
93+
}
94+
95+
public function testOnPullRequestNotOpen()
96+
{
97+
$this->issueApi->expects($this->never())
98+
->method('commentOnIssue');
99+
100+
$event = new GitHubEvent([
101+
'action' => 'close',
102+
], $this->repository);
103+
104+
$this->dispatcher->dispatch($event, GitHubEvents::PULL_REQUEST);
105+
$responseData = $event->getResponseData();
106+
$this->assertEmpty($responseData);
107+
}
108+
}

0 commit comments

Comments
 (0)