ghx 0.0.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/ghx/dependabot/alert.rb +2 -0
- data/lib/ghx/dependabot/package.rb +1 -0
- data/lib/ghx/dependabot/security_vulnerability.rb +1 -0
- data/lib/ghx/dependabot.rb +10 -1
- data/lib/ghx/errors.rb +7 -0
- data/lib/ghx/graphql_client.rb +5 -49
- data/lib/ghx/issue.rb +37 -8
- data/lib/ghx/project_item.rb +30 -15
- data/lib/ghx/rest_client.rb +40 -26
- data/lib/ghx.rb +28 -0
- data/lib/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b80c109f50e1c94cc2aa0bd727a2dbe547b66080380a2847132bc7cda0b34b8
|
4
|
+
data.tar.gz: 179db655ee4d499eb53912cc3a09ebc7ff5c9100d650b4ef6567ce2a8ff9acb7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 22bbefe3f68291efca16223b120575cf64997a9f2f07cc09963f0454314c423933d4cbbaf4b5c26b267d292e560114ca71e6f8faf08e7ad84e016c70229edd3e
|
7
|
+
data.tar.gz: 1082fc4c645cf94a660305ef1e0f7fdaff8c06ebd7bab58ac74d8acead82cb01cf12c8608681f8019b83ad79e479d602fab0f073270dc4d82017d997ae11f18e
|
data/lib/ghx/dependabot/alert.rb
CHANGED
@@ -115,9 +115,11 @@
|
|
115
115
|
|
116
116
|
module GHX
|
117
117
|
module Dependabot
|
118
|
+
# A Dependabot Alert
|
118
119
|
class Alert
|
119
120
|
attr_reader :number, :state, :dependency, :security_advisory, :security_vulnerability, :url, :html_url, :created_at, :updated_at
|
120
121
|
|
122
|
+
# @param json_data [Hash] The JSON data for the alert, from the API
|
121
123
|
def initialize(json_data)
|
122
124
|
@number = json_data["number"]
|
123
125
|
@state = json_data["state"]
|
data/lib/ghx/dependabot.rb
CHANGED
@@ -1,7 +1,16 @@
|
|
1
1
|
module GHX
|
2
|
+
# Module for Dependabot-related classes and methods
|
2
3
|
module Dependabot
|
4
|
+
# Get Dependabot alerts for a given repository
|
5
|
+
#
|
6
|
+
# @note ONLY RETURNS THE FIRST 100 ALERTS
|
7
|
+
# @param owner [String] the owner of the repository
|
8
|
+
# @param repo [String] the repository name
|
9
|
+
# @return [Array<GHX::Dependabot::Alert>] the alerts
|
3
10
|
def self.get_alerts(owner:, repo:)
|
4
|
-
|
11
|
+
# TODO: Add pagination to get all alerts in one go
|
12
|
+
|
13
|
+
GHX.rest_client.get("repos/#{owner}/#{repo}/dependabot/alerts?state=open&per_page=100").map do |alert|
|
5
14
|
GHX::Dependabot::Alert.new(alert)
|
6
15
|
end
|
7
16
|
end
|
data/lib/ghx/errors.rb
ADDED
data/lib/ghx/graphql_client.rb
CHANGED
@@ -1,9 +1,14 @@
|
|
1
1
|
module GHX
|
2
|
+
# Internal class to interact with the GitHub GraphQL API
|
2
3
|
class GraphqlClient
|
4
|
+
# @param api_key [String]
|
3
5
|
def initialize(api_key)
|
4
6
|
@api_key = api_key
|
5
7
|
end
|
6
8
|
|
9
|
+
# Perform a GraphQL Query and return the result
|
10
|
+
# @param query [String] GraphQL Query
|
11
|
+
# @return [Net::HTTPResponse]
|
7
12
|
def query(query)
|
8
13
|
uri = URI("https://api.github.com/graphql")
|
9
14
|
req = Net::HTTP::Post.new(uri)
|
@@ -15,54 +20,5 @@ module GHX
|
|
15
20
|
http.request(req)
|
16
21
|
end
|
17
22
|
end
|
18
|
-
|
19
|
-
# @param [String] project_id
|
20
|
-
# @param [GithubProjectItem] project_item
|
21
|
-
# @param [DateTime] reported_at
|
22
|
-
def update_project_item_reported_at(project_item_id:, reported_at:, project_id: GithubProject::MAIN_GH_PROJECT_ID)
|
23
|
-
field_id = "PVTF_lADOALH_aM4Ac-_zzgSzAZs" # project_item.field_map["Reported At"]
|
24
|
-
|
25
|
-
gql_query = <<~GQL
|
26
|
-
mutation {
|
27
|
-
updateProjectV2ItemFieldValue(input: {
|
28
|
-
fieldId: "#{field_id}",
|
29
|
-
itemId: "#{project_item_id}",
|
30
|
-
projectId: "#{project_id}",
|
31
|
-
value: {
|
32
|
-
date: "#{reported_at.to_date}"
|
33
|
-
}
|
34
|
-
}) {
|
35
|
-
projectV2Item {
|
36
|
-
id
|
37
|
-
}
|
38
|
-
}
|
39
|
-
}
|
40
|
-
GQL
|
41
|
-
|
42
|
-
query(gql_query)
|
43
|
-
end
|
44
|
-
|
45
|
-
def update_project_item_reported_by(project_item_id:, reported_by:, project_id: GithubProject::MAIN_GH_PROJECT_ID)
|
46
|
-
field_id = "PVTF_lADOALH_aM4Ac-_zzgSzBcc" # project_item.field_map["Reporter"]
|
47
|
-
|
48
|
-
gql_query = <<~GQL
|
49
|
-
mutation {
|
50
|
-
updateProjectV2ItemFieldValue(input: {
|
51
|
-
fieldId: "#{field_id}",
|
52
|
-
itemId: "#{project_item_id}",
|
53
|
-
projectId: "#{project_id}",
|
54
|
-
value: {
|
55
|
-
text: "#{reported_by}"
|
56
|
-
}
|
57
|
-
}) {
|
58
|
-
projectV2Item {
|
59
|
-
id
|
60
|
-
}
|
61
|
-
}
|
62
|
-
}
|
63
|
-
GQL
|
64
|
-
|
65
|
-
query(gql_query)
|
66
|
-
end
|
67
23
|
end
|
68
24
|
end
|
data/lib/ghx/issue.rb
CHANGED
@@ -1,18 +1,45 @@
|
|
1
1
|
module GHX
|
2
|
+
# A GitHub Issue
|
2
3
|
class Issue
|
3
4
|
attr_accessor :owner, :repo, :number, :title, :body, :state, :state_reason, :author, :assignees, :labels, :milestone, :created_at, :updated_at, :closed_at
|
4
5
|
|
6
|
+
# Search for issues in a repository
|
7
|
+
# @param owner [String] the owner of the repository
|
8
|
+
# @param repo [String] the repository name
|
9
|
+
# @param query [String] the search query, using GitHub's search syntax
|
10
|
+
# @return [Array<Issue>] the issues found
|
11
|
+
def self.search(owner:, repo:, query:)
|
12
|
+
data = GHX.rest_client.get("search/issues?q=#{URI.encode_www_form_component(query)}+is:issue+repo:#{owner}/#{repo}")
|
13
|
+
data.fetch("items").to_a.map do |issue_data|
|
14
|
+
new(owner: owner, repo: repo, **issue_data)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Find an issue by its number
|
19
|
+
# @param owner [String] the owner of the repository
|
20
|
+
# @param repo [String] the repository name
|
21
|
+
# @param number [Integer] the issue number
|
22
|
+
# @return [Issue] the issue found
|
5
23
|
def self.find(owner:, repo:, number:)
|
6
24
|
response_data = GHX.rest_client.get("repos/#{owner}/#{repo}/issues/#{number}")
|
7
25
|
new(owner: owner, repo: repo, **response_data)
|
8
26
|
end
|
9
27
|
|
28
|
+
# @param owner [String] the owner of the repository
|
29
|
+
# @param repo [String] the repository name
|
30
|
+
# @param **args [Hash] the attributes of the issue you wish to assign
|
31
|
+
# @return [Issue] the new issue
|
10
32
|
def initialize(owner:, repo:, **args)
|
11
33
|
@owner = owner
|
12
34
|
@repo = repo
|
13
35
|
update_attributes(args)
|
14
36
|
end
|
15
37
|
|
38
|
+
# Save the issue to GitHub. Handles both creating and updating.
|
39
|
+
#
|
40
|
+
# If the issue has a number, it will be updated. Otherwise, it will be created.
|
41
|
+
#
|
42
|
+
# @return [Issue] the saved issue
|
16
43
|
def save
|
17
44
|
@number.nil? ? create : update
|
18
45
|
end
|
@@ -46,14 +73,16 @@ module GHX
|
|
46
73
|
end
|
47
74
|
|
48
75
|
def update_attributes(hash)
|
49
|
-
|
50
|
-
|
51
|
-
self.
|
52
|
-
self.
|
53
|
-
self.
|
54
|
-
self.
|
55
|
-
self.
|
56
|
-
self.
|
76
|
+
hash.symbolize_keys!
|
77
|
+
|
78
|
+
self.number = hash[:number]
|
79
|
+
self.title = hash[:title]
|
80
|
+
self.body = hash[:body]
|
81
|
+
self.state = hash[:state]
|
82
|
+
self.state_reason = hash[:state_reason]
|
83
|
+
self.labels = hash[:labels]
|
84
|
+
self.milestone = hash[:milestone]
|
85
|
+
self.assignees = hash[:assignees]
|
57
86
|
end
|
58
87
|
end
|
59
88
|
end
|
data/lib/ghx/project_item.rb
CHANGED
@@ -1,7 +1,14 @@
|
|
1
1
|
module GHX
|
2
|
+
# A GitHub Project Item. This is a single item in a GitHub Project Board.
|
3
|
+
#
|
4
|
+
# ProjectsV2 are only available via the GraphQL API. This class wraps access to the API and provides a more OO interface.
|
5
|
+
#
|
6
|
+
# @note Access to ProjectItems should be done largely (if not always) through the Project class.
|
2
7
|
class ProjectItem
|
3
8
|
attr_accessor :id, :project_id, :issue_number, :issue_title, :issue_url, :issue_state, :field_values, :field_map
|
4
9
|
|
10
|
+
# @param field_configuration [Array<Hash>] An array of field configurations. These are the fields that are available to the Project Item. These are provided via the Project itself. It's much easier to access ProjectItems through the project because of this.
|
11
|
+
# @param data [Hash] The data from the GraphQL API.
|
5
12
|
def initialize(field_configuration:, data:)
|
6
13
|
_setup_field_configuration(field_configuration)
|
7
14
|
|
@@ -33,7 +40,11 @@ module GHX
|
|
33
40
|
end
|
34
41
|
end
|
35
42
|
|
36
|
-
# Updates the given fields to the given values. Makes a GraphQL call per field to do the update.
|
43
|
+
# Updates the given fields to the given values. Makes a GraphQL call *per field* to do the update.
|
44
|
+
#
|
45
|
+
# The implementation wraps access to the various types for each field. Since GraphQL requires us to type match on all
|
46
|
+
# requests, this gives us convenience, especially for things like a select field. We can pass in the value, and the
|
47
|
+
# method will find the ID of the option and update the field for us.
|
37
48
|
#
|
38
49
|
# @param fields [Hash] A hash of field names to values.
|
39
50
|
def update(**fields)
|
@@ -138,23 +149,27 @@ module GHX
|
|
138
149
|
|
139
150
|
private
|
140
151
|
|
152
|
+
# Parse the field_configuration and set up the instance variables and accessors.
|
153
|
+
#
|
154
|
+
# Example field_configuration:
|
155
|
+
# {:id=>"PVTF_lADOALH_aM4Ac-_zzgSxCno", :name=>"Title", :data_type=>"TITLE", :options=>nil}
|
156
|
+
# {:id=>"PVTF_lADOALH_aM4Ac-_zzgSxCns", :name=>"Assignees", :data_type=>"ASSIGNEES", :options=>nil}
|
157
|
+
# {:id=>"PVTF_lADOALH_aM4Ac-_zzgSzAZs", :name=>"Reported At", :data_type=>"DATE", :options=>nil}
|
158
|
+
# {:id=>"PVTSSF_lADOALH_aM4Ac-_zzgSxCnw", :name=>"Status", :data_type=>"SINGLE_SELECT", :options=>[{:id=>"f971fb55", :name=>"To triage"}, {:id=>"856cdede", :name=>"Ready to Assign"}, {:id=>"f75ad846", :name=>"Assigned"}, {:id=>"47fc9ee4", :name=>"Fix In progress"}, {:id=>"5ef0dc97", :name=>"Additional Info Requested"}, {:id=>"98236657", :name=>"Done - Fixed"}, {:id=>"98aea6ad", :name=>"Done - Won't Fix"}, {:id=>"a3b4fc3a", :name=>"Duplicate"}, {:id=>"81377549", :name=>"Not a Vulnerability"}]}
|
159
|
+
# {:id=>"PVTF_lADOALH_aM4Ac-_zzgSxCn0", :name=>"Labels", :data_type=>"LABELS", :options=>nil}
|
160
|
+
# {:id=>"PVTF_lADOALH_aM4Ac-_zzgSxCn4", :name=>"Linked pull requests", :data_type=>"LINKED_PULL_REQUESTS", :options=>nil}
|
161
|
+
# {:id=>"PVTF_lADOALH_aM4Ac-_zzgSxCn8", :name=>"Milestone", :data_type=>"MILESTONE", :options=>nil}
|
162
|
+
# {:id=>"PVTF_lADOALH_aM4Ac-_zzgSxCoA", :name=>"Repository", :data_type=>"REPOSITORY", :options=>nil}
|
163
|
+
# {:id=>"PVTF_lADOALH_aM4Ac-_zzgSxCoM", :name=>"Reviewers", :data_type=>"REVIEWERS", :options=>nil}
|
164
|
+
# {:id=>"PVTSSF_lADOALH_aM4Ac-_zzgSxCuA", :name=>"Severity", :data_type=>"SINGLE_SELECT", :options=>[{:id=>"79628723", :name=>"Informational"}, {:id=>"153889c6", :name=>"Low"}, {:id=>"093709ee", :name=>"Medium"}, {:id=>"5a00bbe7", :name=>"High"}, {:id=>"00e0bbaf", :name=>"Critical"}, {:id=>"fd986bd9", :name=>"Duplicate"}]}
|
165
|
+
# {:id=>"PVTF_lADOALH_aM4Ac-_zzgSzBcc", :name=>"Reporter", :data_type=>"TEXT", :options=>nil}
|
166
|
+
# {:id=>"PVTF_lADOALH_aM4Ac-_zzgSzBho", :name=>"Resolve By", :data_type=>"DATE", :options=>nil}
|
167
|
+
# {:id=>"PVTSSF_lADOALH_aM4Ac-_zzgTKjOw", :name=>"Payout Status", :data_type=>"SINGLE_SELECT", :options=>[{:id=>"53c47c02", :name=>"Ready for Invoice"}, {:id=>"0b8a4629", :name=>"Payout in Process"}, {:id=>"5f356a58", :name=>"Payout Complete"}, {:id=>"368048ac", :name=>"Ineligible for Payout"}]}
|
168
|
+
#
|
169
|
+
#
|
141
170
|
def _setup_field_configuration(field_configuration)
|
142
171
|
@field_configuration = field_configuration.map { |fc| fc.merge({normalized_name: normalized_field_value_name(fc[:name])}) }
|
143
172
|
|
144
|
-
# Example field_configuration:
|
145
|
-
# {:id=>"PVTF_lADOALH_aM4Ac-_zzgSxCno", :name=>"Title", :data_type=>"TITLE", :options=>nil}
|
146
|
-
# {:id=>"PVTF_lADOALH_aM4Ac-_zzgSxCns", :name=>"Assignees", :data_type=>"ASSIGNEES", :options=>nil}
|
147
|
-
# {:id=>"PVTF_lADOALH_aM4Ac-_zzgSzAZs", :name=>"Reported At", :data_type=>"DATE", :options=>nil}
|
148
|
-
# {:id=>"PVTSSF_lADOALH_aM4Ac-_zzgSxCnw", :name=>"Status", :data_type=>"SINGLE_SELECT", :options=>[{:id=>"f971fb55", :name=>"To triage"}, {:id=>"856cdede", :name=>"Ready to Assign"}, {:id=>"f75ad846", :name=>"Assigned"}, {:id=>"47fc9ee4", :name=>"Fix In progress"}, {:id=>"5ef0dc97", :name=>"Additional Info Requested"}, {:id=>"98236657", :name=>"Done - Fixed"}, {:id=>"98aea6ad", :name=>"Done - Won't Fix"}, {:id=>"a3b4fc3a", :name=>"Duplicate"}, {:id=>"81377549", :name=>"Not a Vulnerability"}]}
|
149
|
-
# {:id=>"PVTF_lADOALH_aM4Ac-_zzgSxCn0", :name=>"Labels", :data_type=>"LABELS", :options=>nil}
|
150
|
-
# {:id=>"PVTF_lADOALH_aM4Ac-_zzgSxCn4", :name=>"Linked pull requests", :data_type=>"LINKED_PULL_REQUESTS", :options=>nil}
|
151
|
-
# {:id=>"PVTF_lADOALH_aM4Ac-_zzgSxCn8", :name=>"Milestone", :data_type=>"MILESTONE", :options=>nil}
|
152
|
-
# {:id=>"PVTF_lADOALH_aM4Ac-_zzgSxCoA", :name=>"Repository", :data_type=>"REPOSITORY", :options=>nil}
|
153
|
-
# {:id=>"PVTF_lADOALH_aM4Ac-_zzgSxCoM", :name=>"Reviewers", :data_type=>"REVIEWERS", :options=>nil}
|
154
|
-
# {:id=>"PVTSSF_lADOALH_aM4Ac-_zzgSxCuA", :name=>"Severity", :data_type=>"SINGLE_SELECT", :options=>[{:id=>"79628723", :name=>"Informational"}, {:id=>"153889c6", :name=>"Low"}, {:id=>"093709ee", :name=>"Medium"}, {:id=>"5a00bbe7", :name=>"High"}, {:id=>"00e0bbaf", :name=>"Critical"}, {:id=>"fd986bd9", :name=>"Duplicate"}]}
|
155
|
-
# {:id=>"PVTF_lADOALH_aM4Ac-_zzgSzBcc", :name=>"Reporter", :data_type=>"TEXT", :options=>nil}
|
156
|
-
# {:id=>"PVTF_lADOALH_aM4Ac-_zzgSzBho", :name=>"Resolve By", :data_type=>"DATE", :options=>nil}
|
157
|
-
# {:id=>"PVTSSF_lADOALH_aM4Ac-_zzgTKjOw", :name=>"Payout Status", :data_type=>"SINGLE_SELECT", :options=>[{:id=>"53c47c02", :name=>"Ready for Invoice"}, {:id=>"0b8a4629", :name=>"Payout in Process"}, {:id=>"5f356a58", :name=>"Payout Complete"}, {:id=>"368048ac", :name=>"Ineligible for Payout"}]}
|
158
173
|
@field_configuration.each do |field|
|
159
174
|
next unless field[:name]
|
160
175
|
next if field[:name].to_s.empty?
|
data/lib/ghx/rest_client.rb
CHANGED
@@ -1,57 +1,62 @@
|
|
1
1
|
require "net/http"
|
2
2
|
|
3
3
|
module GHX
|
4
|
+
# RestClient is a simple wrapper around Net::HTTP to make it easier to make API calls to the GitHub REST API.
|
5
|
+
#
|
6
|
+
# This is necessary because not all GitHub API endpoints are covered by Octokit.
|
4
7
|
class RestClient
|
5
8
|
attr_reader :api_key
|
6
9
|
|
10
|
+
# @param api_key [String] the GitHub API key
|
7
11
|
def initialize(api_key)
|
8
12
|
@api_key = api_key
|
9
13
|
end
|
10
14
|
|
11
|
-
#
|
15
|
+
# Make a GET request to the given path
|
16
|
+
# @param path [String] the path to the API endpoint
|
17
|
+
# @return [Hash] the parsed JSON response
|
12
18
|
def get(path)
|
13
19
|
uri = URI.parse("https://api.github.com/#{path}")
|
14
20
|
request = Net::HTTP::Get.new(uri)
|
15
|
-
request["Accept"] = "application/vnd.github+json"
|
16
|
-
request["Authorization"] = "Bearer #{@api_key}"
|
17
|
-
request["X-Github-Api-Version"] = "2022-11-28"
|
18
|
-
|
19
|
-
req_options = {
|
20
|
-
use_ssl: uri.scheme == "https"
|
21
|
-
}
|
22
21
|
|
23
|
-
response =
|
24
|
-
http.request(request)
|
25
|
-
end
|
22
|
+
response = _http_request(uri: uri, request: request)
|
26
23
|
|
27
24
|
JSON.parse(response.body)
|
28
25
|
end
|
29
26
|
|
30
|
-
#
|
27
|
+
# Make a POST request to the given path with the given params
|
28
|
+
# @param path [String] the path to the API endpoint
|
29
|
+
# @param params [Hash] the request body
|
30
|
+
# @return [Hash] the parsed JSON response
|
31
31
|
def post(path, params)
|
32
32
|
uri = URI.parse("https://api.github.com/#{path}")
|
33
33
|
request = Net::HTTP::Post.new(uri)
|
34
|
-
request["Accept"] = "application/vnd.github+json"
|
35
|
-
request["Authorization"] = "Bearer #{@api_key}"
|
36
|
-
request["X-Github-Api-Version"] = "2022-11-28"
|
37
|
-
|
38
|
-
req_options = {
|
39
|
-
use_ssl: uri.scheme == "https"
|
40
|
-
}
|
41
34
|
|
42
35
|
request.body = params.to_json
|
43
36
|
|
44
|
-
response =
|
45
|
-
http.request(request)
|
46
|
-
end
|
37
|
+
response = _http_request(uri: uri, request: request)
|
47
38
|
|
48
39
|
JSON.parse(response.body)
|
49
40
|
end
|
50
41
|
|
51
|
-
#
|
42
|
+
# Make a PATCH request to the given path with the given params
|
43
|
+
# @param path [String] the path to the API endpoint
|
44
|
+
# @param params [Hash] the request body
|
45
|
+
# @return [Hash] the parsed JSON response
|
52
46
|
def patch(path, params)
|
53
47
|
uri = URI.parse("https://api.github.com/#{path}")
|
54
48
|
request = Net::HTTP::Patch.new(uri)
|
49
|
+
|
50
|
+
request.body = params.to_json
|
51
|
+
|
52
|
+
response = _http_request(uri: uri, request: request)
|
53
|
+
|
54
|
+
JSON.parse(response.body)
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def _http_request(uri:, request:)
|
55
60
|
request["Accept"] = "application/vnd.github+json"
|
56
61
|
request["Authorization"] = "Bearer #{@api_key}"
|
57
62
|
request["X-Github-Api-Version"] = "2022-11-28"
|
@@ -60,13 +65,22 @@ module GHX
|
|
60
65
|
use_ssl: uri.scheme == "https"
|
61
66
|
}
|
62
67
|
|
63
|
-
request.body = params.to_json
|
64
|
-
|
65
68
|
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
|
66
69
|
http.request(request)
|
67
70
|
end
|
68
71
|
|
69
|
-
|
72
|
+
if response.code.to_i < 400
|
73
|
+
response
|
74
|
+
elsif [403, 429].include?(response.code.to_i)
|
75
|
+
if response["X-RateLimit-Remaining"].to_i == 0
|
76
|
+
reset_time = Time.at(response["X-RateLimit-Reset"].to_i)
|
77
|
+
raise GHX::RateLimitExceededError, "GitHub API rate limit exceeded. Try again after #{reset_time}"
|
78
|
+
else
|
79
|
+
raise GHX::RateLimitExceededError, "GitHub API rate limit exceeded. Try again later."
|
80
|
+
end
|
81
|
+
else
|
82
|
+
raise GHX::OtherApiError, "GitHub API returned an error: #{response.code} #{response.body}"
|
83
|
+
end
|
70
84
|
end
|
71
85
|
end
|
72
86
|
end
|
data/lib/ghx.rb
CHANGED
@@ -3,7 +3,17 @@ require "net/http"
|
|
3
3
|
require "json"
|
4
4
|
require "octokit"
|
5
5
|
|
6
|
+
class Hash
|
7
|
+
def symbolize_keys!
|
8
|
+
keys.each do |key|
|
9
|
+
self[key.to_sym] = delete(key)
|
10
|
+
end
|
11
|
+
self
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
6
15
|
require_relative "version"
|
16
|
+
require_relative "ghx/errors"
|
7
17
|
require_relative "ghx/graphql_client"
|
8
18
|
require_relative "ghx/rest_client"
|
9
19
|
require_relative "ghx/dependabot"
|
@@ -16,34 +26,52 @@ require_relative "ghx/project_item"
|
|
16
26
|
# Extra classes to support more OO interfaces to the GitHub API. Wraps both the REST API and GraphQL API. Currently
|
17
27
|
# incomplete. Functionality has been built for our existing use-cases, but nothing else.
|
18
28
|
module GHX
|
29
|
+
# Defaults to $stdout
|
30
|
+
# @return [Logger]
|
19
31
|
def self.logger
|
20
32
|
@logger ||= Logger.new($stdout)
|
21
33
|
end
|
22
34
|
|
35
|
+
# @param logger [Logger]
|
23
36
|
def self.logger=(logger)
|
24
37
|
@logger = logger
|
25
38
|
end
|
26
39
|
|
40
|
+
# Internal octokit client.
|
41
|
+
# API Key defaults to ENV["GITHUB_TOKEN"]
|
42
|
+
# @return [Octokit::Client]
|
27
43
|
def self.octokit
|
28
44
|
@octokit ||= Octokit::Client.new(access_token: ENV["GITHUB_TOKEN"])
|
29
45
|
end
|
30
46
|
|
47
|
+
# @param octokit [Octokit::Client]
|
48
|
+
# @return [Octokit::Client]
|
31
49
|
def self.octokit=(octokit)
|
32
50
|
@octokit = octokit
|
33
51
|
end
|
34
52
|
|
53
|
+
# Internal graphql client.
|
54
|
+
# API Key defaults to ENV["GITHUB_TOKEN"]
|
55
|
+
# @return [GHX::GraphqlClient]
|
35
56
|
def self.graphql
|
36
57
|
@graphql ||= GHX::GraphqlClient.new(ENV["GITHUB_GRAPHQL_TOKEN"])
|
37
58
|
end
|
38
59
|
|
60
|
+
# @param graphql [GHX::GraphqlClient]
|
61
|
+
# @return [GHX::GraphqlClient]
|
39
62
|
def self.graphql=(graphql)
|
40
63
|
@graphql = graphql
|
41
64
|
end
|
42
65
|
|
66
|
+
# Internal graphql client.
|
67
|
+
# API Key defaults to ENV["GITHUB_TOKEN"]
|
68
|
+
# @return [GHX::RestClient]
|
43
69
|
def self.rest_client
|
44
70
|
@rest_client ||= GHX::RestClient.new(ENV["GITHUB_TOKEN"])
|
45
71
|
end
|
46
72
|
|
73
|
+
# @param rest_client [GHX::RestClient]
|
74
|
+
# @return [GHX::RestClient]
|
47
75
|
def self.rest_client=(rest_client)
|
48
76
|
@rest_client = rest_client
|
49
77
|
end
|
data/lib/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ghx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- CompanyCam
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-05-
|
11
|
+
date: 2024-05-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: octokit
|
@@ -106,6 +106,7 @@ files:
|
|
106
106
|
- lib/ghx/dependabot/alert.rb
|
107
107
|
- lib/ghx/dependabot/package.rb
|
108
108
|
- lib/ghx/dependabot/security_vulnerability.rb
|
109
|
+
- lib/ghx/errors.rb
|
109
110
|
- lib/ghx/graphql_client.rb
|
110
111
|
- lib/ghx/issue.rb
|
111
112
|
- lib/ghx/project.rb
|