octokit 4.14.0 → 4.20.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -11,7 +11,7 @@ module Octokit
11
11
  # @overload pull_requests(repo, options)
12
12
  # @param repo [Integer, String, Hash, Repository] A GitHub repository
13
13
  # @param options [Hash] Method options
14
- # @option options [String] :state `open` or `closed`.
14
+ # @option options [String] :state `open` or `closed` or `all`.
15
15
  # @return [Array<Sawyer::Resource>] Array of pulls
16
16
  # @see https://developer.github.com/v3/pulls/#list-pull-requests
17
17
  # @example
@@ -60,11 +60,13 @@ module Octokit
60
60
  # @param repo [Integer, String, Repository, Hash] A GitHub repository
61
61
  # @param ref [String] The ref, e.g. <tt>tags/v0.0.3</tt>
62
62
  # @param sha [String] A SHA, e.g. <tt>827efc6d56897b048c772eb4087f854f46256132</tt>
63
- # @param force [Boolean] A flag indicating one wants to force the update to make sure the update is a fast-forward update.
63
+ # @param force [Boolean] A flag indicating whether to force the update or to make sure the update is a fast-forward update.
64
64
  # @return [Array<Sawyer::Resource>] The list of references updated
65
65
  # @see https://developer.github.com/v3/git/refs/#update-a-reference
66
66
  # @example Force update heads/sc/featureA for octocat/Hello-World with sha aa218f56b14c9653891f9e74264a383fa43fefbd
67
67
  # Octokit.update_ref("octocat/Hello-World", "heads/sc/featureA", "aa218f56b14c9653891f9e74264a383fa43fefbd")
68
+ # @example Fast-forward update heads/sc/featureA for octocat/Hello-World with sha aa218f56b14c9653891f9e74264a383fa43fefbd
69
+ # Octokit.update_ref("octocat/Hello-World", "heads/sc/featureA", "aa218f56b14c9653891f9e74264a383fa43fefbd", false)
68
70
  def update_ref(repo, ref, sha, force = true, options = {})
69
71
  parameters = {
70
72
  :sha => sha,
@@ -79,11 +81,13 @@ module Octokit
79
81
  # @param repo [Integer, String, Repository, Hash] A GitHub repository
80
82
  # @param branch [String] The ref, e.g. <tt>feature/new-shiny</tt>
81
83
  # @param sha [String] A SHA, e.g. <tt>827efc6d56897b048c772eb4087f854f46256132</tt>
82
- # @param force [Boolean] A flag indicating one wants to force the update to make sure the update is a fast-forward update.
84
+ # @param force [Boolean] A flag indicating whether to force the update or to make sure the update is a fast-forward update.
83
85
  # @return [Array<Sawyer::Resource>] The list of references updated
84
86
  # @see https://developer.github.com/v3/git/refs/#update-a-reference
85
87
  # @example Force update heads/sc/featureA for octocat/Hello-World with sha aa218f56b14c9653891f9e74264a383fa43fefbd
86
- # Octokit.update_ref("octocat/Hello-World","sc/featureA", "aa218f56b14c9653891f9e74264a383fa43fefbd")
88
+ # Octokit.update_branch("octocat/Hello-World", "sc/featureA", "aa218f56b14c9653891f9e74264a383fa43fefbd")
89
+ # @example Fast-forward update heads/sc/featureA for octocat/Hello-World with sha aa218f56b14c9653891f9e74264a383fa43fefbd
90
+ # Octokit.update_branch("octocat/Hello-World", "sc/featureA", "aa218f56b14c9653891f9e74264a383fa43fefbd", false)
87
91
  def update_branch(repo, branch, sha, force = true, options = {})
88
92
  update_ref repo, "heads/#{branch}", sha, force, options
89
93
  end
@@ -32,7 +32,7 @@ module Octokit
32
32
 
33
33
  # Edit a repository
34
34
  #
35
- # @see https://developer.github.com/v3/repos/#edit
35
+ # @see https://developer.github.com/v3/repos/#update-a-repository
36
36
  # @param repo [String, Hash, Repository] A GitHub repository
37
37
  # @param options [Hash] Repository information to update
38
38
  # @option options [String] :name Name of the repo
@@ -41,11 +41,15 @@ module Octokit
41
41
  # @option options [String] :private `true` makes the repository private, and `false` makes it public.
42
42
  # @option options [String] :has_issues `true` enables issues for this repo, `false` disables issues.
43
43
  # @option options [String] :has_wiki `true` enables wiki for this repo, `false` disables wiki.
44
+ # @option options [Boolean] :is_template `true` makes the repository a template, `false` makes it not a template.
44
45
  # @option options [String] :has_downloads `true` enables downloads for this repo, `false` disables downloads.
45
46
  # @option options [String] :default_branch Update the default branch for this repository.
46
47
  # @return [Sawyer::Resource] Repository information
47
48
  def edit_repository(repo, options = {})
48
49
  repo = Repository.new(repo)
50
+ if options.include? :is_template
51
+ options = ensure_api_media_type(:template_repositories, options)
52
+ end
49
53
  options[:name] ||= repo.name
50
54
  patch "repos/#{repo}", options
51
55
  end
@@ -144,6 +148,7 @@ module Octokit
144
148
  # @option options [String] :private `true` makes the repository private, and `false` makes it public.
145
149
  # @option options [String] :has_issues `true` enables issues for this repo, `false` disables issues.
146
150
  # @option options [String] :has_wiki `true` enables wiki for this repo, `false` disables wiki.
151
+ # @option options [Boolean] :is_template `true` makes this repo available as a template repository, `false` to prevent it.
147
152
  # @option options [String] :has_downloads `true` enables downloads for this repo, `false` disables downloads.
148
153
  # @option options [String] :organization Short name for the org under which to create the repo.
149
154
  # @option options [Integer] :team_id The id of the team that will be granted access to this repository. This is only valid when creating a repo in an organization.
@@ -155,6 +160,9 @@ module Octokit
155
160
  opts = options.dup
156
161
  organization = opts.delete :organization
157
162
  opts.merge! :name => name
163
+ if opts.include? :is_template
164
+ opts = ensure_api_media_type(:template_repositories, opts)
165
+ end
158
166
 
159
167
  if organization.nil?
160
168
  post 'user/repos', opts
@@ -192,6 +200,22 @@ module Octokit
192
200
  end
193
201
  alias :transfer_repo :transfer_repository
194
202
 
203
+ # Create a repository for a user or organization generated from a template repository
204
+ #
205
+ # @param repo [Integer, String, Hash, Repository] A GitHub template repository
206
+ # @param name [String] Name of the new repo
207
+ # @option options [String] :owner Organization or user who the new repository will belong to.
208
+ # @option options [String] :description Description of the repo
209
+ # @option options [String] :private `true` makes the repository private, and `false` makes it public.
210
+ # @option options [Boolean] :include_all_branches `true` copies all branches from the template repository, `false` (default) makes it only copy the master branch.
211
+ # @return [Sawyer::Resource] Repository info for the new repository
212
+ def create_repository_from_template(repo, name, options = {})
213
+ options.merge! :name => name
214
+ options = ensure_api_media_type(:template_repositories, options)
215
+ post "#{Repository.path repo}/generate", options
216
+ end
217
+ alias :create_repo_from_template :create_repository_from_template
218
+
195
219
  # Hide a public repository
196
220
  #
197
221
  # @param repo [Integer, String, Hash, Repository] A GitHub repository
@@ -405,7 +429,7 @@ module Octokit
405
429
  # @example List topics for octokit/octokit.rb
406
430
  # Octokit.topics('octokit/octokit.rb')
407
431
  # @example List topics for octokit/octokit.rb
408
- # client.topics('octokit/octokit.rb')
432
+ # client.topics('octokit/octokit.rb')
409
433
  def topics(repo, options = {})
410
434
  opts = ensure_api_media_type(:topics, options)
411
435
  paginate "#{Repository.path repo}/topics", opts
@@ -562,14 +586,14 @@ module Octokit
562
586
  #
563
587
  # @param repo [Integer, String, Hash, Repository] A GitHub repository.
564
588
  # @param branch [String] Branch name
565
- # @option options [Hash] :required_status_checks If not null, the following keys are required:
566
- # <tt>:enforce_admins [boolean] Enforce required status checks for repository administrators.</tt>
567
- # <tt>:strict [boolean] Require branches to be up to date before merging.</tt>
568
- # <tt>:contexts [Array] The list of status checks to require in order to merge into this branch</tt>
589
+ # @option options [Hash] :required_status_checks If not null, the following keys are required:
590
+ # <tt>:enforce_admins [boolean] Enforce required status checks for repository administrators.</tt>
591
+ # <tt>:strict [boolean] Require branches to be up to date before merging.</tt>
592
+ # <tt>:contexts [Array] The list of status checks to require in order to merge into this branch</tt>
569
593
  #
570
594
  # @option options [Hash] :restrictions If not null, the following keys are required:
571
- # <tt>:users [Array] The list of user logins with push access</tt>
572
- # <tt>:teams [Array] The list of team slugs with push access</tt>.
595
+ # <tt>:users [Array] The list of user logins with push access</tt>
596
+ # <tt>:teams [Array] The list of team slugs with push access</tt>.
573
597
  #
574
598
  # Teams and users restrictions are only available for organization-owned repositories.
575
599
  # @return [Sawyer::Resource] The protected branch
@@ -696,6 +720,62 @@ module Octokit
696
720
  def delete_subscription(repo, options = {})
697
721
  boolean_from_response :delete, "#{Repository.path repo}/subscription", options
698
722
  end
723
+
724
+ # Create a repository dispatch event
725
+ #
726
+ # @param repo [Integer, String, Hash, Repository] A GitHub repository.
727
+ # @param event_type [String] A custom webhook event name.
728
+ # @option options [Hash] :client_payload payload with extra information
729
+ # about the webhook event that your action or worklow may use.
730
+ #
731
+ # @return [Boolean] True if event was dispatched, false otherwise.
732
+ # @see https://developer.github.com/v3/repos/#create-a-repository-dispatch-event
733
+ def dispatch_event(repo, event_type, options = {})
734
+ boolean_from_response :post, "#{Repository.path repo}/dispatches", options.merge({ event_type: event_type })
735
+ end
736
+
737
+ # Check to see if vulnerability alerts are enabled for a repository
738
+ #
739
+ # The authenticated user must have admin access to the repository.
740
+ #
741
+ # @param repo [Integer, String, Hash, Repository] A GitHub repository.
742
+ # @return [Boolean] True if vulnerability alerts are enabled, false otherwise.
743
+ # @see https://docs.github.com/en/rest/reference/repos#check-if-vulnerability-alerts-are-enabled-for-a-repository
744
+ #
745
+ # @example
746
+ # @client.vulnerability_alerts_enabled?("octokit/octokit.rb")
747
+ def vulnerability_alerts_enabled?(repo, options = {})
748
+ opts = ensure_api_media_type(:vulnerability_alerts, options)
749
+ boolean_from_response(:get, "#{Repository.path repo}/vulnerability-alerts", opts)
750
+ end
751
+
752
+ # Enable vulnerability alerts for a repository
753
+ #
754
+ # @param repo [Integer, String, Hash, Repository] A GitHub repository.
755
+ # @param options [Hash]
756
+ #
757
+ # @return [Boolean] True if vulnerability alerts enabled, false otherwise.
758
+ # @see https://docs.github.com/en/rest/reference/repos#enable-vulnerability-alerts
759
+ # @example Enable vulnerability alerts for a repository
760
+ # @client.enable_vulnerability_alerts("octokit/octokit.rb")
761
+ def enable_vulnerability_alerts(repo, options = {})
762
+ opts = ensure_api_media_type(:vulnerability_alerts, options)
763
+ boolean_from_response(:put, "#{Repository.path repo}/vulnerability-alerts", opts)
764
+ end
765
+
766
+ # Disable vulnerability alerts for a repository
767
+ #
768
+ # @param repo [Integer, String, Hash, Repository] A GitHub repository.
769
+ # @param options [Hash]
770
+ #
771
+ # @return [Boolean] True if vulnerability alerts disabled, false otherwise.
772
+ # @see https://docs.github.com/en/rest/reference/repos#disable-vulnerability-alerts
773
+ # @example Disable vulnerability alerts for a repository
774
+ # @client.disable_vulnerability_alerts("octokit/octokit.rb")
775
+ def disable_vulnerability_alerts(repo, options = {})
776
+ opts = ensure_api_media_type(:vulnerability_alerts, options)
777
+ boolean_from_response(:delete, "#{Repository.path repo}/vulnerability-alerts", opts)
778
+ end
699
779
  end
700
780
  end
701
781
  end
@@ -13,7 +13,7 @@ module Octokit
13
13
  # @param repo [Integer, String, Hash, Repository] A GitHub repository
14
14
  # @param user [String] User GitHub username to add
15
15
  # @return [Sawyer::Resource] The repository invitation
16
- # @see https://developer.github.com/v3/repos/invitations/#invite-a-user-to-a-repository
16
+ # @see https://developer.github.com/v3/repos/collaborators/#add-user-as-a-collaborator
17
17
  def invite_user_to_repository(repo, user, options = {})
18
18
  put "#{Repository.path repo}/collaborators/#{user}", options
19
19
  end
@@ -204,6 +204,24 @@ module Octokit
204
204
  options = options.merge(reviewers)
205
205
  delete "#{Repository.path repo}/pulls/#{id}/requested_reviewers", options
206
206
  end
207
+
208
+ # Update a review request comment
209
+ #
210
+ # @param repo [Integer, String, Hash, Repository] A GitHub repository
211
+ # @param number [Integer] Number ID of the pull request
212
+ # @param review [Integer] The id of the review
213
+ # @param body [String] body text of the pull request review.
214
+ # @param options [Hash] Method options
215
+ # @see https://developer.github.com/v3/pulls/reviews/#update-a-pull-request-review
216
+ #
217
+ # @example
218
+ # @client.update_pull_request_review('octokit/octokit.rb', 825, 6505518, 'This is close to perfect! Please address the suggested inline change. And add more about this.')
219
+ #
220
+ # @return [Sawyer::Resource] Hash representing the review comment
221
+ def update_pull_request_review(repo, number, review, body, options = {})
222
+ options[:body] = body
223
+ put "#{Repository.path repo}/pulls/#{number}/reviews/#{review}", options
224
+ end
207
225
  end
208
226
  end
209
227
  end
@@ -44,7 +44,7 @@ module Octokit
44
44
  # @option options [Integer] :page Page of paginated results
45
45
  # @option options [Integer] :per_page Number of items per page
46
46
  # @return [Sawyer::Resource] Search results object
47
- # @see https://developer.github.com/v3/search/#search-issues
47
+ # @see https://developer.github.com/v3/search/#search-issues-and-pull-requests
48
48
  def search_issues(query, options = {})
49
49
  search "search/issues", query, options
50
50
  end
@@ -340,6 +340,92 @@ module Octokit
340
340
  end
341
341
  alias :watched :subscriptions
342
342
 
343
+ # Initiates the generation of a migration archive.
344
+ #
345
+ # Requires authenticated user.
346
+ #
347
+ # @param repositories [Array<String>] :repositories Repositories for the organization.
348
+ # @option options [Boolean, optional] :lock_repositories Indicates whether repositories should be locked during migration
349
+ # @option options [Boolean, optional] :exclude_attachments Exclude attachments fro the migration data
350
+ # @return [Sawyer::Resource] Hash representing the new migration.
351
+ # @example
352
+ # @client.start_migration(['octocat/hello-world'])
353
+ # @see https://docs.github.com/en/rest/reference/migrations#start-a-user-migration
354
+ def start_user_migration(repositories, options = {})
355
+ options = ensure_api_media_type(:migrations, options)
356
+ options[:repositories] = repositories
357
+ post "user/migrations", options
358
+ end
359
+
360
+ # Lists the most recent migrations.
361
+ #
362
+ # Requires authenticated user.
363
+ #
364
+ # @return [Array<Sawyer::Resource>] Array of migration resources.
365
+ # @see https://docs.github.com/en/rest/reference/migrations#list-user-migrations
366
+ def user_migrations(options = {})
367
+ options = ensure_api_media_type(:migrations, options)
368
+ paginate "user/migrations", options
369
+ end
370
+
371
+ # Fetches the status of a migration.
372
+ #
373
+ # Requires authenticated user.
374
+ #
375
+ # @param id [Integer] ID number of the migration.
376
+ # @see https://docs.github.com/en/rest/reference/migrations#get-a-user-migration-status
377
+ def user_migration_status(id, options = {})
378
+ options = ensure_api_media_type(:migrations, options)
379
+ get "user/migrations/#{id}", options
380
+ end
381
+
382
+ # Fetches the URL to a migration archive.
383
+ #
384
+ # Requires authenticated user.
385
+ #
386
+ # @param id [Integer] ID number of the migration.
387
+ # @see https://docs.github.com/en/rest/reference/migrations#download-a-user-migration-archive
388
+ def user_migration_archive_url(id, options = {})
389
+ options = ensure_api_media_type(:migrations, options)
390
+ url = "user/migrations/#{id}/archive"
391
+
392
+ response = client_without_redirects(options).get(url)
393
+ response.headers['location']
394
+ end
395
+
396
+ # Deletes a previous migration archive.
397
+ #
398
+ # Requires authenticated user.
399
+ #
400
+ # @param id [Integer] ID number of the migration.
401
+ # @see https://docs.github.com/en/rest/reference/migrations#delete-a-user-migration-archive
402
+ def delete_user_migration_archive(id, options = {})
403
+ options = ensure_api_media_type(:migrations, options)
404
+ delete "user/migrations/#{id}/archive", options
405
+ end
406
+
407
+ # List repositories for a user migration.
408
+ #
409
+ # Requires authenticated user.
410
+ #
411
+ # @param id [Integer] ID number of the migration.
412
+ # @see https://docs.github.com/en/rest/reference/migrations#list-repositories-for-a-user-migration
413
+ def user_migration_repositories(id, options = {})
414
+ options = ensure_api_media_type(:migrations, options)
415
+ get "user/migrations/#{id}/repositories", options
416
+ end
417
+
418
+ # Unlock a user repository which has been locked by a migration.
419
+ #
420
+ # Requires authenticated user.
421
+ #
422
+ # @param id [Integer] ID number of the migration.
423
+ # @param repo [String] Name of the repository.
424
+ # @see https://docs.github.com/en/rest/reference/migrations#unlock-a-user-repository
425
+ def unlock_user_repository(id, repo, options = {})
426
+ options = ensure_api_media_type(:migrations, options)
427
+ delete "user/migrations/#{id}/repos/#{repo}/lock", options
428
+ end
343
429
  end
344
430
 
345
431
  private
@@ -113,7 +113,7 @@ module Octokit
113
113
  elsif bearer_authenticated?
114
114
  http.authorization 'Bearer', @bearer_token
115
115
  elsif application_authenticated?
116
- http.params = http.params.merge application_authentication
116
+ http.basic_auth(@client_id, @client_secret)
117
117
  end
118
118
  end
119
119
  end
@@ -155,6 +155,9 @@ module Octokit
155
155
 
156
156
  @last_response = response = agent.call(method, Addressable::URI.parse(path.to_s).normalize.to_s, data, options)
157
157
  response.data
158
+ rescue Octokit::Error => error
159
+ @last_response = nil
160
+ raise error
158
161
  end
159
162
 
160
163
  # Executes the request, checking if it was successful
@@ -162,7 +165,7 @@ module Octokit
162
165
  # @return [Boolean] True on success, false otherwise
163
166
  def boolean_from_response(method, path, options = {})
164
167
  request(method, path, options)
165
- @last_response.status == 204
168
+ [201, 202, 204].include? @last_response.status
166
169
  rescue Octokit::NotFound
167
170
  false
168
171
  end
@@ -177,12 +180,12 @@ module Octokit
177
180
  conn_opts[:proxy] = @proxy if @proxy
178
181
  if conn_opts[:ssl].nil?
179
182
  conn_opts[:ssl] = { :verify_mode => @ssl_verify_mode } if @ssl_verify_mode
180
- else
181
- if @connection_options[:ssl][:verify] == false
182
- conn_opts[:ssl] = { :verify_mode => 0}
183
- else
184
- conn_opts[:ssl] = { :verify_mode => @ssl_verify_mode }
185
- end
183
+ else
184
+ verify = @connection_options[:ssl][:verify]
185
+ conn_opts[:ssl] = {
186
+ :verify => verify,
187
+ :verify_mode => verify == false ? 0 : @ssl_verify_mode
188
+ }
186
189
  end
187
190
  opts[:faraday] = Faraday.new(conn_opts)
188
191
 
@@ -1,7 +1,7 @@
1
1
  module Octokit
2
2
  # Custom error class for rescuing from all GitHub errors
3
3
  class Error < StandardError
4
-
4
+ attr_reader :context
5
5
  # Returns the appropriate Octokit::Error subclass based
6
6
  # on status and response message
7
7
  #
@@ -21,7 +21,7 @@ module Octokit
21
21
  when 406 then Octokit::NotAcceptable
22
22
  when 409 then Octokit::Conflict
23
23
  when 415 then Octokit::UnsupportedMediaType
24
- when 422 then Octokit::UnprocessableEntity
24
+ when 422 then error_for_422(body)
25
25
  when 451 then Octokit::UnavailableForLegalReasons
26
26
  when 400..499 then Octokit::ClientError
27
27
  when 500 then Octokit::InternalServerError
@@ -34,9 +34,16 @@ module Octokit
34
34
  end
35
35
  end
36
36
 
37
+ def build_error_context
38
+ if RATE_LIMITED_ERRORS.include?(self.class)
39
+ @context = Octokit::RateLimit.from_response(@response)
40
+ end
41
+ end
42
+
37
43
  def initialize(response=nil)
38
44
  @response = response
39
45
  super(build_error_message)
46
+ build_error_context
40
47
  end
41
48
 
42
49
  # Documentation URL returned by the API for some errors
@@ -63,6 +70,8 @@ module Octokit
63
70
  Octokit::TooManyRequests
64
71
  elsif body =~ /login attempts exceeded/i
65
72
  Octokit::TooManyLoginAttempts
73
+ elsif body =~ /returns blobs up to [0-9]+ MB/i
74
+ Octokit::TooLargeContent
66
75
  elsif body =~ /abuse/i
67
76
  Octokit::AbuseDetected
68
77
  elsif body =~ /repository access blocked/i
@@ -71,6 +80,12 @@ module Octokit
71
80
  Octokit::UnverifiedEmail
72
81
  elsif body =~ /account was suspended/i
73
82
  Octokit::AccountSuspended
83
+ elsif body =~ /billing issue/i
84
+ Octokit::BillingIssue
85
+ elsif body =~ /Resource protected by organization SAML enforcement/i
86
+ Octokit::SAMLProtected
87
+ elsif body =~ /suspended your access|This installation has been suspended/i
88
+ Octokit::InstallationSuspended
74
89
  else
75
90
  Octokit::Forbidden
76
91
  end
@@ -86,6 +101,16 @@ module Octokit
86
101
  end
87
102
  end
88
103
 
104
+ # Return most appropriate error for 422 HTTP status code
105
+ # @private
106
+ def self.error_for_422(body)
107
+ if body =~ /PullRequestReviewComment/i && body =~ /(commit_id|end_commit_oid) is not part of the pull request/i
108
+ Octokit::CommitIsNotPartOfPullRequest
109
+ else
110
+ Octokit::UnprocessableEntity
111
+ end
112
+ end
113
+
89
114
  # Array of validation errors
90
115
  # @return [Array<Hash>] Error info
91
116
  def errors
@@ -231,6 +256,10 @@ module Octokit
231
256
  # and body matches 'login attempts exceeded'
232
257
  class TooManyLoginAttempts < Forbidden; end
233
258
 
259
+ # Raised when GitHub returns a 403 HTTP status code
260
+ # and body matches 'returns blobs up to [0-9]+ MB'
261
+ class TooLargeContent < Forbidden; end
262
+
234
263
  # Raised when GitHub returns a 403 HTTP status code
235
264
  # and body matches 'abuse'
236
265
  class AbuseDetected < Forbidden; end
@@ -247,6 +276,18 @@ module Octokit
247
276
  # and body matches 'account was suspended'
248
277
  class AccountSuspended < Forbidden; end
249
278
 
279
+ # Raised when GitHub returns a 403 HTTP status code
280
+ # and body matches 'billing issue'
281
+ class BillingIssue < Forbidden; end
282
+
283
+ # Raised when GitHub returns a 403 HTTP status code
284
+ # and body matches 'Resource protected by organization SAML enforcement'
285
+ class SAMLProtected < Forbidden; end
286
+
287
+ # Raised when GitHub returns a 403 HTTP status code
288
+ # and body matches 'suspended your access'
289
+ class InstallationSuspended < Forbidden; end
290
+
250
291
  # Raised when GitHub returns a 404 HTTP status code
251
292
  class NotFound < ClientError; end
252
293
 
@@ -269,6 +310,10 @@ module Octokit
269
310
  # Raised when GitHub returns a 422 HTTP status code
270
311
  class UnprocessableEntity < ClientError; end
271
312
 
313
+ # Raised when GitHub returns a 422 HTTP status code
314
+ # and body matches 'PullRequestReviewComment' and 'commit_id (or end_commit_oid) is not part of the pull request'
315
+ class CommitIsNotPartOfPullRequest < UnprocessableEntity; end
316
+
272
317
  # Raised when GitHub returns a 451 HTTP status code
273
318
  class UnavailableForLegalReasons < ClientError; end
274
319
 
@@ -297,4 +342,5 @@ module Octokit
297
342
  # Raised when a repository is created with an invalid format
298
343
  class InvalidRepository < ArgumentError; end
299
344
 
345
+ RATE_LIMITED_ERRORS = [Octokit::TooManyRequests, Octokit::AbuseDetected]
300
346
  end