octokit 4.14.0 → 4.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +14 -13
  3. data/README.md +20 -17
  4. data/lib/octokit/authentication.rb +2 -11
  5. data/lib/octokit/client/actions_secrets.rb +58 -0
  6. data/lib/octokit/client/actions_workflow_runs.rb +105 -0
  7. data/lib/octokit/client/actions_workflows.rb +43 -0
  8. data/lib/octokit/client/apps.rb +43 -30
  9. data/lib/octokit/client/authorizations.rb +2 -70
  10. data/lib/octokit/client/checks.rb +0 -20
  11. data/lib/octokit/client/commit_branches.rb +20 -0
  12. data/lib/octokit/client/commit_pulls.rb +20 -0
  13. data/lib/octokit/client/contents.rb +4 -0
  14. data/lib/octokit/client/deployments.rb +10 -0
  15. data/lib/octokit/client/events.rb +1 -0
  16. data/lib/octokit/client/issues.rb +7 -2
  17. data/lib/octokit/client/oauth_applications.rb +122 -0
  18. data/lib/octokit/client/organizations.rb +39 -11
  19. data/lib/octokit/client/pull_requests.rb +1 -1
  20. data/lib/octokit/client/refs.rb +19 -3
  21. data/lib/octokit/client/repositories.rb +106 -8
  22. data/lib/octokit/client/repository_invitations.rb +1 -1
  23. data/lib/octokit/client/reviews.rb +18 -0
  24. data/lib/octokit/client/search.rb +1 -1
  25. data/lib/octokit/client/users.rb +86 -0
  26. data/lib/octokit/client.rb +12 -0
  27. data/lib/octokit/connection.rb +11 -8
  28. data/lib/octokit/error.rb +54 -2
  29. data/lib/octokit/middleware/follow_redirects.rb +1 -1
  30. data/lib/octokit/preview.rb +7 -3
  31. data/lib/octokit/rate_limit.rb +1 -1
  32. data/lib/octokit/response/feed_parser.rb +0 -2
  33. data/lib/octokit/response/raise_error.rb +0 -2
  34. data/lib/octokit/version.rb +1 -1
  35. data/octokit.gemspec +1 -0
  36. metadata +22 -2
@@ -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
@@ -616,6 +640,24 @@ module Octokit
616
640
  boolean_from_response :delete, "#{Repository.path repo}/branches/#{branch}/protection", opts
617
641
  end
618
642
 
643
+ # Rename a single branch from a repository
644
+ #
645
+ # Requires authenticated client
646
+ #
647
+ # @param repo [Integer, String, Hash, Repository] A GitHub repository.
648
+ # @param branch [String] Current branch name
649
+ # @param new_name [String] New branch name
650
+ # @return [Sawyer::Resource] The renamed branch
651
+ # @see https://developer.github.com/v3/repos/#rename-a-branch
652
+ # @example
653
+ # @client.rename_branch('octokit/octokit.rb', 'master', 'main')
654
+ def rename_branch(repo, branch, new_name, options = {})
655
+ params = {
656
+ new_name: new_name,
657
+ }
658
+ post "#{Repository.path repo}/branches/#{branch}/rename", params.merge(options)
659
+ end
660
+
619
661
  # List users available for assigning to issues.
620
662
  #
621
663
  # Requires authenticated client for private repos.
@@ -696,6 +738,62 @@ module Octokit
696
738
  def delete_subscription(repo, options = {})
697
739
  boolean_from_response :delete, "#{Repository.path repo}/subscription", options
698
740
  end
741
+
742
+ # Create a repository dispatch event
743
+ #
744
+ # @param repo [Integer, String, Hash, Repository] A GitHub repository.
745
+ # @param event_type [String] A custom webhook event name.
746
+ # @option options [Hash] :client_payload payload with extra information
747
+ # about the webhook event that your action or worklow may use.
748
+ #
749
+ # @return [Boolean] True if event was dispatched, false otherwise.
750
+ # @see https://developer.github.com/v3/repos/#create-a-repository-dispatch-event
751
+ def dispatch_event(repo, event_type, options = {})
752
+ boolean_from_response :post, "#{Repository.path repo}/dispatches", options.merge({ event_type: event_type })
753
+ end
754
+
755
+ # Check to see if vulnerability alerts are enabled for a repository
756
+ #
757
+ # The authenticated user must have admin access to the repository.
758
+ #
759
+ # @param repo [Integer, String, Hash, Repository] A GitHub repository.
760
+ # @return [Boolean] True if vulnerability alerts are enabled, false otherwise.
761
+ # @see https://docs.github.com/en/rest/reference/repos#check-if-vulnerability-alerts-are-enabled-for-a-repository
762
+ #
763
+ # @example
764
+ # @client.vulnerability_alerts_enabled?("octokit/octokit.rb")
765
+ def vulnerability_alerts_enabled?(repo, options = {})
766
+ opts = ensure_api_media_type(:vulnerability_alerts, options)
767
+ boolean_from_response(:get, "#{Repository.path repo}/vulnerability-alerts", opts)
768
+ end
769
+
770
+ # Enable vulnerability alerts for a repository
771
+ #
772
+ # @param repo [Integer, String, Hash, Repository] A GitHub repository.
773
+ # @param options [Hash]
774
+ #
775
+ # @return [Boolean] True if vulnerability alerts enabled, false otherwise.
776
+ # @see https://docs.github.com/en/rest/reference/repos#enable-vulnerability-alerts
777
+ # @example Enable vulnerability alerts for a repository
778
+ # @client.enable_vulnerability_alerts("octokit/octokit.rb")
779
+ def enable_vulnerability_alerts(repo, options = {})
780
+ opts = ensure_api_media_type(:vulnerability_alerts, options)
781
+ boolean_from_response(:put, "#{Repository.path repo}/vulnerability-alerts", opts)
782
+ end
783
+
784
+ # Disable vulnerability alerts for a repository
785
+ #
786
+ # @param repo [Integer, String, Hash, Repository] A GitHub repository.
787
+ # @param options [Hash]
788
+ #
789
+ # @return [Boolean] True if vulnerability alerts disabled, false otherwise.
790
+ # @see https://docs.github.com/en/rest/reference/repos#disable-vulnerability-alerts
791
+ # @example Disable vulnerability alerts for a repository
792
+ # @client.disable_vulnerability_alerts("octokit/octokit.rb")
793
+ def disable_vulnerability_alerts(repo, options = {})
794
+ opts = ensure_api_media_type(:vulnerability_alerts, options)
795
+ boolean_from_response(:delete, "#{Repository.path repo}/vulnerability-alerts", opts)
796
+ end
699
797
  end
700
798
  end
701
799
  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
@@ -10,11 +10,16 @@ require 'octokit/repository'
10
10
  require 'octokit/user'
11
11
  require 'octokit/organization'
12
12
  require 'octokit/preview'
13
+ require 'octokit/client/actions_secrets'
14
+ require 'octokit/client/actions_workflows'
15
+ require 'octokit/client/actions_workflow_runs'
13
16
  require 'octokit/client/apps'
14
17
  require 'octokit/client/authorizations'
15
18
  require 'octokit/client/checks'
16
19
  require 'octokit/client/commits'
17
20
  require 'octokit/client/commit_comments'
21
+ require 'octokit/client/commit_pulls'
22
+ require 'octokit/client/commit_branches'
18
23
  require 'octokit/client/community_profile'
19
24
  require 'octokit/client/contents'
20
25
  require 'octokit/client/downloads'
@@ -34,6 +39,7 @@ require 'octokit/client/markdown'
34
39
  require 'octokit/client/marketplace'
35
40
  require 'octokit/client/milestones'
36
41
  require 'octokit/client/notifications'
42
+ require 'octokit/client/oauth_applications'
37
43
  require 'octokit/client/objects'
38
44
  require 'octokit/client/organizations'
39
45
  require 'octokit/client/pages'
@@ -69,10 +75,13 @@ module Octokit
69
75
  include Octokit::Connection
70
76
  include Octokit::Preview
71
77
  include Octokit::Warnable
78
+ include Octokit::Client::ActionsSecrets
72
79
  include Octokit::Client::Authorizations
73
80
  include Octokit::Client::Checks
74
81
  include Octokit::Client::Commits
75
82
  include Octokit::Client::CommitComments
83
+ include Octokit::Client::CommitPulls
84
+ include Octokit::Client::CommitBranches
76
85
  include Octokit::Client::CommunityProfile
77
86
  include Octokit::Client::Contents
78
87
  include Octokit::Client::Deployments
@@ -83,6 +92,8 @@ module Octokit
83
92
  include Octokit::Client::Gists
84
93
  include Octokit::Client::Gitignore
85
94
  include Octokit::Client::Hooks
95
+ include Octokit::Client::ActionsWorkflows
96
+ include Octokit::Client::ActionsWorkflowRuns
86
97
  include Octokit::Client::Apps
87
98
  include Octokit::Client::Issues
88
99
  include Octokit::Client::Labels
@@ -93,6 +104,7 @@ module Octokit
93
104
  include Octokit::Client::Marketplace
94
105
  include Octokit::Client::Milestones
95
106
  include Octokit::Client::Notifications
107
+ include Octokit::Client::OauthApplications
96
108
  include Octokit::Client::Objects
97
109
  include Octokit::Client::Organizations
98
110
  include Octokit::Client::Pages
@@ -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
 
data/lib/octokit/error.rb CHANGED
@@ -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,18 @@ 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
+ elsif body =~ /Path diff too large/i
110
+ Octokit::PathDiffTooLarge
111
+ else
112
+ Octokit::UnprocessableEntity
113
+ end
114
+ end
115
+
89
116
  # Array of validation errors
90
117
  # @return [Array<Hash>] Error info
91
118
  def errors
@@ -231,6 +258,10 @@ module Octokit
231
258
  # and body matches 'login attempts exceeded'
232
259
  class TooManyLoginAttempts < Forbidden; end
233
260
 
261
+ # Raised when GitHub returns a 403 HTTP status code
262
+ # and body matches 'returns blobs up to [0-9]+ MB'
263
+ class TooLargeContent < Forbidden; end
264
+
234
265
  # Raised when GitHub returns a 403 HTTP status code
235
266
  # and body matches 'abuse'
236
267
  class AbuseDetected < Forbidden; end
@@ -247,6 +278,18 @@ module Octokit
247
278
  # and body matches 'account was suspended'
248
279
  class AccountSuspended < Forbidden; end
249
280
 
281
+ # Raised when GitHub returns a 403 HTTP status code
282
+ # and body matches 'billing issue'
283
+ class BillingIssue < Forbidden; end
284
+
285
+ # Raised when GitHub returns a 403 HTTP status code
286
+ # and body matches 'Resource protected by organization SAML enforcement'
287
+ class SAMLProtected < Forbidden; end
288
+
289
+ # Raised when GitHub returns a 403 HTTP status code
290
+ # and body matches 'suspended your access'
291
+ class InstallationSuspended < Forbidden; end
292
+
250
293
  # Raised when GitHub returns a 404 HTTP status code
251
294
  class NotFound < ClientError; end
252
295
 
@@ -269,6 +312,14 @@ module Octokit
269
312
  # Raised when GitHub returns a 422 HTTP status code
270
313
  class UnprocessableEntity < ClientError; end
271
314
 
315
+ # Raised when GitHub returns a 422 HTTP status code
316
+ # and body matches 'PullRequestReviewComment' and 'commit_id (or end_commit_oid) is not part of the pull request'
317
+ class CommitIsNotPartOfPullRequest < UnprocessableEntity; end
318
+
319
+ # Raised when GitHub returns a 422 HTTP status code and body matches 'Path diff too large'.
320
+ # It could occur when attempting to post review comments on a "too large" file.
321
+ class PathDiffTooLarge < UnprocessableEntity; end
322
+
272
323
  # Raised when GitHub returns a 451 HTTP status code
273
324
  class UnavailableForLegalReasons < ClientError; end
274
325
 
@@ -297,4 +348,5 @@ module Octokit
297
348
  # Raised when a repository is created with an invalid format
298
349
  class InvalidRepository < ArgumentError; end
299
350
 
351
+ RATE_LIMITED_ERRORS = [Octokit::TooManyRequests, Octokit::AbuseDetected]
300
352
  end
@@ -11,7 +11,7 @@ module Octokit
11
11
  module Middleware
12
12
 
13
13
  # Public: Exception thrown when the maximum amount of requests is exceeded.
14
- class RedirectLimitReached < Faraday::Error::ClientError
14
+ class RedirectLimitReached < Faraday::ClientError
15
15
  attr_reader :response
16
16
 
17
17
  def initialize(response)
@@ -4,9 +4,11 @@ module Octokit
4
4
  module Preview
5
5
 
6
6
  PREVIEW_TYPES = {
7
- :branch_protection => 'application/vnd.github.loki-preview+json'.freeze,
8
- :checks => 'application/vnd.github.antiope-preview+json'.freeze,
7
+ :applications_api => 'application/vnd.github.doctor-strange-preview+json'.freeze,
8
+ :branch_protection => 'application/vnd.github.luke-cage-preview+json'.freeze,
9
9
  :commit_search => 'application/vnd.github.cloak-preview+json'.freeze,
10
+ :commit_pulls => 'application/vnd.github.groot-preview+json'.freeze,
11
+ :commit_branches => 'application/vnd.github.groot-preview+json'.freeze,
10
12
  :migrations => 'application/vnd.github.wyandotte-preview+json'.freeze,
11
13
  :licenses => 'application/vnd.github.drax-preview+json'.freeze,
12
14
  :source_imports => 'application/vnd.github.barred-rock-preview'.freeze,
@@ -17,10 +19,12 @@ module Octokit
17
19
  :pages => 'application/vnd.github.mister-fantastic-preview+json'.freeze,
18
20
  :projects => 'application/vnd.github.inertia-preview+json'.freeze,
19
21
  :traffic => 'application/vnd.github.spiderman-preview'.freeze,
20
- :integrations => 'application/vnd.github.machine-man-preview+json'.freeze,
21
22
  :topics => 'application/vnd.github.mercy-preview+json'.freeze,
22
23
  :community_profile => 'application/vnd.github.black-panther-preview+json'.freeze,
23
24
  :strict_validation => 'application/vnd.github.speedy-preview+json'.freeze,
25
+ :template_repositories => 'application/vnd.github.baptiste-preview+json'.freeze,
26
+ :project_card_events => 'application/vnd.github.starfox-preview+json'.freeze,
27
+ :vulnerability_alerts => 'application/vnd.github.dorian-preview+json'.freeze,
24
28
  }
25
29
 
26
30
  def ensure_api_media_type(type, options)
@@ -20,7 +20,7 @@ module Octokit
20
20
  # @return [RateLimit]
21
21
  def self.from_response(response)
22
22
  info = new
23
- if response && !response.headers.nil?
23
+ if response && response.respond_to?(:headers) && !response.headers.nil?
24
24
  info.limit = (response.headers['X-RateLimit-Limit'] || 1).to_i
25
25
  info.remaining = (response.headers['X-RateLimit-Remaining'] || 1).to_i
26
26
  info.resets_at = Time.at((response.headers['X-RateLimit-Reset'] || Time.now).to_i)
@@ -7,8 +7,6 @@ module Octokit
7
7
  # Parses RSS and Atom feed responses.
8
8
  class FeedParser < Faraday::Response::Middleware
9
9
 
10
- private
11
-
12
10
  def on_complete(env)
13
11
  if env[:response_headers]["content-type"] =~ /(\batom|\brss)/
14
12
  require 'rss'
@@ -9,8 +9,6 @@ module Octokit
9
9
  # HTTP status codes returned by the API
10
10
  class RaiseError < Faraday::Response::Middleware
11
11
 
12
- private
13
-
14
12
  def on_complete(response)
15
13
  if error = Octokit::Error.from_response(response)
16
14
  raise error
@@ -5,7 +5,7 @@ module Octokit
5
5
 
6
6
  # Current minor release.
7
7
  # @return [Integer]
8
- MINOR = 14
8
+ MINOR = 21
9
9
 
10
10
  # Current patch level.
11
11
  # @return [Integer]
data/octokit.gemspec CHANGED
@@ -6,6 +6,7 @@ require 'octokit/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.add_development_dependency 'bundler', '>= 1', '< 3'
8
8
  spec.add_dependency 'sawyer', '>= 0.5.3', '~> 0.8.0'
9
+ spec.add_dependency 'faraday', '>= 0.9'
9
10
  spec.authors = ["Wynn Netherland", "Erik Michaels-Ober", "Clint Shryock"]
10
11
  spec.description = %q{Simple wrapper for the GitHub API}
11
12
  spec.email = ['wynn.netherland@gmail.com', 'sferik@gmail.com', 'clint@ctshryock.com']