diff --git a/src/Git/Value/SemVerVersion.php b/src/Git/Value/SemVerVersion.php index c6f3a220..04883395 100644 --- a/src/Git/Value/SemVerVersion.php +++ b/src/Git/Value/SemVerVersion.php @@ -79,6 +79,11 @@ public function isNewMinorRelease(): bool return $this->patch === 0; } + public function isNewMajorRelease(): bool + { + return $this->minor === 0 && $this->patch === 0; + } + public function lessThanEqual(self $other): bool { return $this->fullReleaseName() <= $other->fullReleaseName(); diff --git a/src/Github/Api/V3/CreateMilestoneThroughApiCall.php b/src/Github/Api/V3/CreateMilestoneThroughApiCall.php index 72951d49..190aeaf8 100644 --- a/src/Github/Api/V3/CreateMilestoneThroughApiCall.php +++ b/src/Github/Api/V3/CreateMilestoneThroughApiCall.php @@ -63,6 +63,7 @@ public function __invoke(RepositoryName $repository, SemVerVersion $version): vo ->getBody() ->write(json_encode([ 'title' => $version->fullReleaseName(), + 'description' => $this->milestoneDescription($version), ])); $response = $this->client->sendRequest($request); @@ -93,4 +94,17 @@ public function __invoke(RepositoryName $repository, SemVerVersion $version): vo $version->fullReleaseName() )); } + + private function milestoneDescription(SemVerVersion $version): string + { + if ($version->isNewMajorRelease()) { + return 'Backwards incompatible release (major)'; + } + + if ($version->isNewMinorRelease()) { + return 'Feature release (minor)'; + } + + return sprintf('%s bugfix release (patch)', $version->targetReleaseBranchName()->name()); + } } diff --git a/test/unit/Git/Value/SemVerVersionTest.php b/test/unit/Git/Value/SemVerVersionTest.php index 6d55587c..2630fb76 100644 --- a/test/unit/Git/Value/SemVerVersionTest.php +++ b/test/unit/Git/Value/SemVerVersionTest.php @@ -119,6 +119,38 @@ public function newMinorReleasesProvider(): array ]; } + /** + * @dataProvider newMajorReleasesProvider + */ + public function testIsNewMajorRelease(string $milestoneName, bool $expected): void + { + self::assertSame( + $expected, + SemVerVersion::fromMilestoneName($milestoneName) + ->isNewMajorRelease() + ); + } + + /** + * @return array> + * + * @psalm-return array + */ + public function newMajorReleasesProvider(): array + { + return [ + ['3.0.1', false], + ['3.0.0', true], + ['2.0.10', false], + ['2.0.0', true], + ['1.0.0', true], + ['1.1.0', false], + ['1.1.1', false], + ['1.1.2', false], + ['1.1.90', false], + ]; + } + /** * @dataProvider lessThanEqualProvider */ diff --git a/test/unit/Github/Api/V3/CreateMilestoneTest.php b/test/unit/Github/Api/V3/CreateMilestoneTest.php index 373e1557..d05e6089 100644 --- a/test/unit/Github/Api/V3/CreateMilestoneTest.php +++ b/test/unit/Github/Api/V3/CreateMilestoneTest.php @@ -87,6 +87,7 @@ public function testSuccessfulRequest(): void self::assertJsonStringEqualsJsonString( <<<'JSON' { + "description": "1.2.x bugfix release (patch)", "title": "1.2.3" } JSON, @@ -146,7 +147,8 @@ public function testExistingMilestone(): void self::assertJsonStringEqualsJsonString( <<<'JSON' { - "title": "1.2.3" + "description": "Feature release (minor)", + "title": "2.1.0" } JSON, $request->getBody()->__toString() @@ -160,7 +162,59 @@ public function testExistingMilestone(): void $this->createMilestone->__invoke( RepositoryName::fromFullName('foo/bar'), - SemVerVersion::fromMilestoneName('1.2.3') + SemVerVersion::fromMilestoneName('2.1.0') + ); + } + + public function testMajorMilestone(): void + { + $this->messageFactory + ->expects(self::any()) + ->method('createRequest') + ->with('POST', 'https://api.github.com/repos/foo/bar/milestones') + ->willReturn(new Request('https://the-domain.com/the-path')); + + $validResponse = (new Response())->withStatus(201); + + $validResponse->getBody()->write( + <<<'JSON' + { + "html_url": "http://another-domain.com/the-pr" + } + JSON + ); + + $this->httpClient + ->expects(self::once()) + ->method('sendRequest') + ->with(self::callback(function (RequestInterface $request): bool { + self::assertSame( + [ + 'Host' => ['the-domain.com'], + 'Content-Type' => ['application/json'], + 'User-Agent' => ['Ocramius\'s minimal API V3 client'], + 'Authorization' => ['token ' . $this->apiToken], + ], + $request->getHeaders() + ); + + self::assertJsonStringEqualsJsonString( + <<<'JSON' + { + "description": "Backwards incompatible release (major)", + "title": "3.0.0" + } + JSON, + $request->getBody()->__toString() + ); + + return true; + })) + ->willReturn($validResponse); + + $this->createMilestone->__invoke( + RepositoryName::fromFullName('foo/bar'), + SemVerVersion::fromMilestoneName('3.0.0') ); } }