diff --git a/composer.json b/composer.json index ffa1261..abb9bb4 100644 --- a/composer.json +++ b/composer.json @@ -43,6 +43,13 @@ "pestphp/pest-plugin": true } }, + "extra": { + "laravel": { + "providers": [ + "ConduitUI\\Pr\\PrServiceProvider" + ] + } + }, "minimum-stability": "dev", "prefer-stable": true } diff --git a/config/pr.php b/config/pr.php new file mode 100644 index 0000000..b6db9f3 --- /dev/null +++ b/config/pr.php @@ -0,0 +1,20 @@ + [ + 'token' => env('GITHUB_TOKEN'), + ], +]; diff --git a/phpstan.neon b/phpstan.neon index 5cc331b..94e9bd2 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,6 +2,10 @@ parameters: level: 8 paths: - src + excludePaths: + # Excluded because it depends on Laravel's ServiceProvider which isn't available + # in the non-Laravel test environment. The class is only used in Laravel apps. + - src/PrServiceProvider.php tmpDir: build/phpstan ignoreErrors: - diff --git a/src/PrServiceProvider.php b/src/PrServiceProvider.php new file mode 100644 index 0000000..ea3c61d --- /dev/null +++ b/src/PrServiceProvider.php @@ -0,0 +1,80 @@ +mergeConfigFrom( + __DIR__.'/../config/pr.php', + 'pr' + ); + + $this->app->singleton(PrServiceInterface::class, function ($app) { + $token = $this->resolveToken($app); + + if ($token === null) { + throw new \RuntimeException( + 'GitHub token not configured. Set GITHUB_TOKEN environment variable or publish and configure the pr.php config file.' + ); + } + + return new GitHubPrService(new Connector($token)); + }); + + $this->app->singleton(GitHubPrService::class, function ($app) { + return $app->make(PrServiceInterface::class); + }); + } + + /** + * Bootstrap services. + */ + public function boot(): void + { + if ($this->app->runningInConsole()) { + $this->publishes([ + __DIR__.'/../config/pr.php' => config_path('pr.php'), + ], 'pr-config'); + } + + // Auto-configure the PullRequests facade only if token is available + // This prevents crashing apps that don't need PR functionality + if ($this->resolveToken($this->app) !== null) { + PullRequests::setService($this->app->make(PrServiceInterface::class)); + } + } + + /** + * Resolve the GitHub token from available configuration sources. + * + * @param \Illuminate\Contracts\Foundation\Application $app + */ + private function resolveToken($app): ?string + { + $sources = [ + $app['config']->get('pr.github.token'), + $app['config']->get('services.github.token'), + env('GITHUB_TOKEN'), + ]; + + foreach ($sources as $token) { + if (is_string($token) && trim($token) !== '') { + return trim($token); + } + } + + return null; + } +}