diff --git a/app/config/github.yml b/app/config/github.yml index ab16fd14..d4b10781 100644 --- a/app/config/github.yml +++ b/app/config/github.yml @@ -26,12 +26,19 @@ services: arguments: - '@app.github.cached_labels_api' + app.subscriber.status_change_by_review_subscriber: + class: AppBundle\Subscriber\StatusChangeByReviewSubscriber + arguments: + - '@app.status_api' + - '@logger' + parameters: # point to the main symfony repositories repositories: symfony/symfony: subscribers: - app.subscriber.status_change_by_comment_subscriber + - app.subscriber.status_change_by_review_subscriber - app.subscriber.needs_review_new_pr_subscriber - app.subscriber.bug_label_new_issue_subscriber - app.subscriber.auto_label_pr_from_content_subscriber @@ -41,6 +48,7 @@ parameters: subscribers: - app.subscriber.status_change_by_comment_subscriber - app.subscriber.status_change_on_push_subscriber + - app.subscriber.status_change_by_review_subscriber - app.subscriber.needs_review_new_pr_subscriber - app.subscriber.bug_label_new_issue_subscriber - app.subscriber.auto_label_pr_from_content_subscriber @@ -51,6 +59,7 @@ parameters: subscribers: - app.subscriber.status_change_by_comment_subscriber - app.subscriber.status_change_on_push_subscriber + - app.subscriber.status_change_by_review_subscriber - app.subscriber.needs_review_new_pr_subscriber - app.subscriber.bug_label_new_issue_subscriber - app.subscriber.auto_label_pr_from_content_subscriber diff --git a/composer.json b/composer.json index 371766bf..9c2b0964 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,8 @@ "knplabs/github-api": "^1.4" }, "require-dev": { - "sensio/generator-bundle": "~2.3" + "sensio/generator-bundle": "~2.3", + "phpunit/phpunit": "^5.0" }, "scripts": { "post-root-package-install": [ diff --git a/composer.lock b/composer.lock index db9e20b9..f95bacc0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "02846ac26c66c1194933ff53981db8e6", - "content-hash": "9295a0324313faa7514af320fc4a0f51", + "content-hash": "c4b42c11e2aa627f9ff0b039705abb63", "packages": [ { "name": "doctrine/annotations", @@ -73,7 +72,7 @@ "docblock", "parser" ], - "time": "2015-08-31 12:32:49" + "time": "2015-08-31T12:32:49+00:00" }, { "name": "doctrine/cache", @@ -143,7 +142,7 @@ "cache", "caching" ], - "time": "2015-12-03 10:50:37" + "time": "2015-12-03T10:50:37+00:00" }, { "name": "doctrine/collections", @@ -209,7 +208,7 @@ "collections", "iterator" ], - "time": "2015-04-14 22:21:58" + "time": "2015-04-14T22:21:58+00:00" }, { "name": "doctrine/common", @@ -282,7 +281,7 @@ "persistence", "spl" ], - "time": "2015-12-04 13:06:46" + "time": "2015-12-04T13:06:46+00:00" }, { "name": "doctrine/dbal", @@ -345,7 +344,7 @@ "persistence", "queryobject" ], - "time": "2015-01-12 21:57:01" + "time": "2015-01-12T21:57:01+00:00" }, { "name": "doctrine/doctrine-bundle", @@ -423,7 +422,7 @@ "orm", "persistence" ], - "time": "2015-11-16 17:11:46" + "time": "2015-11-16T17:11:46+00:00" }, { "name": "doctrine/doctrine-cache-bundle", @@ -510,7 +509,7 @@ "cache", "caching" ], - "time": "2015-11-27 04:59:07" + "time": "2015-11-27T04:59:07+00:00" }, { "name": "doctrine/inflector", @@ -577,7 +576,7 @@ "singularize", "string" ], - "time": "2015-11-06 14:35:42" + "time": "2015-11-06T14:35:42+00:00" }, { "name": "doctrine/lexer", @@ -631,7 +630,7 @@ "lexer", "parser" ], - "time": "2014-09-09 13:34:57" + "time": "2014-09-09T13:34:57+00:00" }, { "name": "doctrine/orm", @@ -704,7 +703,7 @@ "database", "orm" ], - "time": "2015-08-31 13:19:01" + "time": "2015-08-31T13:19:01+00:00" }, { "name": "guzzle/guzzle", @@ -799,7 +798,8 @@ "rest", "web service" ], - "time": "2015-03-18 18:23:50" + "abandoned": "guzzlehttp/guzzle", + "time": "2015-03-18T18:23:50+00:00" }, { "name": "incenteev/composer-parameter-handler", @@ -850,7 +850,7 @@ "keywords": [ "parameters management" ], - "time": "2015-11-10 17:04:01" + "time": "2015-11-10T17:04:01+00:00" }, { "name": "jdorn/sql-formatter", @@ -900,7 +900,7 @@ "highlight", "sql" ], - "time": "2014-01-12 16:20:24" + "time": "2014-01-12T16:20:24+00:00" }, { "name": "knplabs/github-api", @@ -961,7 +961,7 @@ "gist", "github" ], - "time": "2015-10-11 02:38:28" + "time": "2015-10-11T02:38:28+00:00" }, { "name": "kriswallsmith/assetic", @@ -1038,7 +1038,7 @@ "compression", "minification" ], - "time": "2015-11-12 13:51:40" + "time": "2015-11-12T13:51:40+00:00" }, { "name": "monolog/monolog", @@ -1115,7 +1115,7 @@ "logging", "psr-3" ], - "time": "2015-10-14 12:51:02" + "time": "2015-10-14T12:51:02+00:00" }, { "name": "psr/log", @@ -1153,7 +1153,7 @@ "psr", "psr-3" ], - "time": "2012-12-21 11:40:51" + "time": "2012-12-21T11:40:51+00:00" }, { "name": "sensio/distribution-bundle", @@ -1213,7 +1213,7 @@ "configuration", "distribution" ], - "time": "2015-11-26 18:10:31" + "time": "2015-11-26T18:10:31+00:00" }, { "name": "sensio/framework-extra-bundle", @@ -1268,7 +1268,7 @@ "annotations", "controllers" ], - "time": "2015-10-28 15:47:04" + "time": "2015-10-28T15:47:04+00:00" }, { "name": "sensiolabs/security-checker", @@ -1312,7 +1312,7 @@ } ], "description": "A security checker for your composer.lock", - "time": "2015-11-07 08:07:40" + "time": "2015-11-07T08:07:40+00:00" }, { "name": "swiftmailer/swiftmailer", @@ -1365,7 +1365,7 @@ "mail", "mailer" ], - "time": "2015-06-06 14:19:39" + "time": "2015-06-06T14:19:39+00:00" }, { "name": "symfony/assetic-bundle", @@ -1435,7 +1435,7 @@ "compression", "minification" ], - "time": "2015-11-17 09:45:47" + "time": "2015-11-17T09:45:47+00:00" }, { "name": "symfony/monolog-bundle", @@ -1494,7 +1494,7 @@ "log", "logging" ], - "time": "2015-11-17 10:02:29" + "time": "2015-11-17T10:02:29+00:00" }, { "name": "symfony/swiftmailer-bundle", @@ -1551,7 +1551,7 @@ ], "description": "Symfony SwiftmailerBundle", "homepage": "http://symfony.com", - "time": "2015-11-28 10:59:29" + "time": "2015-11-28T10:59:29+00:00" }, { "name": "symfony/symfony", @@ -1675,7 +1675,7 @@ "keywords": [ "framework" ], - "time": "2015-11-23 11:58:08" + "time": "2015-11-23T11:58:08+00:00" }, { "name": "twig/twig", @@ -1736,10 +1736,1218 @@ "keywords": [ "templating" ], - "time": "2015-11-05 12:49:06" + "time": "2015-11-05T12:49:06+00:00" } ], "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "^6.2.3", + "squizlabs/php_codesniffer": "^3.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2017-07-22T11:58:36+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "8e6e04167378abf1ddb4d3522d8755c5fd90d102" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/8e6e04167378abf1ddb4d3522d8755c5fd90d102", + "reference": "8e6e04167378abf1ddb4d3522d8755c5fd90d102", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "doctrine/collections": "1.*", + "phpunit/phpunit": "~4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "homepage": "https://github.com/myclabs/DeepCopy", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2017-04-12T18:52:22+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2017-09-11T18:02:19+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "4.1.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "2d3d238c433cf69caeb4842e97a3223a116f94b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/2d3d238c433cf69caeb4842e97a3223a116f94b2", + "reference": "2d3d238c433cf69caeb4842e97a3223a116f94b2", + "shasum": "" + }, + "require": { + "php": "^7.0", + "phpdocumentor/reflection-common": "^1.0@dev", + "phpdocumentor/type-resolver": "^0.4.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2017-08-30T18:51:59+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2017-07-14T14:27:02+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "v1.7.2", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6", + "reference": "c9b8c6088acd19d769d4cc0ffa60a9fe34344bd6", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", + "sebastian/comparator": "^1.1|^2.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8 || ^5.6.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2017-09-04T11:05:03+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "4.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef7b2f56815df854e66ceaee8ebe9393ae36a40d", + "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^5.6 || ^7.0", + "phpunit/php-file-iterator": "^1.3", + "phpunit/php-text-template": "^1.2", + "phpunit/php-token-stream": "^1.4.2 || ^2.0", + "sebastian/code-unit-reverse-lookup": "^1.0", + "sebastian/environment": "^1.3.2 || ^2.0", + "sebastian/version": "^1.0 || ^2.0" + }, + "require-dev": { + "ext-xdebug": "^2.1.4", + "phpunit/phpunit": "^5.7" + }, + "suggest": { + "ext-xdebug": "^2.5.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2017-04-02T07:44:40+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2016-10-03T07:40:28+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2017-02-26T11:10:40+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "9a02332089ac48e704c70f6cefed30c224e3c0b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/9a02332089ac48e704c70f6cefed30c224e3c0b0", + "reference": "9a02332089ac48e704c70f6cefed30c224e3c0b0", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.2.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2017-08-20T05:47:52+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "5.7.22", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "10df877596c9906d4110b5b905313829043f2ada" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/10df877596c9906d4110b5b905313829043f2ada", + "reference": "10df877596c9906d4110b5b905313829043f2ada", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "~1.3", + "php": "^5.6 || ^7.0", + "phpspec/prophecy": "^1.6.2", + "phpunit/php-code-coverage": "^4.0.4", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "^1.0.6", + "phpunit/phpunit-mock-objects": "^3.2", + "sebastian/comparator": "^1.2.4", + "sebastian/diff": "^1.4.3", + "sebastian/environment": "^1.3.4 || ^2.0", + "sebastian/exporter": "~2.0", + "sebastian/global-state": "^1.1", + "sebastian/object-enumerator": "~2.0", + "sebastian/resource-operations": "~1.0", + "sebastian/version": "~1.0.3|~2.0", + "symfony/yaml": "~2.1|~3.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-xdebug": "*", + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.7.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2017-09-24T07:23:38+00:00" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "3.4.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "a23b761686d50a560cc56233b9ecf49597cc9118" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/a23b761686d50a560cc56233b9ecf49597cc9118", + "reference": "a23b761686d50a560cc56233b9ecf49597cc9118", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.6 || ^7.0", + "phpunit/php-text-template": "^1.2", + "sebastian/exporter": "^1.2 || ^2.0" + }, + "conflict": { + "phpunit/phpunit": "<5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.4" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2017-06-30T09:13:00+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2017-03-04T06:30:41+00:00" + }, + { + "name": "sebastian/comparator", + "version": "1.2.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2 || ~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2017-01-29T09:50:25+00:00" + }, + { + "name": "sebastian/diff", + "version": "1.4.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2017-05-22T07:24:03+00:00" + }, + { + "name": "sebastian/environment", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2016-11-26T07:53:53+00:00" + }, + { + "name": "sebastian/exporter", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~2.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2016-11-19T08:54:04+00:00" + }, + { + "name": "sebastian/global-state", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2015-10-12T03:26:01+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7", + "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7", + "shasum": "" + }, + "require": { + "php": ">=5.6", + "sebastian/recursion-context": "~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2017-02-18T15:18:39+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2016-11-19T07:33:16+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2015-07-28T20:34:47+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-10-03T07:35:21+00:00" + }, { "name": "sensio/generator-bundle", "version": "v2.5.3", @@ -1786,7 +2994,57 @@ } ], "description": "This bundle generates code for you", - "time": "2015-03-17 06:36:52" + "time": "2015-03-17T06:36:52+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", + "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2016-11-23T20:04:58+00:00" } ], "aliases": [], diff --git a/src/AppBundle/GitHubEvents.php b/src/AppBundle/GitHubEvents.php index c91a9701..43990a28 100644 --- a/src/AppBundle/GitHubEvents.php +++ b/src/AppBundle/GitHubEvents.php @@ -53,6 +53,9 @@ final class GitHubEvents /** @Event('\AppBundle\Event\GitHubEvent') */ const PR_REVIEW_COMMENT = 'github.pull_request_review_comment'; + /** @Event('\AppBundle\Event\GithubEvent') */ + const PULL_REQUEST_REVIEW = 'github.pull_request_review'; + /** @Event('\AppBundle\Event\GitHubEvent') */ const PULL_REQUEST = 'github.pull_request'; diff --git a/src/AppBundle/Subscriber/AbstractStatusChangeSubscriber.php b/src/AppBundle/Subscriber/AbstractStatusChangeSubscriber.php new file mode 100644 index 00000000..a4b55717 --- /dev/null +++ b/src/AppBundle/Subscriber/AbstractStatusChangeSubscriber.php @@ -0,0 +1,47 @@ + Status::NEEDS_REVIEW, + 'needs work' => Status::NEEDS_WORK, + 'works for me' => Status::WORKS_FOR_ME, + 'reviewed' => Status::REVIEWED, + ]; + + protected $statusApi; + + public function __construct(StatusApi $statusApi) + { + $this->statusApi = $statusApi; + } + + /** + * Parses the text and looks for keywords to see if this should cause any + * status change. + * + * @param string $body + * + * @return null|string + */ + protected function parseStatusFromText($body) + { + $triggerWord = implode('|', array_keys(static::$triggerWordToStatus)); + $formatting = '[\\s\\*]*'; + // Match first character after "status:" + // Case insensitive ("i"), ignores formatting with "*" before or after the ":" + $pattern = "~(?=\n|^)${formatting}status${formatting}:${formatting}[\"']?($triggerWord)[\"']?${formatting}[.!]?${formatting}(?<=\r\n|\n|$)~i"; + + if (preg_match_all($pattern, $body, $matches)) { + // Second subpattern = first status character + return static::$triggerWordToStatus[strtolower(end($matches[1]))]; + } + } +} + diff --git a/src/AppBundle/Subscriber/StatusChangeByCommentSubscriber.php b/src/AppBundle/Subscriber/StatusChangeByCommentSubscriber.php index bf7330e0..2367c40f 100644 --- a/src/AppBundle/Subscriber/StatusChangeByCommentSubscriber.php +++ b/src/AppBundle/Subscriber/StatusChangeByCommentSubscriber.php @@ -7,23 +7,14 @@ use AppBundle\Issues\Status; use AppBundle\Issues\StatusApi; use Psr\Log\LoggerInterface; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; -class StatusChangeByCommentSubscriber implements EventSubscriberInterface +class StatusChangeByCommentSubscriber extends AbstractStatusChangeSubscriber { - private static $triggerWordToStatus = [ - 'needs review' => Status::NEEDS_REVIEW, - 'needs work' => Status::NEEDS_WORK, - 'works for me' => Status::WORKS_FOR_ME, - 'reviewed' => Status::REVIEWED, - ]; - - private $statusApi; private $logger; public function __construct(StatusApi $statusApi, LoggerInterface $logger) { - $this->statusApi = $statusApi; + parent::__construct($statusApi); $this->logger = $logger; } @@ -37,36 +28,24 @@ public function onIssueComment(GitHubEvent $event) { $data = $event->getData(); $repository = $event->getRepository(); - $newStatus = null; $issueNumber = $data['issue']['number']; + $newStatus = $this->parseStatusFromText($data['comment']['body']); - $triggerWord = implode('|', array_keys(static::$triggerWordToStatus)); - $formatting = '[\\s\\*]*'; - // Match first character after "status:" - // Case insensitive ("i"), ignores formatting with "*" before or after the ":" - $pattern = "~(?=\n|^)${formatting}status${formatting}:${formatting}[\"']?($triggerWord)[\"']?${formatting}[.!]?${formatting}(?<=\r\n|\n|$)~i"; - - if (preg_match_all($pattern, $data['comment']['body'], $matches)) { - // Second subpattern = first status character - $newStatus = static::$triggerWordToStatus[strtolower(end($matches[1]))]; - - if (Status::REVIEWED === $newStatus && false === $this->checkUserIsAllowedToReview($data)) { - $event->setResponseData(array( - 'issue' => $issueNumber, - 'status_change' => null, - )); - - return; - } - - $this->logger->debug(sprintf('Setting issue number %s to status %s', $issueNumber, $newStatus)); - $this->statusApi->setIssueStatus($issueNumber, $newStatus, $repository); + if (Status::REVIEWED === $newStatus && false === $this->isUserAllowedToReview($data)) { + $newStatus = null; } $event->setResponseData(array( 'issue' => $issueNumber, 'status_change' => $newStatus, )); + + if (null === $newStatus) { + return; + } + + $this->logger->debug(sprintf('Setting issue number %s to status %s', $issueNumber, $newStatus)); + $this->statusApi->setIssueStatus($issueNumber, $newStatus, $repository); } public static function getSubscribedEvents() @@ -76,7 +55,7 @@ public static function getSubscribedEvents() ); } - private function checkUserIsAllowedToReview(array $data) + private function isUserAllowedToReview(array $data) { return $data['issue']['user']['login'] !== $data['comment']['user']['login']; } diff --git a/src/AppBundle/Subscriber/StatusChangeByReviewSubscriber.php b/src/AppBundle/Subscriber/StatusChangeByReviewSubscriber.php new file mode 100644 index 00000000..72c13883 --- /dev/null +++ b/src/AppBundle/Subscriber/StatusChangeByReviewSubscriber.php @@ -0,0 +1,115 @@ + + */ +class StatusChangeByReviewSubscriber extends AbstractStatusChangeSubscriber +{ + private $logger; + + public function __construct(StatusApi $statusApi, LoggerInterface $logger) + { + parent::__construct($statusApi); + $this->logger = $logger; + } + + /** + * Sets the status based on the review state (approved/changes requested) + * or the review body (using the Status: keyword). + * + * @param GithubEvent $event + */ + public function onReview(GitHubEvent $event) + { + $data = $event->getData(); + if ('submitted' !== $data['action']) { + $event->setResponseData(array('unsupported_action' => $data['action'])); + + return; + } + + $repository = $event->getRepository(); + $pullRequestNumber = $data['pull_request']['number']; + $newStatus = null; + + // Set status based on review state + switch (strtolower($data['review']['state'])) { + case 'approved': + $newStatus = Status::REVIEWED; + + break; + case 'changes_requested': + $newStatus = Status::NEEDS_WORK; + + break; + default: + $newStatus = $this->parseStatusFromText($data['review']['body']); + } + + if (Status::REVIEWED === $newStatus && false === $this->isUserAllowedToReview($data)) { + $newStatus = null; + } + + $event->setResponseData(array( + 'pull_request' => $pullRequestNumber, + 'status_change' => $newStatus, + )); + + if (null === $newStatus) { + return; + } + + $this->logger->debug(sprintf('Setting issue number %s to status %s', $pullRequestNumber, $newStatus)); + $this->statusApi->setIssueStatus($pullRequestNumber, $newStatus, $repository); + } + + /** + * Sets the status to needs review when a review is requested. + * + * @param GithubEvent $event + */ + public function onReviewRequested(GithubEvent $event) + { + $data = $event->getData(); + if ('review_requested' !== $data['action']) { + $event->setResponseData(array('unsupported_action' => $data['action'])); + + return; + } + + $repository = $event->getRepository(); + $pullRequestNumber = $data['pull_request']['number']; + $newStatus = Status::NEEDS_REVIEW; + + $this->logger->debug(sprintf('Setting issue number %s to status %s', $pullRequestNumber, $newStatus)); + $this->statusApi->setIssueStatus($pullRequestNumber, $newStatus, $repository); + + $event->setResponseData(array( + 'pull_request' => $pullRequestNumber, + 'status_change' => $newStatus, + )); + } + + public static function getSubscribedEvents() + { + return array( + GitHubEvents::PULL_REQUEST_REVIEW => 'onReview', + GitHubEvents::PULL_REQUEST => 'onReviewRequested', + ); + } + + private function isUserAllowedToReview(array $data) + { + return $data['pull_request']['user']['login'] !== $data['review']['user']['login']; + } +} diff --git a/src/AppBundle/Tests/Subscriber/StatusChangeByReviewSubscriberTest.php b/src/AppBundle/Tests/Subscriber/StatusChangeByReviewSubscriberTest.php new file mode 100644 index 00000000..92b1b0bd --- /dev/null +++ b/src/AppBundle/Tests/Subscriber/StatusChangeByReviewSubscriberTest.php @@ -0,0 +1,142 @@ +statusApi = $this->getMock('AppBundle\Issues\StatusApi'); + $logger = $this->getMock('Psr\Log\LoggerInterface'); + $this->statusChangeSubscriber = new StatusChangeByReviewSubscriber($this->statusApi, $logger); + $this->repository = new Repository('weaverryan', 'symfony', [], null); + + $this->dispatcher = new EventDispatcher(); + $this->dispatcher->addSubscriber($this->statusChangeSubscriber); + } + + /** + * @dataProvider getCommentsForStatusChange + */ + public function testOnReview($comment, $expectedStatus) + { + if (null !== $expectedStatus) { + $this->statusApi->expects($this->once()) + ->method('setIssueStatus') + ->with(1234, $expectedStatus); + } + + $event = new GitHubEvent(array( + 'action' => 'submitted', + 'pull_request' => array('number' => 1234, 'user' => ['login' => 'weaverryan']), + 'review' => array('state' => 'commented', 'body' => $comment, 'user' => ['login' => 'leannapelham']), + ), $this->repository); + + $this->dispatcher->dispatch(GitHubEvents::PULL_REQUEST_REVIEW, $event); + + $responseData = $event->getResponseData(); + + $this->assertCount(2, $responseData); + $this->assertSame(1234, $responseData['pull_request']); + $this->assertSame($expectedStatus, $responseData['status_change']); + } + + public function getCommentsForStatusChange() + { + return array( + array('Have a great day!', null), + // basic tests for status change + array('Status: needs review', Status::NEEDS_REVIEW), + array('Status: needs work', Status::NEEDS_WORK), + array('Status: reviewed', Status::REVIEWED), + // accept quotes + array('Status: "reviewed"', Status::REVIEWED), + array("Status: 'reviewed'", Status::REVIEWED), + // accept trailing punctuation + array('Status: works for me!', Status::WORKS_FOR_ME), + array('Status: works for me.', Status::WORKS_FOR_ME), + // play with different formatting + array('STATUS: REVIEWED', Status::REVIEWED), + array('**Status**: reviewed', Status::REVIEWED), + array('**Status:** reviewed', Status::REVIEWED), + array('**Status: reviewed**', Status::REVIEWED), + array('**Status: reviewed!**', Status::REVIEWED), + array('**Status: reviewed**.', Status::REVIEWED), + array('Status:reviewed', Status::REVIEWED), + array('Status: reviewed', Status::REVIEWED), + // reject missing colon + array('Status reviewed', null), + // multiple matches - use the last one + array("Status: needs review \r\n that is what the issue *was* marked as.\r\n Status: reviewed", Status::REVIEWED), + // "needs review" does not come directly after status: , so there is no status change + array('Here is my status: I\'m really happy! I realize this needs review, but I\'m, having too much fun Googling cats!', null), + // reject if the status is not on a line of its own + // use case: someone posts instructions about how to change a status + // in a comment + array('You should include e.g. the line `Status: needs review` in your comment', null), + array('Before the ticket was in state "Status: reviewed", but then the status was changed', null), + ); + } + + public function testOnIssueCommentAuthorSelfReview() + { + $this->statusApi->expects($this->never()) + ->method('setIssueStatus') + ; + + $user = array('login' => 'weaverryan'); + + $event = new GitHubEvent(array( + 'action' => 'submitted', + 'pull_request' => array( + 'number' => 1234, + 'user' => $user, + ), + 'review' => array( + 'state' => 'commented', + 'body' => 'Status: reviewed', + 'user' => $user, + ), + ), $this->repository); + + $this->dispatcher->dispatch(GitHubEvents::PULL_REQUEST_REVIEW, $event); + + $responseData = $event->getResponseData(); + + $this->assertCount(2, $responseData); + $this->assertSame(1234, $responseData['pull_request']); + $this->assertNull($responseData['status_change']); + } + + public function testOnReviewRequested() + { + $this->statusApi->expects($this->once()) + ->method('setIssueStatus') + ->with(1234, Status::NEEDS_REVIEW); + + $event = new GitHubEvent(array( + 'action' => 'review_requested', + 'pull_request' => array('number' => 1234) + ), $this->repository); + + $this->dispatcher->dispatch(GitHubEvents::PULL_REQUEST, $event); + } +}