diff --git a/app/Actions/TriggerDockerHubBuildAction.php b/app/Actions/TriggerDockerHubBuildAction.php new file mode 100644 index 0000000..04019e7 --- /dev/null +++ b/app/Actions/TriggerDockerHubBuildAction.php @@ -0,0 +1,21 @@ +image = $image; + } +} diff --git a/app/Jobs/TriggerDockerHubBuild.php b/app/Jobs/TriggerDockerHubBuild.php new file mode 100644 index 0000000..3be7b2f --- /dev/null +++ b/app/Jobs/TriggerDockerHubBuild.php @@ -0,0 +1,87 @@ +image = $image; + } + + /// + /// Task + /// + + /** + * Executes the job. + * + * @return void + */ + public function handle () { + $this->initializeReport(); + $this->triggerBuild(); + $this->sendReport(); + } + + /** + * Initializes the actions report. + */ + private function initializeReport () { + $this->actionToReport = new TriggerDockerHubBuildAction($this->image); + } + + /** + * Triggers a new Docker Hub build. + */ + private function triggerBuild () { + try { + DockerHub::build($this->image); + } catch (Exception $ex) { + $actionError = new ActionError($ex); + $this->actionToReport->attachError($actionError); + } + } + + /** + * Fires a report event with the actions report. + */ + private function sendReport () { + $event = new ReportEvent($this->actionToReport); + Event::fire($event); + } + +} diff --git a/app/Listeners/DockerHubListener.php b/app/Listeners/DockerHubListener.php new file mode 100644 index 0000000..10cbf3b --- /dev/null +++ b/app/Listeners/DockerHubListener.php @@ -0,0 +1,81 @@ +shouldNotify($event)) { + $this->notifyNewCommits($event); + } + } + + /** + * Determines if the event should be notified to Docker Hub. + * We're interested by push events, for repos with Docker images + * we've a token to trigger a build. + * + * @param GitHubPayloadEvent $event The GitHub payload event + * @return bool + */ + public function shouldNotify (GitHubPayloadEvent $event) { + return $event->event === 'push' + && DockerHub::hasToken($this->getRepository($event)); + } + + /** + * Notifies Phabricator there are new commits to pull. + * + * @param GitHubPayloadEvent $event The GitHub payload event + */ + public function notifyNewCommits (GitHubPayloadEvent $event) { + $job = new TriggerDockerHubBuild($this->getRepository($event)); + $job->handle(); + } + + /** + * Extracts repository fullname (e.g. acme/foo) from event. + * + * @var string + */ + private function getRepository (GitHubPayloadEvent $event) { + return $event->payload->repository->full_name; + } + + /// + /// Events listening + /// + + /** + * Registers the listeners for the subscriber. + * + * @param Dispatcher $events + */ + public function subscribe (Dispatcher $events) { + $class = DockerHubListener::class; + $events->listen( + GitHubPayloadEvent::class, + "$class@onGitHubPayload" + ); + } + +} diff --git a/composer.json b/composer.json index 54c4da5..d58dfb3 100644 --- a/composer.json +++ b/composer.json @@ -1,56 +1,56 @@ { "name": "nasqueron/notifications", "description": "Nasqueron notifications center", "keywords": [ "nasqueron", "activemq", "AMQP", "notifications" ], "license": "BSD-2-Clause", "type": "project", "require": { "php": ">=5.6.0", "laravel/framework": "5.2.*", "guzzlehttp/guzzle": "^6.2", - "keruald/dockerhub": "^0.0.2", + "keruald/dockerhub": "^0.0.3", "keruald/github": "^0.2.0", "keruald/broker": "^0.4.1", "keruald/mailgun": "^0.0.1", "netresearch/jsonmapper": "~0.1.0", "sentry/sentry": "^0.13.0" }, "require-dev": { "fzaninotto/faker": "~1.4", "mockery/mockery": "0.9.*", "phpmd/phpmd" : "@stable", "phpunit/phpunit": "~4.0", "phpspec/phpspec": "~2.1", "squizlabs/php_codesniffer": "2.*", "symfony/css-selector": "~3.0", "symfony/dom-crawler": "~3.0" }, "autoload": { "psr-4": { "Nasqueron\\Notifications\\": "app/", "Nasqueron\\Notifications\\Tests\\": "tests/" } }, "scripts": { "post-root-package-install": [ "php -r \"copy('.env.example', '.env');\"" ], "post-create-project-cmd": [ "php artisan key:generate" ], "phpmd": [ "vendor/bin/phpmd app/ xml ruleset.xml" ], "test": [ "phpunit --no-coverage" ] }, "config": { "preferred-install": "dist" } } diff --git a/config/app.php b/config/app.php index 240b539..5adae3b 100644 --- a/config/app.php +++ b/config/app.php @@ -1,266 +1,267 @@ env('APP_ENV', 'production'), /* |-------------------------------------------------------------------------- | Application Debug Mode |-------------------------------------------------------------------------- | | When your application is in debug mode, detailed error messages with | stack traces will be shown on every error that occurs within your | application. If disabled, a simple generic error page is shown. | */ 'debug' => env('APP_DEBUG', false), /* |-------------------------------------------------------------------------- | Application URL |-------------------------------------------------------------------------- | | This URL is used by the console to properly generate URLs when using | the Artisan command line tool. You should set this to the root of | your application so that it is used when running Artisan tasks. | */ 'url' => 'http://localhost', /* |-------------------------------------------------------------------------- | Application Timezone |-------------------------------------------------------------------------- | | Here you may specify the default timezone for your application, which | will be used by the PHP date and date-time functions. We have gone | ahead and set this to a sensible default for you out of the box. | */ 'timezone' => 'UTC', /* |-------------------------------------------------------------------------- | Application Locale Configuration |-------------------------------------------------------------------------- | | The application locale determines the default locale that will be used | by the translation service provider. You are free to set this value | to any of the locales which will be supported by the application. | */ 'locale' => 'en', /* |-------------------------------------------------------------------------- | Application Fallback Locale |-------------------------------------------------------------------------- | | The fallback locale determines the locale to use when the current one | is not available. You may change the value to correspond to any of | the language folders that are provided through your application. | */ 'fallback_locale' => 'en', /* |-------------------------------------------------------------------------- | Encryption Key |-------------------------------------------------------------------------- | | This key is used by the Illuminate encrypter service and should be set | to a random, 32 character string, otherwise these encrypted strings | will not be safe. Please do this before deploying an application! | */ 'key' => env('APP_KEY'), 'cipher' => 'AES-256-CBC', /* |-------------------------------------------------------------------------- | Logging Configuration |-------------------------------------------------------------------------- | | Here you may configure the log settings for your application. Out of | the box, Laravel uses the Monolog PHP logging library. This gives | you a variety of powerful log handlers / formatters to utilize. | | Available Settings: "single", "daily", "syslog", "errorlog" | */ 'log' => env('APP_LOG', 'single'), /* |-------------------------------------------------------------------------- | Features |-------------------------------------------------------------------------- | | This array contains the features provided by the notifications center. | | It allows to toggle a feature on the fly, with a boolean to enable it. | */ 'features' => [ // Enable the API entry point at the /gate URL 'Gate' => true, // Send a response to inform the caller of the different actions done. // If disabled, send an empty 200 response instead. 'ActionsReport' => true, ], /* |-------------------------------------------------------------------------- | Autoloaded Service Providers |-------------------------------------------------------------------------- | | The service providers listed here will be automatically loaded on the | request to your application. Feel free to add your own services to | this array to grant expanded functionality to your applications. | */ 'providers' => [ /* * Laravel Framework Service Providers... */ Illuminate\Broadcasting\BroadcastServiceProvider::class, Illuminate\Bus\BusServiceProvider::class, Illuminate\Cache\CacheServiceProvider::class, Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class, Illuminate\Cookie\CookieServiceProvider::class, Illuminate\Database\DatabaseServiceProvider::class, Illuminate\Encryption\EncryptionServiceProvider::class, Illuminate\Filesystem\FilesystemServiceProvider::class, Illuminate\Foundation\Providers\FoundationServiceProvider::class, Illuminate\Hashing\HashServiceProvider::class, Illuminate\Mail\MailServiceProvider::class, Illuminate\Pagination\PaginationServiceProvider::class, Illuminate\Pipeline\PipelineServiceProvider::class, Illuminate\Queue\QueueServiceProvider::class, Illuminate\Redis\RedisServiceProvider::class, Illuminate\Session\SessionServiceProvider::class, Illuminate\Translation\TranslationServiceProvider::class, Illuminate\Validation\ValidationServiceProvider::class, Illuminate\View\ViewServiceProvider::class, /* * Application Service Providers... */ Nasqueron\Notifications\Providers\AppServiceProvider::class, Nasqueron\Notifications\Providers\BrokerServiceProvider::class, Nasqueron\Notifications\Providers\DockerHubServiceProvider::class, Nasqueron\Notifications\Providers\EventServiceProvider::class, Nasqueron\Notifications\Providers\MailgunServiceProvider::class, Nasqueron\Notifications\Providers\PhabricatorAPIServiceProvider::class, Nasqueron\Notifications\Providers\PhabricatorProjectsMapServiceProvider::class, Nasqueron\Notifications\Providers\ReportServiceProvider::class, Nasqueron\Notifications\Providers\RouteServiceProvider::class, Nasqueron\Notifications\Providers\SentryServiceProvider::class, Nasqueron\Notifications\Providers\ServicesServiceProvider::class ], /* |-------------------------------------------------------------------------- | Events listeners |-------------------------------------------------------------------------- | | The events listeners listed here will be automatically loaded on the | request to your application. | */ 'listeners' => [ Nasqueron\Notifications\Listeners\AMQPEventListener::class, + Nasqueron\Notifications\Listeners\DockerHubListener::class, Nasqueron\Notifications\Listeners\LastPayloadSaver::class, Nasqueron\Notifications\Listeners\NotificationListener::class, Nasqueron\Notifications\Listeners\PhabricatorListener::class, ], /* |-------------------------------------------------------------------------- | Class Aliases |-------------------------------------------------------------------------- | | This array of class aliases will be registered when this application | is started. However, feel free to register as many as you wish as | the aliases are "lazy" loaded so they don't hinder performance. | */ 'aliases' => [ /* * Laravel Framework aliases... */ 'App' => Illuminate\Support\Facades\App::class, 'Artisan' => Illuminate\Support\Facades\Artisan::class, 'Auth' => Illuminate\Support\Facades\Auth::class, 'Blade' => Illuminate\Support\Facades\Blade::class, 'Bus' => Illuminate\Support\Facades\Bus::class, 'Cache' => Illuminate\Support\Facades\Cache::class, 'Config' => Illuminate\Support\Facades\Config::class, 'Cookie' => Illuminate\Support\Facades\Cookie::class, 'Crypt' => Illuminate\Support\Facades\Crypt::class, 'DB' => Illuminate\Support\Facades\DB::class, 'Eloquent' => Illuminate\Database\Eloquent\Model::class, 'Event' => Illuminate\Support\Facades\Event::class, 'File' => Illuminate\Support\Facades\File::class, 'Gate' => Illuminate\Support\Facades\Gate::class, 'Hash' => Illuminate\Support\Facades\Hash::class, 'Input' => Illuminate\Support\Facades\Input::class, 'Inspiring' => Illuminate\Foundation\Inspiring::class, 'Lang' => Illuminate\Support\Facades\Lang::class, 'Log' => Illuminate\Support\Facades\Log::class, 'Mail' => Illuminate\Support\Facades\Mail::class, 'Password' => Illuminate\Support\Facades\Password::class, 'Queue' => Illuminate\Support\Facades\Queue::class, 'Redirect' => Illuminate\Support\Facades\Redirect::class, 'Redis' => Illuminate\Support\Facades\Redis::class, 'Request' => Illuminate\Support\Facades\Request::class, 'Response' => Illuminate\Support\Facades\Response::class, 'Route' => Illuminate\Support\Facades\Route::class, 'Schema' => Illuminate\Support\Facades\Schema::class, 'Session' => Illuminate\Support\Facades\Session::class, 'Storage' => Illuminate\Support\Facades\Storage::class, 'URL' => Illuminate\Support\Facades\URL::class, 'Validator' => Illuminate\Support\Facades\Validator::class, 'View' => Illuminate\Support\Facades\View::class, /* * App aliases... */ 'Broker' => Nasqueron\Notifications\Facades\Broker::class, 'DockerHub' => Nasqueron\Notifications\Facades\DockerHub::class, 'Mailgun' => Nasqueron\Notifications\Facades\Mailgun::class, 'PhabricatorAPI' => Nasqueron\Notifications\Facades\PhabricatorAPI::class, 'ProjectsMap' => Nasqueron\Notifications\Facades\ProjectsMap::class, 'Raven' => Nasqueron\Notifications\Facades\Raven::class, 'Report' => Nasqueron\Notifications\Facades\Report::class, 'Services' => Nasqueron\Notifications\Facades\Services::class, ], ];