Skip to content

Conversation

@jordanpartridge
Copy link
Contributor

Summary

Implements IssueInstance service providing a fluent API for managing individual GitHub issues, following the RepositoryInstance pattern from conduit-ui/repo.

Changes

Issue DTO Enhancements

  • Added apiUrl field for API endpoint reference
  • Added activeLockReason field to track lock status
  • Added helper methods:
    • isLocked() - Check if issue is locked
    • hasLabel(string $label) - Check if issue has specific label
    • isAssignedTo(string $username) - Check if issue is assigned to user

IssueInstance Service

Created new chainable service for managing individual issues:

Issue Updates:

  • update(array $attributes) - Update issue with custom attributes
  • title(string $title) - Update issue title
  • body(string $body) - Update issue body

State Management:

  • close(?string $reason) - Close issue (with optional reason: 'completed' or 'not_planned')
  • reopen() - Reopen closed issue

Label Management:

  • addLabel(string $label) - Add single label
  • addLabels(array $labels) - Add multiple labels
  • removeLabel(string $label) - Remove specific label
  • setLabels(array $labels) - Replace all labels

Assignment:

  • assign(string|array $assignees) - Assign to user(s)
  • assignTo(string $username) - Convenience method for single assignment
  • unassign(string|array $assignees) - Remove assignees
  • milestone(int|null $milestoneNumber) - Set milestone

Lock Management:

  • lock(?string $reason) - Lock issue with optional reason
  • unlock() - Unlock issue

Comments:

  • comment(string $body) - Add comment to issue

Data Access:

  • get() - Get cached issue data
  • fresh() - Fetch fresh issue data from API
  • Magic __get() for property access

Supporting Requests

  • LockIssueRequest - PUT request to lock issues
  • UnlockIssueRequest - DELETE request to unlock issues

IssuesService Integration

  • Added find(string $fullName, int $number) method to get IssueInstance

Facade Update

  • Updated GithubIssues facade with find() method documentation

Usage Example

use ConduitUI\Issue\Facades\GithubIssues;

// Chainable fluent API
GithubIssues::find('owner/repo', 123)
    ->addLabel('bug')
    ->assignTo('developer')
    ->comment('Looking into this')
    ->close('completed');

// Update title and body
GithubIssues::find('owner/repo', 456)
    ->title('New Title')
    ->body('Updated description')
    ->addLabels(['enhancement', 'priority-high']);

Test Coverage

  • 390 passing tests
  • 99.4% code coverage
  • All IssueInstance methods tested with mocked HTTP responses
  • Updated existing Issue DTO tests for new fields

Quality Gates

  • All tests passing
  • Code style fixed with Pint
  • 99% coverage exceeds requirements

Closes #21

Implements IssueInstance service providing fluent API for managing GitHub issues:

- Add Issue DTO enhancements (apiUrl, activeLockReason fields)
- Add helper methods (isLocked, hasLabel, isAssignedTo)
- Implement IssueInstance service with chainable methods:
  - update(), title(), body()
  - close(), reopen()
  - addLabel(), addLabels(), removeLabel(), setLabels()
  - assign(), assignTo(), unassign()
  - milestone()
  - lock(), unlock()
  - comment()
- Add find() method to IssuesService
- Create LockIssueRequest and UnlockIssueRequest
- Comprehensive test coverage (99.4%)

Closes #21
@coderabbitai
Copy link

coderabbitai bot commented Dec 19, 2025

Warning

Rate limit exceeded

@jordanpartridge has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 1 minutes and 12 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 96a2f1e and 2f1dfd3.

📒 Files selected for processing (8)
  • src/Data/Issue.php (5 hunks)
  • src/Facades/GithubIssues.php (1 hunks)
  • src/Requests/Issues/LockIssueRequest.php (1 hunks)
  • src/Requests/Issues/UnlockIssueRequest.php (1 hunks)
  • src/Services/IssueInstance.php (1 hunks)
  • src/Services/IssuesService.php (1 hunks)
  • tests/Unit/Data/IssueTest.php (4 hunks)
  • tests/Unit/Services/IssueInstanceTest.php (1 hunks)
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/issue-model

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Issue Model with Chainable Action Methods

2 participants