digitalkaoz/issues
PHP wrapper to search and fetch issues across multiple trackers (GitHub, GitLab, Jira, Bitbucket). Includes a CLI for cross-tracker searching and a simple API to find projects and list issues programmatically.
Installation
composer require digitalkaoz/issues@dev-main
(Note: Due to the package's age, ensure your composer.json allows PHP 7.4+ for full compatibility with the latest changes.)
Basic Initialization
use Digitalkaoz\Issues\IssueTracker;
$tracker = new IssueTracker('bitbucket', [
'username' => 'your_username',
'token' => 'your_app_password_or_token',
]);
First Use Case: Fetching Issues
$issues = $tracker->issues()->all();
// Returns an array of issue objects (e.g., for Bitbucket: title, id, labels, etc.)
Where to Look First
examples/ folder.config/issues.php (auto-generated) or the constructor parameters for Bitbucket-specific options like workspace.tests/ or examples/ folders for Bitbucket-specific usage snippets.Tracker-Specific Operations
// Bitbucket example
$tracker = new IssueTracker('bitbucket', [
'token' => 'your_app_password',
'workspace' => 'your_workspace',
]);
$repoIssues = $tracker->issues()->repo('your-repo')->open()->fetch();
Querying Issues
// Filter by label and state (Bitbucket-specific fields)
$issues = $tracker->issues()
->labels(['bug', 'critical'])
->state('open')
->fetch();
Creating/Updating Issues
$newIssue = $tracker->issues()->create([
'title' => 'Fix login bug',
'content' => 'Users cannot log in after update.', // Note: Bitbucket uses 'content' instead of 'body'
'labels' => ['bug', 'auth'],
]);
Integration with Laravel
$this->app->singleton(IssueTracker::class, function ($app) {
return new IssueTracker(
config('issues.tracker'),
config('issues.credentials') + ['workspace' => config('issues.bitbucket.workspace')]
);
});
IssuesFacade) to simplify calls:
Issues::tracker('bitbucket')->issues()->all();
Batch Processing
foreach ($tracker->issues()->all() as $issue) {
if ($issue->isOlderThan('30 days')) {
$tracker->issues()->update($issue->id, ['labels' => ['stale']]);
}
}
all() or fetch() calls using Laravel’s cache:
$issues = Cache::remember("issues_{$repo}", now()->addHours(1), function () use ($tracker) {
return $tracker->issues()->repo($repo)->all();
});
IssueCreated, IssueUpdated) after tracker operations.event(new IssueCreated($newIssue));
Bitbucket-Specific Fields
content instead of body for issue descriptions.class Issue {
public function __construct(array $data) {
$this->title = $data['title'] ?? '';
$this->description = $data['content'] ?? $data['body'] ?? '';
$this->labels = collect($data['labels'] ?? []);
}
}
Authentication Issues
$tracker->getClient()->setDebug(true); // If the package uses Guzzle.
Workspace Requirement
workspace parameter in the credentials. Add it to your config:
'bitbucket' => [
'workspace' => env('BITBUCKET_WORKSPACE'),
],
Deprecated Trackers
Trello) may still be present but unsupported. Avoid using them.IssueTracker class for custom APIs.$tracker->setLogLevel(IssueTracker::LOG_DEBUG);
try {
$issues = $tracker->issues()->all();
} catch (\Exception $e) {
Log::error("Tracker error: " . $e->getMessage(), ['response' => $e->getResponse()]);
}
Custom Trackers
Extend Digitalkaoz\Issues\IssueTracker and override:
getApiUrl(): Change the base API endpoint.authenticate(): Implement custom auth logic for Bitbucket or other trackers.parseIssue(): Modify how issue data is structured for Bitbucket-specific fields.Laravel Service Container Bind the tracker to the container with custom configurations:
$this->app->bind(IssueTracker::class, function ($app) {
return new IssueTracker(
config('issues.tracker'),
$app['config']['issues.credentials'] + ['debug' => env('ISSUES_DEBUG', false)]
);
});
Testing Mock the tracker in tests:
$mockTracker = Mockery::mock(IssueTracker::class)->makePartial();
$mockTracker->shouldReceive('issues')->andReturnSelf();
$mockTracker->shouldReceive('all')->andReturn([/* mock issues */]);
Webhooks
For real-time updates, pair with a webhook listener (e.g., Laravel’s HandleIncomingWebhook):
// In a webhook route:
$payload = json_decode(request()->getContent(), true);
Issues::tracker('bitbucket')->issues()->syncFromWebhook($payload);
How can I help you explore Laravel packages today?