Class: RailsErrorDashboard::Services::IssueTrackerClient

Inherits:
Object
  • Object
show all
Defined in:
lib/rails_error_dashboard/services/issue_tracker_client.rb

Overview

Base class and factory for issue tracker API clients.

Supports GitHub, GitLab, Codeberg/Gitea/Forgejo, and Linear via a unified interface. Each provider implements the same methods with provider-specific API calls.

Examples:

client = IssueTrackerClient.for(:github, token: "ghp_xxx", repo: "user/repo")
result = client.create_issue(title: "NoMethodError", body: "...", labels: ["bug"])
# => { url: "https://github.com/user/repo/issues/42", number: 42 }

Constant Summary collapse

REQUEST_TIMEOUT =

seconds

15
MAX_BODY_LENGTH =

GitHub has ~65K limit for issue body

65_000

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(token:, repo:, api_url: nil) ⇒ IssueTrackerClient

Returns a new instance of IssueTrackerClient.



66
67
68
69
70
# File 'lib/rails_error_dashboard/services/issue_tracker_client.rb', line 66

def initialize(token:, repo:, api_url: nil)
  @token = token
  @repo = repo
  @api_url = api_url
end

Instance Attribute Details

#api_urlObject (readonly)

Returns the value of attribute api_url.



23
24
25
# File 'lib/rails_error_dashboard/services/issue_tracker_client.rb', line 23

def api_url
  @api_url
end

#repoObject (readonly)

Returns the value of attribute repo.



23
24
25
# File 'lib/rails_error_dashboard/services/issue_tracker_client.rb', line 23

def repo
  @repo
end

#tokenObject (readonly)

Returns the value of attribute token.



23
24
25
# File 'lib/rails_error_dashboard/services/issue_tracker_client.rb', line 23

def token
  @token
end

Class Method Details

.for(provider, token:, repo:, api_url: nil) ⇒ IssueTrackerClient

Factory method — returns the correct client for the provider

Parameters:

  • provider (Symbol)

    :github, :gitlab, :codeberg, or :linear

  • token (String)

    API authentication token

  • repo (String)

    Repository identifier (“owner/repo”), or Linear team key (“ENG”)

  • api_url (String, nil) (defaults to: nil)

    Custom API base URL (for self-hosted)

Returns:



32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/rails_error_dashboard/services/issue_tracker_client.rb', line 32

def self.for(provider, token:, repo:, api_url: nil)
  case provider&.to_sym
  when :github
    GitHubIssueClient.new(token: token, repo: repo, api_url: api_url)
  when :gitlab
    GitLabIssueClient.new(token: token, repo: repo, api_url: api_url)
  when :codeberg
    CodebergIssueClient.new(token: token, repo: repo, api_url: api_url)
  when :linear
    LinearIssueClient.new(token: token, repo: repo, api_url: api_url)
  else
    raise ArgumentError, "Unknown issue tracker provider: #{provider}. Supported: :github, :gitlab, :codeberg, :linear"
  end
end

.from_configIssueTrackerClient?

Build a client from the current gem configuration

Returns:



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/rails_error_dashboard/services/issue_tracker_client.rb', line 50

def self.from_config
  config = RailsErrorDashboard.configuration
  return nil unless config.enable_issue_tracking

  provider = config.effective_issue_tracker_provider
  token = config.effective_issue_tracker_token
  repo = config.effective_issue_tracker_repo
  api_url = config.effective_issue_tracker_api_url

  return nil unless provider && token && repo

  self.for(provider, token: token, repo: repo, api_url: api_url)
rescue => e
  nil
end

Instance Method Details

#add_comment(number:, body:) ⇒ Hash

Add a comment to an issue

Returns:

  • (Hash)

    { url:, success: true } or { success: false, error: “…” }

Raises:

  • (NotImplementedError)


92
93
94
# File 'lib/rails_error_dashboard/services/issue_tracker_client.rb', line 92

def add_comment(number:, body:)
  raise NotImplementedError
end

#close_issue(number:) ⇒ Hash

Close an issue

Returns:

  • (Hash)

    { success: true } or { success: false, error: “…” }

Raises:

  • (NotImplementedError)


80
81
82
# File 'lib/rails_error_dashboard/services/issue_tracker_client.rb', line 80

def close_issue(number:)
  raise NotImplementedError
end

#create_issue(title:, body:, labels: []) ⇒ Hash

Create an issue on the platform

Returns:

  • (Hash)

    { url:, number:, success: true } or { success: false, error: “…” }

Raises:

  • (NotImplementedError)


74
75
76
# File 'lib/rails_error_dashboard/services/issue_tracker_client.rb', line 74

def create_issue(title:, body:, labels: [])
  raise NotImplementedError
end

#fetch_comments(number:, per_page: 10) ⇒ Hash

Fetch comments from an issue

Returns:

  • (Hash)

    { comments: […], success: true } or { success: false, error: “…” }

Raises:

  • (NotImplementedError)


98
99
100
# File 'lib/rails_error_dashboard/services/issue_tracker_client.rb', line 98

def fetch_comments(number:, per_page: 10)
  raise NotImplementedError
end

#fetch_issue(number:) ⇒ Hash

Fetch issue details (status, assignees, labels)

Returns:

  • (Hash)

    { state:, assignees: […], labels: […], title:, success: true } or { success: false }

Raises:

  • (NotImplementedError)


104
105
106
# File 'lib/rails_error_dashboard/services/issue_tracker_client.rb', line 104

def fetch_issue(number:)
  raise NotImplementedError
end

#reopen_issue(number:) ⇒ Hash

Reopen a closed issue

Returns:

  • (Hash)

    { success: true } or { success: false, error: “…” }

Raises:

  • (NotImplementedError)


86
87
88
# File 'lib/rails_error_dashboard/services/issue_tracker_client.rb', line 86

def reopen_issue(number:)
  raise NotImplementedError
end