lingfennan-github_api 0.18.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +20 -0
  3. data/README.md +741 -0
  4. data/lib/github_api.rb +93 -0
  5. data/lib/github_api/api.rb +398 -0
  6. data/lib/github_api/api/actions.rb +60 -0
  7. data/lib/github_api/api/arguments.rb +253 -0
  8. data/lib/github_api/api/config.rb +105 -0
  9. data/lib/github_api/api/config/property.rb +30 -0
  10. data/lib/github_api/api/config/property_set.rb +120 -0
  11. data/lib/github_api/api/factory.rb +33 -0
  12. data/lib/github_api/authorization.rb +75 -0
  13. data/lib/github_api/client.rb +77 -0
  14. data/lib/github_api/client/activity.rb +31 -0
  15. data/lib/github_api/client/activity/events.rb +233 -0
  16. data/lib/github_api/client/activity/feeds.rb +50 -0
  17. data/lib/github_api/client/activity/notifications.rb +181 -0
  18. data/lib/github_api/client/activity/starring.rb +130 -0
  19. data/lib/github_api/client/activity/watching.rb +176 -0
  20. data/lib/github_api/client/authorizations.rb +142 -0
  21. data/lib/github_api/client/authorizations/app.rb +98 -0
  22. data/lib/github_api/client/emojis.rb +19 -0
  23. data/lib/github_api/client/gists.rb +289 -0
  24. data/lib/github_api/client/gists/comments.rb +100 -0
  25. data/lib/github_api/client/git_data.rb +31 -0
  26. data/lib/github_api/client/git_data/blobs.rb +51 -0
  27. data/lib/github_api/client/git_data/commits.rb +101 -0
  28. data/lib/github_api/client/git_data/references.rb +150 -0
  29. data/lib/github_api/client/git_data/tags.rb +95 -0
  30. data/lib/github_api/client/git_data/trees.rb +113 -0
  31. data/lib/github_api/client/gitignore.rb +57 -0
  32. data/lib/github_api/client/issues.rb +248 -0
  33. data/lib/github_api/client/issues/assignees.rb +77 -0
  34. data/lib/github_api/client/issues/comments.rb +146 -0
  35. data/lib/github_api/client/issues/events.rb +50 -0
  36. data/lib/github_api/client/issues/labels.rb +189 -0
  37. data/lib/github_api/client/issues/milestones.rb +146 -0
  38. data/lib/github_api/client/markdown.rb +62 -0
  39. data/lib/github_api/client/meta.rb +19 -0
  40. data/lib/github_api/client/orgs.rb +127 -0
  41. data/lib/github_api/client/orgs/hooks.rb +182 -0
  42. data/lib/github_api/client/orgs/members.rb +142 -0
  43. data/lib/github_api/client/orgs/memberships.rb +131 -0
  44. data/lib/github_api/client/orgs/projects.rb +57 -0
  45. data/lib/github_api/client/orgs/teams.rb +407 -0
  46. data/lib/github_api/client/projects.rb +83 -0
  47. data/lib/github_api/client/projects/cards.rb +158 -0
  48. data/lib/github_api/client/projects/columns.rb +146 -0
  49. data/lib/github_api/client/pull_requests.rb +195 -0
  50. data/lib/github_api/client/pull_requests/comments.rb +140 -0
  51. data/lib/github_api/client/pull_requests/reviews.rb +158 -0
  52. data/lib/github_api/client/repos.rb +468 -0
  53. data/lib/github_api/client/repos/branches.rb +48 -0
  54. data/lib/github_api/client/repos/branches/protections.rb +75 -0
  55. data/lib/github_api/client/repos/collaborators.rb +84 -0
  56. data/lib/github_api/client/repos/comments.rb +125 -0
  57. data/lib/github_api/client/repos/commits.rb +80 -0
  58. data/lib/github_api/client/repos/contents.rb +246 -0
  59. data/lib/github_api/client/repos/deployments.rb +138 -0
  60. data/lib/github_api/client/repos/downloads.rb +62 -0
  61. data/lib/github_api/client/repos/forks.rb +48 -0
  62. data/lib/github_api/client/repos/hooks.rb +214 -0
  63. data/lib/github_api/client/repos/keys.rb +104 -0
  64. data/lib/github_api/client/repos/merging.rb +47 -0
  65. data/lib/github_api/client/repos/pages.rb +48 -0
  66. data/lib/github_api/client/repos/projects.rb +62 -0
  67. data/lib/github_api/client/repos/pub_sub_hubbub.rb +133 -0
  68. data/lib/github_api/client/repos/releases.rb +189 -0
  69. data/lib/github_api/client/repos/releases/assets.rb +136 -0
  70. data/lib/github_api/client/repos/releases/tags.rb +24 -0
  71. data/lib/github_api/client/repos/statistics.rb +89 -0
  72. data/lib/github_api/client/repos/statuses.rb +91 -0
  73. data/lib/github_api/client/say.rb +25 -0
  74. data/lib/github_api/client/scopes.rb +46 -0
  75. data/lib/github_api/client/search.rb +133 -0
  76. data/lib/github_api/client/search/legacy.rb +111 -0
  77. data/lib/github_api/client/users.rb +117 -0
  78. data/lib/github_api/client/users/emails.rb +65 -0
  79. data/lib/github_api/client/users/followers.rb +115 -0
  80. data/lib/github_api/client/users/keys.rb +104 -0
  81. data/lib/github_api/configuration.rb +70 -0
  82. data/lib/github_api/connection.rb +82 -0
  83. data/lib/github_api/constants.rb +61 -0
  84. data/lib/github_api/core_ext/array.rb +25 -0
  85. data/lib/github_api/core_ext/hash.rb +91 -0
  86. data/lib/github_api/core_ext/ordered_hash.rb +107 -0
  87. data/lib/github_api/deprecation.rb +39 -0
  88. data/lib/github_api/error.rb +32 -0
  89. data/lib/github_api/error/client_error.rb +89 -0
  90. data/lib/github_api/error/service_error.rb +223 -0
  91. data/lib/github_api/ext/faraday.rb +38 -0
  92. data/lib/github_api/mash.rb +7 -0
  93. data/lib/github_api/middleware.rb +37 -0
  94. data/lib/github_api/mime_type.rb +33 -0
  95. data/lib/github_api/normalizer.rb +23 -0
  96. data/lib/github_api/null_encoder.rb +25 -0
  97. data/lib/github_api/page_iterator.rb +138 -0
  98. data/lib/github_api/page_links.rb +63 -0
  99. data/lib/github_api/paged_request.rb +42 -0
  100. data/lib/github_api/pagination.rb +115 -0
  101. data/lib/github_api/parameter_filter.rb +35 -0
  102. data/lib/github_api/params_hash.rb +115 -0
  103. data/lib/github_api/rate_limit.rb +25 -0
  104. data/lib/github_api/request.rb +85 -0
  105. data/lib/github_api/request/basic_auth.rb +36 -0
  106. data/lib/github_api/request/jsonize.rb +54 -0
  107. data/lib/github_api/request/oauth2.rb +44 -0
  108. data/lib/github_api/request/verbs.rb +63 -0
  109. data/lib/github_api/response.rb +48 -0
  110. data/lib/github_api/response/atom_parser.rb +22 -0
  111. data/lib/github_api/response/follow_redirects.rb +140 -0
  112. data/lib/github_api/response/header.rb +87 -0
  113. data/lib/github_api/response/jsonize.rb +28 -0
  114. data/lib/github_api/response/mashify.rb +24 -0
  115. data/lib/github_api/response/raise_error.rb +22 -0
  116. data/lib/github_api/response/xmlize.rb +27 -0
  117. data/lib/github_api/response_wrapper.rb +161 -0
  118. data/lib/github_api/ssl_certs/cacerts.pem +2183 -0
  119. data/lib/github_api/utils/url.rb +63 -0
  120. data/lib/github_api/validations.rb +22 -0
  121. data/lib/github_api/validations/format.rb +26 -0
  122. data/lib/github_api/validations/presence.rb +32 -0
  123. data/lib/github_api/validations/required.rb +21 -0
  124. data/lib/github_api/validations/token.rb +41 -0
  125. data/lib/github_api/version.rb +5 -0
  126. metadata +338 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7e0786842120e70440331c0ceae848373da9042f
4
+ data.tar.gz: c07497b699800fd5048b4c0d2a7a4b5db6908fce
5
+ SHA512:
6
+ metadata.gz: e7d27ca7b8cdd9873100b1d1986a268315c6bbefe3a21a2ea7788b6433ef8ab1cc35f5f3d84b180994abb04118987293c0eabf864984fd16ca9a8ad34f4bb2e9
7
+ data.tar.gz: bbe1284d85eb777eaaaabe2108b964ed86893cec7120afd0d1d15168c4dc8ee784c9b61f5658b110254ffde46f66599474c8931949c009bef6a04448ac766c99
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Piotr Murach
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,741 @@
1
+ <div align="center">
2
+ <a href="http://piotrmurach.github.io/github/"><img width="136" src="https://github.com/piotrmurach/github/raw/master/icons/github_api.png" alt="github api logo" /></a>
3
+ </div>
4
+
5
+ # GithubAPI [![Gitter](https://badges.gitter.im/Join%20Chat.svg)][gitter]
6
+
7
+ [![Gem Version](https://badge.fury.io/rb/github_api.svg)][gem]
8
+ [![Build Status](https://secure.travis-ci.org/piotrmurach/github.svg?branch=master)][travis]
9
+ [![Code Climate](https://codeclimate.com/github/piotrmurach/github/badges/gpa.svg)][codeclimate]
10
+ [![Coverage Status](https://coveralls.io/repos/piotrmurach/github/badge.svg?branch=master)][coverage]
11
+ [![Inline docs](http://inch-ci.org/github/piotrmurach/github.svg)][inchpages]
12
+ [![Dependency Status](https://gemnasium.com/piotrmurach/github.svg?travis)][gemnasium]
13
+
14
+ [gitter]: https://gitter.im/piotrmurach/github_api
15
+ [gem]: http://badge.fury.io/rb/github_api
16
+ [travis]: http://travis-ci.org/piotrmurach/github
17
+ [codeclimate]: https://codeclimate.com/github/piotrmurach/github
18
+ [coverage]: https://coveralls.io/r/piotrmurach/github
19
+ [inchpages]: http://inch-ci.org/github/piotrmurach/github
20
+ [gemnasium]: https://gemnasium.com/piotrmurach/github
21
+
22
+ [Website](http://piotrmurach.github.io/github/) | [Wiki](https://github.com/piotrmurach/github/wiki) | [RDocs](http://rubydoc.info/github/piotrmurach/github/master/frames)
23
+
24
+ A Ruby client for the official GitHub API.
25
+
26
+ Supports all the API methods. It's built in a modular way. You can either instantiate the whole API wrapper Github.new or use parts of it i.e. Github::Client::Repos.new if working solely with repositories is your main concern. Intuitive query methods allow you easily call API endpoints.
27
+
28
+ ## Features
29
+
30
+ * Intuitive GitHub API interface navigation.
31
+ * It's comprehensive. You can request all GitHub API resources.
32
+ * Modular design allows for working with parts of API.
33
+ * Fully customizable including advanced middleware stack construction.
34
+ * Supports OAuth2 authorization.
35
+ * Flexible argument parsing. You can write expressive and natural queries.
36
+ * Requests pagination with convenient DSL and automatic options.
37
+ * Easy error handling split for client and server type errors.
38
+ * Supports multithreaded environment.
39
+ * Custom media type specification through the 'media' parameter.
40
+ * Request results caching
41
+ * Fully tested with unit and feature tests hitting the live api.
42
+
43
+ ## Installation
44
+
45
+ Install the gem by running
46
+
47
+ ```ruby
48
+ gem install github_api
49
+ ```
50
+
51
+ or put it in your Gemfile and run `bundle install`
52
+
53
+ ```ruby
54
+ gem "github_api"
55
+ ```
56
+
57
+ ## Contents
58
+
59
+ * [1. Usage](#1-usage)
60
+ * [1.1 API Navigation](#11-api-navigation)
61
+ * [1.2 Modularity](#12-modularity)
62
+ * [1.3 Arguments](#13-arguments)
63
+ * [1.4 Response Querying](#14-response-querying)
64
+ * [1.4.1 Response Body](#141-response-body)
65
+ * [1.4.2 Response Headers](#142-response-headers)
66
+ * [1.4.3 Response Success](#143-response-success)
67
+ * [1.5 Request Headers](#15-request-headers)
68
+ * [1.5.1 Media Types](#151-media-types)
69
+ * [2. Configuration](#2-configuration)
70
+ * [2.1 Basic](#21-basic)
71
+ * [2.2 Advanced](#22-advanced)
72
+ * [2.3 SSL](#23-ssl)
73
+ * [2.4 Caching](#24-caching)
74
+ * [3. Authentication](#3-authentication)
75
+ * [3.1 Basic](#31-basic)
76
+ * [3.2 Authorizations API](#32-authorizations-api)
77
+ * [3.3 Scopes](#33-scopes)
78
+ * [3.4 Application OAuth](#34-application-oauth)
79
+ * [3.5 Two-Factor](#35-two-factor)
80
+ * [4. Pagination](#4-pagination)
81
+ * [4.1 Auto pagination](#41-auto-pagination)
82
+ * [5. Error Handling](#5-error-handling)
83
+ * [5.1 Client Error](#51-client-error)
84
+ * [5.2 Service Error](#52-service-error)
85
+ * [5.2.1 Data](#521-data)
86
+ * [5.2.2 Error Messages](#522-error-messages)
87
+ * [6. Examples](#6-examples)
88
+ * [6.1 Rails](#61-rails)
89
+ * [6.2 Manipulating Files](#62-manipulating-files)
90
+ * [7. Testing](#7-testing)
91
+
92
+ ## 1 Usage
93
+
94
+ To start using the gem, you can either perform requests directly on `Github` namespace:
95
+
96
+ ```ruby
97
+ Github.repos.list user: 'piotrmurach'
98
+ ```
99
+
100
+ or create a new client instance like so
101
+
102
+ ```ruby
103
+ github = Github.new
104
+ ```
105
+
106
+ and then call api methods, for instance, to list a given user repositories do
107
+
108
+ ```ruby
109
+ github.repos.list user: 'piotrmurach'
110
+ ```
111
+
112
+ ### 1.1 API Navigation
113
+
114
+ The **github_api** closely mirrors the [GitHub API](https://developer.github.com/v3/) hierarchy. For example, if you want to create a new file in a repository, look up the GitHub API spec. In there you will find contents sub category underneath the repository category. This would translate to the request:
115
+
116
+ ```ruby
117
+ github = Github.new
118
+ github.repos.contents.create 'piotrmurach', 'finite_machine', 'hello.rb',
119
+ path: 'hello.rb',
120
+ content: "puts 'hello ruby'"
121
+ ```
122
+
123
+ The whole library reflects the same api navigation. Therefore, if you need to list releases for a repository do:
124
+
125
+ ```ruby
126
+ github.repos.releases.list 'piotrmurach', 'finite_machine'
127
+ ```
128
+
129
+ or to list a user's followers:
130
+
131
+ ```ruby
132
+ github.users.followers.list 'piotrmurach'
133
+ ```
134
+
135
+ The code base has been extensively documented with examples of how to use each method. Please refer to the [documentation](http://rubydoc.info/github/piotrmurach/github/master/frames) under the `Github::Client` class name.
136
+
137
+ Alternatively, you can find out which methods are supported by an api by calling `actions` on a class or instance. For example, in order to find out available endpoints for `Github::Client::Repos::Contents` api call `actions` method:
138
+
139
+ ```ruby
140
+ Github::Client::Repos::Contents.actions
141
+ => [:archive, :create, :delete, :find, :get, :readme, :update]
142
+ ```
143
+
144
+ ### 1.2 Modularity
145
+
146
+ The code base is modular. This means that you can work specifically with a given part of GitHub API. If you want to only work with activity starring API do the following:
147
+
148
+ ```ruby
149
+ starring = Github::Client::Activity::Starring.new oauth_token: token
150
+ starring.star 'piotrmurach', 'github'
151
+ ```
152
+
153
+ Please refer to the [documentation](http://rubydoc.info/github/piotrmurach/github/master/frames) and look under `Github::Client` to see all available classes.
154
+
155
+ ### 1.3 Arguments
156
+
157
+ The **github_api** library allows for flexible argument parsing.
158
+
159
+ Arguments can be passed directly inside the method called. The `required` arguments are passed in first, followed by optional parameters supplied as hash options:
160
+
161
+ ```ruby
162
+ issues = Github::Client::Issues.new
163
+ issues.milestones.list 'piotrmurach', 'github', state: 'open'
164
+ ```
165
+
166
+ In the previous example, the order of arguments is important. However, each method also allows you to specify `required` arguments using hash symbols and thus remove the need for ordering. Therefore, the same example could be rewritten like so:
167
+
168
+ ```ruby
169
+ issues = Github::Client::Issues.new
170
+ issues.milestones.list user: 'piotrmurach', repo: 'github', state: 'open'
171
+ ```
172
+
173
+ Furthermore, `required` arguments can be passed during instance creation:
174
+
175
+ ```ruby
176
+ issues = Github::Client::Issues.new user: 'piotrmurach', repo: 'github'
177
+ issues.milestones.list state: 'open'
178
+ ```
179
+
180
+ Similarly, the `required` arguments for the request can be passed inside the current scope such as:
181
+
182
+ ```ruby
183
+ issues = Github::Client::Issues.new
184
+ issues.milestones(user: 'piotrmurach', repo: 'github').list state: 'open'
185
+ ```
186
+
187
+ But why limit ourselves? You can mix and match arguments, for example:
188
+
189
+ ```ruby
190
+ issues = Github::Client::Issues.new user: 'piotrmurach'
191
+ issues.milestones(repo: 'github').list
192
+ issues.milestones(repo: 'tty').list
193
+ ```
194
+
195
+ You can also use a bit of syntactic sugar whereby "username/repository" can be passed as well:
196
+
197
+ ```ruby
198
+ issues = Github::Client::Issues.new
199
+ issues.milestones('piotrmurach/github').list
200
+ issues.milestones.list 'piotrmurach/github'
201
+ ```
202
+
203
+ Finally, use the `with` scope to clearly denote your requests
204
+
205
+ ```ruby
206
+ issues = Github::Client::Issues.new
207
+ issues.milestones.with(user: 'piotrmurach', repo: 'github').list
208
+ ```
209
+
210
+ Please consult the method [documentation](http://rubydoc.info/github/piotrmurach/github/master/frames) or [GitHub specification](https://developer.github.com/v3/) to see which arguments are required and what are the option parameters.
211
+
212
+ ### 1.4 Response Querying
213
+
214
+ The response is of type `Github::ResponseWrapper` and allows traversing all the json response attributes like method calls. In addition, if the response returns more than one resource, these will be automatically yielded to the provided block one by one.
215
+
216
+ For example, when request is issued to list all the branches on a given repository, each branch will be yielded one by one:
217
+
218
+ ```ruby
219
+ repos = Github::Client::Repos.new
220
+ repos.branches user: 'piotrmurach', repo: 'github' do |branch|
221
+ puts branch.name
222
+ end
223
+ ```
224
+
225
+ #### 1.4.1 Response Body
226
+
227
+ The `ResponseWrapper` allows you to call json attributes directly as method calls. there is no magic here, all calls are delegated to the response body. Therefore, you can directly inspect request body by calling `body` method on the `ResponseWrapper` like so:
228
+
229
+ ```ruby
230
+ response = repos.branches user: 'piotrmurach', repo: 'github'
231
+ response.body # => Array of branches
232
+ ```
233
+
234
+ #### 1.4.2 Response Headers
235
+
236
+ Each response comes packaged with methods allowing for inspection of HTTP start line and headers. For example, to check for rate limits and status codes do:
237
+
238
+ ```ruby
239
+ response = Github::Client::Repos.branches 'piotrmurach', 'github'
240
+ response.headers.ratelimit_limit # "5000"
241
+ response.headers.ratelimit_remaining # "4999"
242
+ response.headers.status # "200"
243
+ response.headers.content_type # "application/json; charset=utf-8"
244
+ response.headers.etag # "\"2c5dfc54b3fe498779ef3a9ada9a0af9\""
245
+ response.headers.cache_control # "public, max-age=60, s-maxage=60"
246
+ ```
247
+
248
+ #### 1.4.3 Response Success
249
+
250
+ If you want to verify if the response was success, namely, that the `200` code was returned call the `success?` like so:
251
+
252
+ ```ruby
253
+ response = Github::Client::Repos.branches 'piotrmurach', 'github'
254
+ response.success? # => true
255
+ ```
256
+
257
+ ### 1.5 Request Headers
258
+
259
+ It is possible to specify additional header information which will be added to the final request.
260
+
261
+ For example, to set `etag` and `X-Poll_Interval` headers, use the `:headers` hash key inside the `:options` hash like in the following:
262
+
263
+ ```ruby
264
+ events = Github::Client::Activity::Events.new
265
+ events.public headers: {
266
+ 'X-Poll-Interval': 60,
267
+ 'ETag': "a18c3bded88eb5dbb5c849a489412bf3"
268
+ }
269
+ ```
270
+
271
+ #### 1.5.1 Media Types
272
+
273
+ In order to set custom media types for a request use the accept header. By using the `:accept` key you can determine media type like in the example:
274
+
275
+ ```ruby
276
+ issues = Github::Client::Issues.new
277
+ issues.get 'piotrmurach', 'github', 108, accept: 'application/vnd.github.raw'
278
+ ```
279
+
280
+ ## 2 Configuration
281
+
282
+ The **github_api** provides ability to specify global configuration options. These options will be available to all api calls.
283
+
284
+ ### 2.1 Basic
285
+
286
+ The configuration options can be set by using the `configure` helper
287
+
288
+ ```ruby
289
+ Github.configure do |c|
290
+ c.basic_auth = "login:password"
291
+ c.adapter = :typheous
292
+ c.user = 'piotrmurach'
293
+ c.repo = 'finite_machine'
294
+ end
295
+ ```
296
+
297
+ Alternatively, you can configure the settings by passing a block to an instance like:
298
+
299
+ ```ruby
300
+ Github.new do |c|
301
+ c.endpoint = 'https://github.company.com/api/v3'
302
+ c.site = 'https://github.company.com'
303
+ c.upload_endpoint = 'https://github.company.com/api/uploads'
304
+ end
305
+ ```
306
+
307
+ or simply by passing hash of options to an instance like so
308
+
309
+ ```ruby
310
+ github = Github.new basic_auth: 'login:password',
311
+ adapter: :typheous,
312
+ user: 'piotrmurach',
313
+ repo: 'finite_machine'
314
+ ```
315
+
316
+ The following is the full list of available configuration options:
317
+
318
+ ```ruby
319
+ adapter # Http client used for performing requests. Default :net_http
320
+ auto_pagination # Automatically traverse requests page links. Default false
321
+ basic_auth # Basic authentication in form login:password.
322
+ client_id # Oauth client id.
323
+ client_secret # Oauth client secret.
324
+ connection_options # Hash of connection options.
325
+ endpoint # Enterprise API endpoint. Default: 'https://api.github.com'
326
+ oauth_token # Oauth authorization token.
327
+ org # Global organization used in requests if none provided
328
+ per_page # Number of items per page. Max of 100. Default 30.
329
+ repo # Global repository used in requests in none provided
330
+ site # enterprise API web endpoint
331
+ ssl # SSL settings in hash form.
332
+ user # Global user used for requests if none provided
333
+ user_agent # Custom user agent name. Default 'Github API Ruby Gem'
334
+ ```
335
+
336
+ ### 2.2 Advanced
337
+
338
+ The **github_api** will use the default middleware stack which is exposed by calling `stack` on a client instance. However, this stack can be freely modified with methods such as `insert`, `insert_after`, `delete` and `swap`. For instance, to add your `CustomMiddleware` do:
339
+
340
+ ```ruby
341
+ Github.configure do |c|
342
+ c.stack.insert_after Github::Response::Helpers, CustomMiddleware
343
+ end
344
+ ```
345
+
346
+ Furthermore, you can build your entire custom stack and specify other connection options such as `adapter` by doing:
347
+
348
+ ```ruby
349
+ Github.new do |c|
350
+ c.adapter :excon
351
+
352
+ c.stack do |builder|
353
+ builder.use Github::Response::Helpers
354
+ builder.use Github::Response::Jsonize
355
+ end
356
+ end
357
+ ```
358
+
359
+ ### 2.3 SSL
360
+
361
+ By default requests over SSL are set to OpenSSL::SSL::VERIFY_PEER. However, you can turn off peer verification by
362
+
363
+ ```ruby
364
+ github = Github.new ssl: { verify: false }
365
+ ```
366
+
367
+ If your client fails to find CA certs, you can pass other SSL options to specify exactly how the information is sourced
368
+
369
+ ```ruby
370
+ ssl: {
371
+ client_cert: "/usr/local/www.example.com/client_cert.pem"
372
+ client_key: "/user/local/www.example.com/client_key.pem"
373
+ ca_file: "example.com.cert"
374
+ ca_path: "/etc/ssl/"
375
+ }
376
+ ```
377
+
378
+ For instance, download CA root certificates from Mozilla [cacert](http://curl.haxx.se/ca/cacert.pem) and point ca_file at your certificate bundle location. This will allow the client to verify the github.com ssl certificate as authentic.
379
+
380
+ ### 2.4 Caching
381
+
382
+ Caching is supported through the [`faraday-http-cache` gem](https://github.com/plataformatec/faraday-http-cache).
383
+
384
+ Add the gem to your Gemfile:
385
+
386
+ ```ruby
387
+ gem 'faraday-http-cache'
388
+ ```
389
+
390
+ You can now configure cache parameters as follows
391
+
392
+ ```ruby
393
+ Github.configure do |config|
394
+ config.stack = proc do |builder|
395
+ builder.use Faraday::HttpCache, store: Rails.cache
396
+ end
397
+ end
398
+ ```
399
+
400
+ More details on the available options can be found in the gem's own documentation: https://github.com/plataformatec/faraday-http-cache#faraday-http-cache
401
+
402
+ ## 3 Authentication
403
+
404
+ ### 3.1 Basic
405
+
406
+ To start making requests as authenticated user you can use your GitHub username and password like so
407
+
408
+ ```ruby
409
+ Github.new basic_auth: 'login:password'
410
+ ```
411
+
412
+ Though this method is convenient you should strongly consider using `OAuth` for improved security reasons.
413
+
414
+ ### 3.2 Authorizations API
415
+
416
+ #### 3.2.1 For a User
417
+
418
+ To create an access token through the GitHub Authorizations API, you are required to pass your basic credentials and scopes you wish to have for the authentication token.
419
+
420
+ ```ruby
421
+ github = Github.new basic_auth: 'login:password'
422
+ github.auth.create scopes: ['repo'], note: 'admin script'
423
+ ```
424
+
425
+ You can add more than one scope from the `user`, `public_repo`, `repo`, `gist` or leave the scopes parameter out, in which case, the default read-only access will be assumed (includes public user profile info, public repo info, and gists).
426
+
427
+ #### 3.2.2 For an App
428
+
429
+ Furthermore, to create auth token for an application you need to pass `:app` argument together with `:client_id` and `:client_secret` parameters.
430
+
431
+ ```ruby
432
+ github = Github.new basic_auth: 'login:password'
433
+ github.auth.app.create 'client-id', scopes: ['repo']
434
+ ```
435
+
436
+ In order to revoke auth token(s) for an application you must use basic authentication with `client_id` as login and `client_secret` as password.
437
+
438
+ ```ruby
439
+ github = Github.new basic_auth: "client_id:client_secret"
440
+ github.auth.app.delete 'client-id'
441
+ ```
442
+
443
+ Revoke a specific app token.
444
+
445
+ ```ruby
446
+ github.auth.app.delete 'client-id', 'access-token'
447
+ ```
448
+
449
+ ### 3.3 Scopes
450
+
451
+ You can check OAuth scopes you have by:
452
+
453
+ ```ruby
454
+ github = Github.new oauth_token: 'token'
455
+ github.scopes.list # => ['repo']
456
+ ```
457
+
458
+ or inidividually for a given user:
459
+
460
+ ```ruby
461
+ github = Github.new
462
+ github.scopes.list 'token'
463
+ ```
464
+
465
+ To list the scopes that the particular GitHub API action checks for do:
466
+
467
+ ```ruby
468
+ repos = Github::Client::Repos.new
469
+ response = repos.list user: 'piotrmurach'
470
+ response.headers.accepted_oauth_scopes # => ['delete_repo', 'repo', 'public_repo']
471
+ ```
472
+
473
+ To understand what each scope means refer to [documentation](http://developer.github.com/v3/oauth/#scopes)
474
+
475
+ ### 3.4 Application OAuth
476
+
477
+ In order to authenticate your app through OAuth2 on GitHub you need to
478
+
479
+ * Visit https://github.com/settings/applications/new and register your app.
480
+ You will need to be logged in to initially register the application.
481
+
482
+ * Authorize your credentials https://github.com/login/oauth/authorize
483
+
484
+ You can use convenience methods to help you achieve this using **GithubAPI** gem:
485
+
486
+ ```ruby
487
+ github = Github.new client_id: '...', client_secret: '...'
488
+ github.authorize_url redirect_uri: 'http://localhost', scope: 'repo'
489
+ # => "https://github.com/login/oauth/authorize?scope=repo&response_type=code&client_id='...'&redirect_uri=http%3A%2F%2Flocalhost"
490
+ ```
491
+ After you get your authorization code, call to receive your access_token
492
+
493
+ ```ruby
494
+ token = github.get_token( authorization_code )
495
+ ```
496
+
497
+ Once you have your access token, configure your github instance following instructions under Configuration.
498
+
499
+ **Note**: If you are working locally (i.e. your app URL and callback URL are localhost), do not specify a ```:redirect_uri``` otherwise you will get a ```redirect_uri_mismatch``` error.
500
+
501
+ ### 3.5 Two-Factor
502
+
503
+ In order to use [Two-Factor](https://help.github.com/articles/about-two-factor-authentication) authentication you need provide `X-GitHub-OTP: required; :2fa-type` header.
504
+
505
+ You can add headers during initialization:
506
+
507
+ ```ruby
508
+ Github.new do |config|
509
+ config.basic_auth = "user:password"
510
+ config.connection_options = {headers: {"X-GitHub-OTP" => '2fa token'}}
511
+ end
512
+ ```
513
+
514
+ or per request:
515
+
516
+ ```ruby
517
+ github = Github.new basic_auth: 'login:password'
518
+ github.oauth.create scopes: ["public_repo"],
519
+ headers: {"X-GitHub-OTP" => "2fa token"}
520
+ ```
521
+
522
+ ## 4 Pagination
523
+
524
+ Any request that returns multiple items will be paginated to 30 items by default. You can specify custom `page` and `per_page` query parameters to alter default behavior. For instance:
525
+
526
+ ```ruby
527
+ repos = Github::Client::Repos.new
528
+ response = repos.list user: 'wycats', per_page: 10, page: 5
529
+ ```
530
+
531
+ Then you can query the pagination information included in the link header by:
532
+
533
+ ```ruby
534
+ response.links.first # Shows the URL of the first page of results.
535
+ response.links.next # Shows the URL of the immediate next page of results.
536
+ response.links.prev # Shows the URL of the immediate previous page of results.
537
+ response.links.last # Shows the URL of the last page of results.
538
+ ```
539
+
540
+ In order to iterate through the entire result set page by page, you can use convenience methods:
541
+
542
+ ```ruby
543
+ response.each_page do |page|
544
+ page.each do |repo|
545
+ puts repo.name
546
+ end
547
+ end
548
+ ```
549
+
550
+ or use `has_next_page?` and `next_page` helper methods like in the following:
551
+
552
+ ```ruby
553
+ while response.has_next_page?
554
+ ... process response ...
555
+ res.next_page
556
+ end
557
+ ```
558
+
559
+ One can also navigate straight to the specific page by:
560
+
561
+ ```ruby
562
+ res.count_pages # Number of pages
563
+ res.page 5 # Requests given page if it exists, nil otherwise
564
+ res.first_page # Get first page
565
+ res.next_page # Get next page
566
+ res.prev_page # Get previous page
567
+ res.last_page # Get last page
568
+ ```
569
+
570
+ ### 4.1 Auto pagination
571
+
572
+ You can retrieve all pages in one invocation by passing the `auto_pagination` option like so:
573
+
574
+ ```ruby
575
+ github = Github.new auto_pagination: true
576
+ ```
577
+
578
+ Depending at what stage you pass the `auto_pagination` it will affect all or only a single request. For example, in order to auto paginate all Repository API methods do:
579
+
580
+ ```ruby
581
+ Github::Сlient::Repos.new auto_pagination: true
582
+ ```
583
+
584
+ However, to only auto paginate results for a single request do:
585
+
586
+ ```ruby
587
+ Github::Client::Repos.new.list user: '...', auto_pagination: true
588
+ ```
589
+
590
+ ## 5 Error Handling
591
+
592
+ The generic error class `Github::Error::GithubError` will handle both the client (`Github::Error::ClientError`) and service (`Github::Error::ServiceError`) side errors.
593
+
594
+ For instance in your code you can catch errors like
595
+
596
+ ```ruby
597
+ begin
598
+ # Do something with github_api gem
599
+ rescue Github::Error::GithubError => e
600
+ puts e.message
601
+ if e.is_a? Github::Error::ServiceError
602
+ # handle GitHub service errors such as 404
603
+ elsif e.is_a? Github::Error::ClientError
604
+ # handle client errors e.i. missing required parameter in request
605
+ end
606
+ end
607
+ ```
608
+
609
+ ### 5.1 Client Error
610
+
611
+ Any time **Github** client has a problem sending request a `Github::Error::ClientError` is raised that will provide a summary of the problem and possible solutions.
612
+
613
+ ### 5.2 Service Error
614
+
615
+ When the **Github** client receives a HTTP response from GitHub service that indicates error then `Github::Error::ServiceError` is raised.
616
+
617
+ There are number of specific error types such as `Github::Error::NotAcceptable` when `406` status code is returned.
618
+
619
+ #### 5.2.1 Data
620
+
621
+ When `Github::Error::ServiceError` is raised you can call `data` to access it payload in JSON format.
622
+
623
+ #### 5.2.2 Error messages
624
+
625
+ Anytime there are error messages provided with `Github::Error::ServiceError` you can access them by calling `error_messages` helper.
626
+
627
+ ## 6 Examples
628
+
629
+ ### 6.1 Rails
630
+
631
+ A Rails controller that allows a user to authorize their GitHub account and then performs a request.
632
+
633
+ ```ruby
634
+ class GithubController < ApplicationController
635
+
636
+ def authorize
637
+ address = github.authorize_url redirect_uri: 'http://...', scope: 'repo'
638
+ redirect_to address
639
+ end
640
+
641
+ def callback
642
+ authorization_code = params[:code]
643
+ access_token = github.get_token authorization_code
644
+ access_token.token # => returns token value
645
+ end
646
+
647
+ private
648
+
649
+ def github
650
+ @github ||= Github.new client_id: '...', client_secret: '...'
651
+ end
652
+ end
653
+ ```
654
+
655
+ ### 6.2 Manipulating Files
656
+
657
+ In order to be able to create/update/remove files you need to use Contents API like so:
658
+
659
+ ```ruby
660
+ contents = Github::Client::Repos::Contents.new oauth_token: '...'
661
+ ```
662
+
663
+ Having instantiated the contents, to create a file do:
664
+
665
+ ```ruby
666
+ contents.create 'username', 'repo_name', 'full_path_to/file.ext',
667
+ path: 'full_path_to/file.ext',
668
+ message: 'Your commit message',
669
+ content: 'The contents of your file'
670
+ ```
671
+
672
+ Content is all Base64 encoded to/from the API, and when you create a file it encodes it automatically for you.
673
+
674
+ To update a file, first you need to find the file so you can get the SHA you're updating off of:
675
+
676
+ ```ruby
677
+ file = contents.find path: 'full_path_to/file.ext'
678
+ ```
679
+
680
+ Then update the file just like you do with creating:
681
+
682
+ ```ruby
683
+ contents.update 'username', 'repo_name', 'full_path_to/file.ext',
684
+ path: 'full_path_to/file.ext'
685
+ message: 'Your commit message',
686
+ content: 'The contents to be updated',
687
+ sha: file.sha
688
+ ```
689
+
690
+ Finally to remove a file, find the file so you can get the SHA you're removing:
691
+
692
+ ```ruby
693
+ file = contents.find path: 'full_path_to/file.ext'
694
+ ```
695
+
696
+ Then delete the file like so:
697
+
698
+ ```ruby
699
+ github.delete 'username', 'tome-of-knowledge', 'full_path_to/file.ext',
700
+ path: 'full_path_to/file.ext',
701
+ message: 'Your Commit Message',
702
+ sha: file.sha
703
+ ```
704
+
705
+ ## 7 Testing
706
+
707
+ The test suite is split into two groups, `live` and `mock`.
708
+
709
+ The `live` tests are in the `features` folder and exercise the GitHub API directly by making live requests and then caching responses with VCR in directory named `features\cassettes`. For details on how to get set up, please navigate to the `features` folder.
710
+
711
+ To run all feature tests do:
712
+
713
+ ```ruby
714
+ bundle exec rake features
715
+ ```
716
+
717
+ The `mock` tests are in the `spec` folder and their primary concern is to test the gem internals without the hindrance of external calls.
718
+
719
+ To run all specs do:
720
+
721
+ ```ruby
722
+ bundle exec rake spec
723
+ ```
724
+
725
+ Finally to run all tests do:
726
+
727
+ ```ruby
728
+ bundle exec rake
729
+ ```
730
+
731
+ ## Development
732
+
733
+ Questions or problems? Please post them on the [issue tracker](https://github.com/piotrmurach/github/issues). You can contribute changes by forking the project and submitting a pull request. You can ensure the tests are passing by running `bundle` and `rake`.
734
+
735
+ ## Contributing
736
+
737
+ Bug reports and pull requests are welcome on GitHub at https://github.com/piotrmurach/github. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
738
+
739
+ ## Copyright
740
+
741
+ Copyright (c) 2011-2017 Piotr Murach. See LICENSE.txt for further details.