Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@
"pestphp/pest-plugin": true
}
},
"extra": {
"laravel": {
"providers": [
"ConduitUI\\Pr\\PrServiceProvider"
]
}
},
"minimum-stability": "dev",
"prefer-stable": true
}
20 changes: 20 additions & 0 deletions config/pr.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

return [
/*
|--------------------------------------------------------------------------
| GitHub Configuration
|--------------------------------------------------------------------------
|
| Configure your GitHub access token for pull request operations.
| You can set this in your .env file as GITHUB_TOKEN or configure
| it in config/services.php under 'github.token'.
|
*/

'github' => [
'token' => env('GITHUB_TOKEN'),
],
];
4 changes: 4 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -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:
-
Expand Down
80 changes: 80 additions & 0 deletions src/PrServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

declare(strict_types=1);

namespace ConduitUI\Pr;

use ConduitUi\GitHubConnector\Connector;
use ConduitUI\Pr\Contracts\PrServiceInterface;
use ConduitUI\Pr\Services\GitHubPrService;
use Illuminate\Support\ServiceProvider;

class PrServiceProvider extends ServiceProvider
{
/**
* Register services.
*/
public function register(): void
{
$this->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));
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.

$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;
}
Comment on lines +46 to +79
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Avoid eager resolution in boot()—missing token shouldn’t break the whole Laravel app / artisan.
Right now boot() always resolves PrServiceInterface, so a missing token throws during app boot, even if the package isn’t used. Prefer lazy configuration (or only set up the facade when token is present).

     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
-        $service = $this->app->make(PrServiceInterface::class);
-        PullRequests::setService($service);
+        // Auto-configure the PullRequests facade (lazy / non-fatal if unconfigured)
+        $token = $this->app['config']->get('pr.github.token')
+            ?: $this->app['config']->get('services.github.token')
+            ?: env('GITHUB_TOKEN');
+
+        if ($token) {
+            PullRequests::setService($this->app->make(PrServiceInterface::class));
+        }
     }
🤖 Prompt for AI Agents
In src/PrServiceProvider.php around lines 48 to 57, boot() eagerly resolves
PrServiceInterface which throws if the token is missing; instead avoid calling
$this->app->make() during boot — either guard resolution with a config/token
check (e.g. if (config('pr.token')) {
PullRequests::setService($this->app->make(PrServiceInterface::class)); }) or
defer wiring by using the container hooks (e.g.
$this->app->afterResolving(PrServiceInterface::class, fn($service) =>
PullRequests::setService($service)); or $this->app->resolving(...)) so the
service is only resolved when available and the app can boot without the token.

}