Module: ActiveProject::Adapters::GithubRepo::Issues

Included in:
ActiveProject::Adapters::GithubRepoAdapter
Defined in:
lib/active_project/adapters/github_repo/issues.rb

Instance Method Summary collapse

Instance Method Details

#create_issue(project_id, attributes) ⇒ ActiveProject::Resources::Issue

Creates a new issue in a GitHub repository.

Parameters:

  • project_id (String)

    The repository name or full_name

  • attributes (Hash)

    Issue attributes. Required: :title Optional: :description (body), :assignees (array of usernames)

Returns:



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/active_project/adapters/github_repo/issues.rb', line 60

def create_issue(project_id, attributes)
  # Determine the repository path to use
  repo_path = determine_repo_path(project_id)

  unless attributes[:title] && !attributes[:title].empty?
    raise ArgumentError, "Missing required attribute for GitHub issue creation: :title"
  end

  data = {
    title: attributes[:title],
    body: attributes[:description]
  }

  # Convert assignees if present
  if attributes[:assignees] && attributes[:assignees].is_a?(Array)
    if attributes[:assignees].all? { |a| a.is_a?(Hash) && a[:name] }
      data[:assignees] = attributes[:assignees].map { |a| a[:name] }
    else
      data[:assignees] = attributes[:assignees]
    end
  end

  # Add labels if present
  data[:labels] = attributes[:labels] if attributes[:labels]

  issue_data = make_request(:post, "#{repo_path}/issues", data)
  map_issue_data(issue_data)
end

#delete_issue(id, context = {}) ⇒ Boolean

Attempts to delete an issue in GitHub, but since GitHub doesn’t support true deletion, it closes the issue instead.

Parameters:

  • id (String, Integer)

    The issue number.

  • context (Hash) (defaults to: {})

    Optional context.

Returns:

  • (Boolean)

    Always returns false since GitHub doesn’t support true deletion.



140
141
142
143
144
145
# File 'lib/active_project/adapters/github_repo/issues.rb', line 140

def delete_issue(id, context = {})
  # GitHub doesn't support true deletion of issues
  # The best we can do is close the issue
  update_issue(id, { status: :closed }, context)
  false # Return false indicating true deletion is not supported
end

#find_issue(id, context = {}) ⇒ ActiveProject::Resources::Issue

Finds a specific issue by its number.

Parameters:

  • id (String, Integer)

    The issue number within the repository.

  • context (Hash) (defaults to: {})

    Optional context. Supported keys:

    • repo_owner: Repository owner if different from configured owner

    • repo_name: Repository name if different from configured repo

Returns:



42
43
44
45
46
47
48
49
50
51
52
# File 'lib/active_project/adapters/github_repo/issues.rb', line 42

def find_issue(id, context = {})
  # Determine the repository path to use
  repo_path = if context[:repo_owner] && context[:repo_name]
               "repos/#{context[:repo_owner]}/#{context[:repo_name]}"
  else
               @repo_path
  end

  issue_data = make_request(:get, "#{repo_path}/issues/#{id}")
  map_issue_data(issue_data)
end

#list_issues(project_id, options = {}) ⇒ Array<ActiveProject::Resources::Issue>

Lists GitHub issues within a specific repository (project).

Parameters:

  • project_id (String)

    The repository name or full_name

  • options (Hash) (defaults to: {})

    Optional filtering options. Supported keys:

    • status: ‘open’, ‘closed’, or ‘all’ (default: ‘open’)

    • page: Page number for pagination (default: 1)

    • per_page: Issues per page (default: 30, max: 100)

    • sort: ‘created’, ‘updated’, or ‘comments’ (default: ‘created’)

    • direction: ‘asc’ or ‘desc’ (default: ‘desc’)

Returns:



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/active_project/adapters/github_repo/issues.rb', line 17

def list_issues(project_id, options = {})
  # Determine the repository path to use
  repo_path = determine_repo_path(project_id)

  # Build query parameters
  query = {}
  query[:state] = options[:status] || "open"
  query[:page] = options[:page] if options[:page]
  query[:per_page] = options[:per_page] if options[:per_page]
  query[:sort] = options[:sort] if options[:sort]
  query[:direction] = options[:direction] if options[:direction]

  issues_data = make_request(:get, "#{repo_path}/issues", nil, query)
  return [] unless issues_data.is_a?(Array)

  issues_data.map { |issue_data| map_issue_data(issue_data) }
end

#update_issue(id, attributes, context = {}) ⇒ ActiveProject::Resources::Issue

Updates an existing issue in GitHub.

Parameters:

  • id (String, Integer)

    The issue number.

  • attributes (Hash)

    Issue attributes to update. Supported keys: :title, :description (body), :status (state), :assignees

  • context (Hash) (defaults to: {})

    Optional context. Supported keys:

    • repo_owner: Repository owner if different from configured owner

    • repo_name: Repository name if different from configured repo

Returns:



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/active_project/adapters/github_repo/issues.rb', line 98

def update_issue(id, attributes, context = {})
  # Determine the repository path to use
  repo_path = if context[:repo_owner] && context[:repo_name]
               "repos/#{context[:repo_owner]}/#{context[:repo_name]}"
  else
               @repo_path
  end

  data = {}
  data[:title] = attributes[:title] if attributes.key?(:title)
  data[:body] = attributes[:description] if attributes.key?(:description)

  # Handle status mapping
  if attributes.key?(:status)
    state = case attributes[:status]
    when :open, :in_progress then "open"
    when :closed then "closed"
    else attributes[:status].to_s
    end
    data[:state] = state
  end

  # Convert assignees if present
  if attributes.key?(:assignees)
    if attributes[:assignees].nil? || attributes[:assignees].empty?
      data[:assignees] = []
    elsif attributes[:assignees].all? { |a| a.is_a?(Hash) && a[:name] }
      data[:assignees] = attributes[:assignees].map { |a| a[:name] }
    else
      data[:assignees] = attributes[:assignees]
    end
  end

  issue_data = make_request(:patch, "#{repo_path}/issues/#{id}", data)
  map_issue_data(issue_data)
end