diff --git a/.gitignore b/.gitignore index 271c399..5d25b3d 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,7 @@ !/var/sessions /var/sessions/* !var/sessions/.gitkeep -!var/SymfonyRequirements.php /vendor/ /web/bundles/ -var/bootstrap.php.cache \ No newline at end of file +var/bootstrap.php.cache +web/config.php \ No newline at end of file diff --git a/app/Resources/views/markdown/pr_commit_name_nok.md.twig b/app/Resources/views/markdown/pr_commit_name_nok.md.twig new file mode 100644 index 0000000..e853ebd --- /dev/null +++ b/app/Resources/views/markdown/pr_commit_name_nok.md.twig @@ -0,0 +1,35 @@ + +Hi! + +These(s) commit(s) name(s) seems to be incomplete or malformed, regarding our [guidelines](http://doc.prestashop.com/display/PS16/How+to+write+a+commit+message): + +{% if commits|length > 1 %} + + + + + {% for commit in commits %} + + + + {% endfor %} +
Malformed commits
{{ commit }}
+{% else %} +

`{{ commits[0] }}` is malformed or incomplete.

+{% endif %} + +A valid commit name can be, for instance: + +``` +BO: Shows company in BO search if B2B is enabled +``` + +Would you mind to amend your commits' names? + +To do this, open a command line window and use `git commit --amend` for the commit's name. See [GitHub's help page](https://help.github.com/articles/changing-a-commit-message/) for more information. + +_Note: this **must** be done via the command line: you can't do this just by changing the title of the pull-request from the GitHub interface!_ :) + +Thank you! + +(note: this is an automated message, but answering it will reach a real human ) diff --git a/app/Resources/views/markdown/pr_table_errors.md.twig b/app/Resources/views/markdown/pr_table_errors.md.twig index ff48ea1..6450100 100644 --- a/app/Resources/views/markdown/pr_table_errors.md.twig +++ b/app/Resources/views/markdown/pr_table_errors.md.twig @@ -1,3 +1,4 @@ + Hi! Your pull request description seems to be incomplete or malformed: diff --git a/app/config/services.yml b/app/config/services.yml index 84536a7..25e7b0f 100644 --- a/app/config/services.yml +++ b/app/config/services.yml @@ -20,7 +20,7 @@ services: class: Github\Api\Issue factory: ['@app.github.client', api] arguments: [issue] - + app.github.comments_api: class: Github\Api\Issue\Comments factory: ['@app.github.issues_api', comments] @@ -34,7 +34,7 @@ services: class: Github\Api\Repo factory: ['@app.github.client', api] arguments: [repository] - + app.github.organizations_api: class: Github\Api\Organization factory: ['@app.github.client', api] @@ -49,6 +49,15 @@ services: class: Github\Api\Issue\Labels factory: ['@app.github.issues_api', labels] + app.github.gitdata_api: + class: Github\Api\GitData + factory: ['@app.github.client', api] + arguments: [gitData] + + app.github.commits_api: + class: Github\Api\GitData\Commits + factory: ['@app.github.gitdata_api', commits] + # Application GitHub API app.github.cached_labels_api: @@ -75,7 +84,11 @@ services: app.pullrequest_listener: class: AppBundle\PullRequests\Listener - arguments: ['@app.comment_api', '@validator', '@app.pull_request.repository'] + arguments: + - '@app.comment_api' + - '@app.commit.repository' + - '@validator' + - '@app.pull_request.repository' # Event subscribers @@ -127,6 +140,14 @@ services: class: AppBundle\Search\Repository arguments: ['@app.github.search_api', '%repository_username%', '%repository_name%'] + app.commit.repository: + class: AppBundle\Commits\Repository + arguments: + - '@app.github.commits_api' + - '@app.github.pullrequests_api' + - '%repository_username%' + - '%repository_name%' + # Reporters app.pull_requests.reporter: diff --git a/app/config/services_test.yml b/app/config/services_test.yml index acb6bd7..1738a08 100644 --- a/app/config/services_test.yml +++ b/app/config/services_test.yml @@ -20,4 +20,8 @@ services: # Your integrations tests shouldn't post comments to github app.pullrequest_listener: class: Tests\AppBundle\PullRequests\FakeListener - arguments: ['@app.comment_api', '@validator', '@twig'] \ No newline at end of file + arguments: + - '@app.comment_api' + - '@validator' + - '@twig' + - '@app.commit.repository' diff --git a/composer.json b/composer.json index 0338e39..1dcd896 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ "sensio/distribution-bundle": "^5.0", "sensio/framework-extra-bundle": "^3.0.2", "incenteev/composer-parameter-handler": "^2.0", - "knplabs/github-api": "^1.4", + "knplabs/github-api": "^1.7", "lp-digital/github-event-parser": "~0.7" }, "require-dev": { diff --git a/composer.lock b/composer.lock index bd37ecf..b0782dd 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "7642775cc7d2542fb9184fb334cf977e", - "content-hash": "44b67e63045c5eee64f703a510dd918d", + "hash": "2fd2a90c965a809426c7ca97dd559dcb", + "content-hash": "53c6ef4b5ed7bf90d051032893168c82", "packages": [ { "name": "doctrine/annotations", @@ -1033,16 +1033,16 @@ }, { "name": "lp-digital/github-event-parser", - "version": "v0.7.6.1", + "version": "v0.7.7", "source": { "type": "git", "url": "https://github.com/Lp-digital/github-event-parser.git", - "reference": "753c4aa6121075665d6ae982895ef23029096d0a" + "reference": "bf0a198b24ad3546d41c79d9716be2517b5e11fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Lp-digital/github-event-parser/zipball/753c4aa6121075665d6ae982895ef23029096d0a", - "reference": "753c4aa6121075665d6ae982895ef23029096d0a", + "url": "https://api.github.com/repos/Lp-digital/github-event-parser/zipball/bf0a198b24ad3546d41c79d9716be2517b5e11fc", + "reference": "bf0a198b24ad3546d41c79d9716be2517b5e11fc", "shasum": "" }, "require": { @@ -1080,7 +1080,7 @@ "github", "json parser" ], - "time": "2016-07-27 12:05:31" + "time": "2016-10-06 14:39:23" }, { "name": "monolog/monolog", @@ -1256,22 +1256,30 @@ }, { "name": "psr/log", - "version": "1.0.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" + "reference": "5277094ed527a1c4477177d102fe4c53551953e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", + "url": "https://api.github.com/repos/php-fig/log/zipball/5277094ed527a1c4477177d102fe4c53551953e0", + "reference": "5277094ed527a1c4477177d102fe4c53551953e0", "shasum": "" }, + "require": { + "php": ">=5.3.0" + }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, "autoload": { - "psr-0": { - "Psr\\Log\\": "" + "psr-4": { + "Psr\\Log\\": "Psr/Log/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1285,25 +1293,26 @@ } ], "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", "keywords": [ "log", "psr", "psr-3" ], - "time": "2012-12-21 11:40:51" + "time": "2016-09-19 16:02:08" }, { "name": "sensio/distribution-bundle", - "version": "v5.0.11", + "version": "v5.0.12", "source": { "type": "git", "url": "https://github.com/sensiolabs/SensioDistributionBundle.git", - "reference": "fc3d3998527726761e140715e6e439780a31eec4" + "reference": "b6dcd04595e4db95ead22ddea58c397864e00c32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sensiolabs/SensioDistributionBundle/zipball/fc3d3998527726761e140715e6e439780a31eec4", - "reference": "fc3d3998527726761e140715e6e439780a31eec4", + "url": "https://api.github.com/repos/sensiolabs/SensioDistributionBundle/zipball/b6dcd04595e4db95ead22ddea58c397864e00c32", + "reference": "b6dcd04595e4db95ead22ddea58c397864e00c32", "shasum": "" }, "require": { @@ -1342,7 +1351,7 @@ "configuration", "distribution" ], - "time": "2016-09-12 14:16:31" + "time": "2016-09-14 20:25:12" }, { "name": "sensio/framework-extra-bundle", @@ -2041,16 +2050,16 @@ }, { "name": "twig/twig", - "version": "v1.24.2", + "version": "v1.26.1", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "33093f6e310e6976baeac7b14f3a6ec02f2d79b7" + "reference": "a09d8ee17ac1cfea29ed60c83960ad685c6a898d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/33093f6e310e6976baeac7b14f3a6ec02f2d79b7", - "reference": "33093f6e310e6976baeac7b14f3a6ec02f2d79b7", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/a09d8ee17ac1cfea29ed60c83960ad685c6a898d", + "reference": "a09d8ee17ac1cfea29ed60c83960ad685c6a898d", "shasum": "" }, "require": { @@ -2063,7 +2072,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.24-dev" + "dev-master": "1.26-dev" } }, "autoload": { @@ -2098,7 +2107,7 @@ "keywords": [ "templating" ], - "time": "2016-09-01 17:50:53" + "time": "2016-10-05 18:57:41" } ], "packages-dev": [ @@ -2158,16 +2167,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.5.3", + "version": "1.5.4", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "94e5ca3e90aa5b34663780393e10914f7438f991" + "reference": "ea74994a3dc7f8d2f65a06009348f2d63c81e61f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/94e5ca3e90aa5b34663780393e10914f7438f991", - "reference": "94e5ca3e90aa5b34663780393e10914f7438f991", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/ea74994a3dc7f8d2f65a06009348f2d63c81e61f", + "reference": "ea74994a3dc7f8d2f65a06009348f2d63c81e61f", "shasum": "" }, "require": { @@ -2196,7 +2205,7 @@ "object", "object graph" ], - "time": "2016-09-07 15:34:10" + "time": "2016-09-16 13:37:59" }, { "name": "phpdocumentor/reflection-common", @@ -2254,16 +2263,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "3.1.0", + "version": "3.1.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "9270140b940ff02e58ec577c237274e92cd40cdd" + "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9270140b940ff02e58ec577c237274e92cd40cdd", - "reference": "9270140b940ff02e58ec577c237274e92cd40cdd", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e", + "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e", "shasum": "" }, "require": { @@ -2295,7 +2304,7 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2016-06-10 09:48:41" + "time": "2016-09-30 07:12:33" }, { "name": "phpdocumentor/type-resolver", @@ -2730,16 +2739,16 @@ }, { "name": "phpunit/phpunit-mock-objects", - "version": "3.2.7", + "version": "3.3.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "546898a2c0c356ef2891b39dd7d07f5d82c8ed0a" + "reference": "03500345483e1e17b52e2e4d34a89c9408ab2902" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/546898a2c0c356ef2891b39dd7d07f5d82c8ed0a", - "reference": "546898a2c0c356ef2891b39dd7d07f5d82c8ed0a", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/03500345483e1e17b52e2e4d34a89c9408ab2902", + "reference": "03500345483e1e17b52e2e4d34a89c9408ab2902", "shasum": "" }, "require": { @@ -2785,7 +2794,7 @@ "mock", "xunit" ], - "time": "2016-09-06 16:07:45" + "time": "2016-10-04 11:03:26" }, { "name": "sebastian/code-unit-reverse-lookup", diff --git a/src/AppBundle/Commits/Repository.php b/src/AppBundle/Commits/Repository.php new file mode 100644 index 0000000..42a00f7 --- /dev/null +++ b/src/AppBundle/Commits/Repository.php @@ -0,0 +1,59 @@ +commitsApi = $commitsApi; + $this->pullRequestApi = $pullRequestApi; + $this->repositoryUsername = $repositoryUsername; + $this->repositoryName = $repositoryName; + } + + public function findAllByPullRequest(PullRequest $pullRequest) + { + $responseApi = $this->pullRequestApi->commits( + $this->repositoryUsername, + $this->repositoryName, + $pullRequest->getNumber() + ); + + $commits = []; + foreach ($responseApi as $commitApi) { + $commits[] = Commit::createFromData($commitApi['commit']); + } + + return $commits; + } +} diff --git a/src/AppBundle/EventSubscriber/PullRequestSubscriber.php b/src/AppBundle/EventSubscriber/PullRequestSubscriber.php index f581bd3..466d18e 100644 --- a/src/AppBundle/EventSubscriber/PullRequestSubscriber.php +++ b/src/AppBundle/EventSubscriber/PullRequestSubscriber.php @@ -24,8 +24,11 @@ public static function getSubscribedEvents() ['welcomePeople', 253], ['checkForNewTranslations', 252], ['initLabels', 254], + ['checkCommits', 252], ], 'pullrequestevent_edited' => [ + ['removePullRequestValidationComment', 255], + ['removeCommitValidationComment', 255], ['removePrestonBotComment', 255], ['checkForNewTranslations', 252], ], @@ -62,7 +65,7 @@ public function checkForTableDescription(GitHubEvent $githubEvent) $this->container ->get('app.pullrequest_listener') - ->handlePullRequestCreatedEvent($pullRequest, $pullRequest->getCommitSha()) + ->checkForTableDescription($pullRequest) ; $githubEvent->addStatus([ @@ -73,7 +76,25 @@ public function checkForTableDescription(GitHubEvent $githubEvent) } /** - * if a call to trans or l function is done, add + * Validate the commits name. + */ + public function checkCommits(GitHubEvent $githubEvent) + { + $pullRequest = $githubEvent->getEvent()->pullRequest; + + $this->container + ->get('app.pullrequest_listener') + ->checkCommits($pullRequest) + ; + + $githubEvent->addStatus([ + 'event' => 'pr_opened', + 'action' => 'commits labels checked', + ]); + } + + /** + * If a call to trans or l function is done, add * "waiting for wording" label. */ public function checkForNewTranslations(GitHubEvent $githubEvent) @@ -113,7 +134,7 @@ public function welcomePeople(GitHubEvent $githubEvent) /** * @todo: create functional test in WebhookController */ - public function removePrestonBotComment(GithubEvent $githubEvent) + public function removePullRequestValidationComment(GithubEvent $githubEvent) { $pullRequest = $githubEvent->getEvent()->pullRequest; @@ -123,7 +144,7 @@ public function removePrestonBotComment(GithubEvent $githubEvent) $this->container ->get('app.pullrequest_listener') - ->handlePullRequestEditedEvent($pullRequest) + ->removePullRequestValidationComment($pullRequest) ; $githubEvent->addStatus([ @@ -132,4 +153,27 @@ public function removePrestonBotComment(GithubEvent $githubEvent) ]) ; } + + /** + * @todo: create functional test in WebhookController + */ + public function removeCommitValidationComment(GithubEvent $githubEvent) + { + $pullRequest = $githubEvent->getEvent()->pullRequest; + + if ($pullRequest->isClosed() || $pullRequest->isMerged()) { + return; + } + + $this->container + ->get('app.pullrequest_listener') + ->removeCommitValidationComment($pullRequest) + ; + + $githubEvent->addStatus([ + 'event' => 'pr_edited', + 'action' => 'preston validation commit comment removed', + ]) + ; + } } diff --git a/src/AppBundle/PullRequests/CommitParser.php b/src/AppBundle/PullRequests/CommitParser.php new file mode 100644 index 0000000..730c1e1 --- /dev/null +++ b/src/AppBundle/PullRequests/CommitParser.php @@ -0,0 +1,29 @@ +message = $message; + $this->pullRequest = $pullRequest; + } + + public function getMessage() + { + return $this->message; + } +} diff --git a/src/AppBundle/PullRequests/Listener.php b/src/AppBundle/PullRequests/Listener.php index 3bef3a0..07a67ab 100644 --- a/src/AppBundle/PullRequests/Listener.php +++ b/src/AppBundle/PullRequests/Listener.php @@ -3,6 +3,7 @@ namespace AppBundle\PullRequests; use AppBundle\Comments\CommentApi; +use AppBundle\Commits\Repository as CommitRepository; use Lpdigital\Github\Entity\PullRequest; use AppBundle\PullRequests\Repository as PullRequestRepository; use Symfony\Component\Validator\Validator\ValidatorInterface; @@ -10,22 +11,27 @@ class Listener { private $commentApi; + private $commitRepository; private $validator; private $repository; const PRESTONBOT_NAME = 'prestonBot'; + const TABLE_ERROR = 'PR_TABLE_DESCRIPTION_ERROR'; + const COMMIT_ERROR = 'PR_COMMIT_NAME_ERROR'; public function __construct( CommentApi $commentApi, + CommitRepository $commitRepository, ValidatorInterface $validator, PullRequestRepository $repository ) { $this->commentApi = $commentApi; + $this->commitRepository = $commitRepository; $this->validator = $validator; $this->repository = $repository; } - public function handlePullRequestCreatedEvent(PullRequest $pullRequest, $commitId) + public function checkForTableDescription(PullRequest $pullRequest) { $bodyParser = new BodyParser($pullRequest->getBody()); @@ -39,15 +45,82 @@ public function handlePullRequestCreatedEvent(PullRequest $pullRequest, $commitI } } - public function handlePullRequestEditedEvent(PullRequest $pullRequest) + /** + * @todo: if Pull request description is valid, proposal can be improved. + */ + public function checkCommits(PullRequest $pullRequest) { - $prestonComments = $this->repository - ->getCommentsFrom($pullRequest, self::PRESTONBOT_NAME) - ; + $commitErrors = $this->getErrorsFromCommits($pullRequest); - if (count($prestonComments) > 0) { - $validationComment = $prestonComments[0]; - $this->commentApi->remove($validationComment->getId()); + if ($commitErrors > 0) { + $this->commentApi->sendWithTemplate( + $pullRequest, + 'markdown/pr_commit_name_nok.md.twig', + ['commits' => $commitErrors] + ); } } + + public function removePullRequestValidationComment(PullRequest $pullRequest) + { + $bodyParser = new BodyParser($pullRequest->getBody()); + + $bodyErrors = $this->validator->validate($bodyParser); + if (0 === count($bodyErrors)) { + $this->removeCommentsIfExists($pullRequest, self::TABLE_ERROR); + } + } + + public function removeCommitValidationComment(PullRequest $pullRequest) + { + if (0 === $this->getErrorsFromCommits($pullRequest)) { + $this->removeCommentsIfExists($pullRequest, self::COMMIT_ERROR); + } + } + + /** + * Wrap the validation of commits. + * + * @return array error messages if any. + */ + public function getErrorsFromCommits(PullRequest $pullRequest) + { + $commits = $this->commitRepository->findAllByPullRequest($pullRequest); + $commitsErrors = []; + + foreach ($commits as $commit) { + $commitLabel = $commit->getMessage(); + $commitParser = new CommitParser($commitLabel, $pullRequest); + $validationErrors = $this->validator->validate($commitParser); + + if (count($validationErrors) > 0) { + $commitsErrors[] = $commitLabel; + } + } + + return $commitsErrors; + } + + /** + * Wraps the remove of existing PrestonBot comments. + * + * @param PullRequest the pull request + * @param $pattern expression to filter comments in CommentApi + */ + public function removeCommentsIfExists(PullRequest $pullRequest, $pattern) + { + $comments = $this->repository + ->getCommentsByExpressionFrom( + $pullRequest, + $pattern, + self::PRESTONBOT_NAME + ) + ; + + if (count($comments) > 0) { + foreach ($comments as $comment) { + $this->commentApi->remove($comment->getId()); + } + } + } } diff --git a/src/AppBundle/PullRequests/Repository.php b/src/AppBundle/PullRequests/Repository.php index e48df42..5cfd0ae 100644 --- a/src/AppBundle/PullRequests/Repository.php +++ b/src/AppBundle/PullRequests/Repository.php @@ -14,6 +14,7 @@ */ class Repository { + private $pullRequestRepository; private $searchRepository; private $commentsApi; @@ -89,10 +90,10 @@ public function getComments(PullRequest $pullRequest) /** * Return Comments of selected user if any. - * + * * @param PullRequest Lpdigital\Github\Entity\PullRequest * @param string login from Entity User of Comment entry - * + * * @return array collection of user's comments */ public function getCommentsFrom(PullRequest $pullRequest, $userLogin) @@ -109,6 +110,31 @@ public function getCommentsFrom(PullRequest $pullRequest, $userLogin) return $userComments; } + /** + * Return Comments of selected user if any, filtered by expression. + * + * @param PullRequest Lpdigital\Github\Entity\PullRequest + * @param string login from Entity User of Comment entry + * + * @return array collection of user's filtered comments + */ + public function getCommentsByExpressionFrom( + PullRequest $pullRequest, + $expression, + $userLogin + ) { + $userCommentsByExpression = []; + $userComments = $this->getCommentsFrom($pullRequest, $userLogin); + + foreach ($userComments as $userComment) { + if (strpos($userComment->getBody(), $expression)) { + $userCommentsByExpression[] = $userComment; + } + } + + return $userCommentsByExpression; + } + private function parseLabel($label) { return '"'.$label.'"'; diff --git a/tests/AppBundle/Controller/WebhookControllerTest.php b/tests/AppBundle/Controller/WebhookControllerTest.php index 12b853c..efa5b76 100644 --- a/tests/AppBundle/Controller/WebhookControllerTest.php +++ b/tests/AppBundle/Controller/WebhookControllerTest.php @@ -9,7 +9,7 @@ class WebhookControllerTest extends WebTestCase /** * @dataProvider getTests */ - public function testIssueComment($eventHeader, $payloadFilename, $expectedResponse) + public function testActions($eventHeader, $payloadFilename, $expectedResponse) { $client = $this->createClient(); $client->enableProfiler(); @@ -32,7 +32,7 @@ public function testIssueComment($eventHeader, $payloadFilename, $expectedRespon public function getTests() { $tests = []; - $tests[] = [ + $tests['Issue comments'] = [ 'issue_comment', 'issue_comment.created.json', [ @@ -42,7 +42,7 @@ public function getTests() ], ], ]; - $tests[] = [ + $tests['Pull request creation'] = [ 'pull_request', 'pull_request.opened.json', [ @@ -62,9 +62,12 @@ public function getTests() 'event' => 'pr_opened', 'action' => 'checked for new translations', ], + [ + 'event' => 'pr_opened', + 'action' => 'commits labels checked'] ], ]; - $tests[] = [ + $tests['Add labels'] = [ 'issues', 'issues.labeled.bug.json', [ @@ -74,7 +77,7 @@ public function getTests() ], ], ]; - $tests[] = [ + $tests['Ignore labels'] = [ 'issues', 'issues.labeled.feature.json', [ @@ -84,7 +87,7 @@ public function getTests() ], ], ]; - $tests[] = [ + $tests['Pull request on wrong repository'] = [ 'pull_request', 'wrong_repository.pull_request.json', [], diff --git a/tests/AppBundle/PullRequests/CommitParserTest.php b/tests/AppBundle/PullRequests/CommitParserTest.php new file mode 100644 index 0000000..5535cc8 --- /dev/null +++ b/tests/AppBundle/PullRequests/CommitParserTest.php @@ -0,0 +1,61 @@ + + */ +class CommitParserTest extends WebTestCase +{ + public static $kernel; + public static $pullRequest; + + public function setUp() + { + $kernel = self::getKernelClass(); + + self::$kernel = new $kernel('dev', true); + self::$kernel->boot(); + + self::$pullRequest = $this->createMock(PullRequest::class); + } + + /** + * dump test for coverage. + */ + public function testGetMessage() + { + $parser = new CommitParser('foo', self::$pullRequest); + $this->assertSame($parser->getMessage(), 'foo'); + } + + /** + * @dataProvider getCommits + */ + public function testValidation($label, $expected) + { + $validator = self::$kernel->getContainer()->get('validator'); + $parser = new CommitParser($label, self::$pullRequest); + + $validationsErrors = $validator->validate($parser); + $isValid = (count($validationsErrors) === 0); + + $this->assertTrue($isValid === $expected); + } + + public static function getCommits() + { + return [ + ['bo: fixed stuff', false], + ['fixed stuff', false], + ['BO: fixed stuff', true], + ['BA: fixed stuff', false], + ['FO : fixed stuff', false], + ['IN: installation process ok', true], + ]; + } +} diff --git a/tests/AppBundle/PullRequests/FakeListener.php b/tests/AppBundle/PullRequests/FakeListener.php index 4ad757f..511b17f 100644 --- a/tests/AppBundle/PullRequests/FakeListener.php +++ b/tests/AppBundle/PullRequests/FakeListener.php @@ -3,7 +3,9 @@ namespace tests\AppBundle\PullRequests; use AppBundle\Comments\CommentApi; +use AppBundle\Commits\Repository as CommitRepository; use AppBundle\PullRequests\BodyParser; +use AppBundle\PullRequests\CommitParser; use Lpdigital\Github\Entity\PullRequest; use Symfony\Component\Validator\Validator\ValidatorInterface; use Twig_Environment; @@ -14,17 +16,23 @@ class FakeListener { private $commentApi; + private $commitRepository; private $validator; private $twig; - public function __construct(CommentApi $commentApi, ValidatorInterface $validator, Twig_Environment $twig) - { + public function __construct( + CommentApi $commentApi, + ValidatorInterface $validator, + Twig_Environment $twig, + CommitRepository $commitRepository + ) { $this->commentApi = $commentApi; + $this->commitRepository = $commitRepository; $this->validator = $validator; $this->twig = $twig; } - public function handlePullRequestCreatedEvent(PullRequest $pullRequest, $commitId) + public function checkForTableDescription(PullRequest $pullRequest) { $bodyParser = new BodyParser($pullRequest->getBody()); @@ -36,7 +44,29 @@ public function handlePullRequestCreatedEvent(PullRequest $pullRequest, $commitI } } - public function handlePullRequestEditedEvent(PullRequest $pullRequest) + public function checkCommits(PullRequest $pullRequest) + { + $commits = $this->commitRepository->findAllByPullRequest($pullRequest); + $validationErrors = []; + + foreach ($commits as $commit) { + $commitLabel = $commit->getMessage(); + $commitParser = new CommitParser($commitLabel, $pullRequest); + $commitErrors = $this->validator->validate($commitParser); + + if (count($commitErrors) > 0) { + $validationErrors[] = $commitLabel; + } + } + + if (count($validationErrors) > 0) { + $bodyMessage = $this->twig->render('markdown/pr_commit_name_nok.md.twig', ['commits' => $validationErrors]); + + return true; + } + } + + public function removePullRequestValidationComment(PullRequest $pullRequest) { $prestonComments = $this->repository ->getCommentsFrom($pullRequest, self::PRESTONBOT_NAME) diff --git a/tests/AppBundle/webhook_examples/pull_request.opened.json b/tests/AppBundle/webhook_examples/pull_request.opened.json index 3d850db..3c0c219 100644 --- a/tests/AppBundle/webhook_examples/pull_request.opened.json +++ b/tests/AppBundle/webhook_examples/pull_request.opened.json @@ -1,6 +1,6 @@ { "action": "opened", - "number": 3, + "number": 1, "pull_request": { "url": "https://api.github.com/repos/weaverryan/symfony/pulls/3", "id": 38727018, @@ -8,7 +8,7 @@ "diff_url": "https://github.com/weaverryan/symfony/pull/3.diff", "patch_url": "https://github.com/weaverryan/symfony/pull/3.patch", "issue_url": "https://api.github.com/repos/weaverryan/symfony/issues/3", - "number": 3, + "number": 1, "state": "open", "locked": false, "title": "Testing PR", diff --git a/tests/AppBundle/webhook_examples/wrong_repository.pull_request.json b/tests/AppBundle/webhook_examples/wrong_repository.pull_request.json index 0f60694..dc94c6a 100644 --- a/tests/AppBundle/webhook_examples/wrong_repository.pull_request.json +++ b/tests/AppBundle/webhook_examples/wrong_repository.pull_request.json @@ -1,6 +1,6 @@ { "action": "opened", - "number": 3, + "number": 1, "pull_request": { "url": "https://api.github.com/repos/weaverryan/symfony/pulls/3", "id": 38727018, @@ -8,7 +8,7 @@ "diff_url": "https://github.com/weaverryan/symfony/pull/3.diff", "patch_url": "https://github.com/weaverryan/symfony/pull/3.patch", "issue_url": "https://api.github.com/repos/weaverryan/symfony/issues/3", - "number": 3, + "number": 1, "state": "open", "locked": false, "title": "Testing PR", diff --git a/var/SymfonyRequirements.php b/var/SymfonyRequirements.php index 2299704..b59a59f 100644 --- a/var/SymfonyRequirements.php +++ b/var/SymfonyRequirements.php @@ -739,9 +739,9 @@ function_exists('posix_isatty'), if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { $this->addRecommendation( - $this->getRealpathCacheSize() > 5 * 1024 * 1024, - 'realpath_cache_size should be above 5242880 in php.ini', - 'Setting "realpath_cache_size" to e.g. "5242880" or "5000k" in php.ini* may improve performance on Windows significantly in some cases.' + $this->getRealpathCacheSize() >= 5 * 1024 * 1024, + 'realpath_cache_size should be at least 5M in php.ini', + 'Setting "realpath_cache_size" to e.g. "5242880" or "5M" in php.ini* may improve performance on Windows significantly in some cases.' ); }