Skip to content

Commit

Permalink
Merge branch '4-stable' into update-readme
Browse files Browse the repository at this point in the history
  • Loading branch information
Heather Harvey authored Apr 19, 2021
2 parents f2764d5 + f639176 commit 3b2741d
Show file tree
Hide file tree
Showing 28 changed files with 262 additions and 64 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Ruby toolkit for the GitHub API.

![logo](http://cl.ly/image/3Y013H0A2z3z/gundam-ruby.png)
![logo](https://docs.github.com/assets/images/gundamcat.png)

Upgrading? Check the [Upgrade Guide](#upgrading-guide) before bumping to a new
[major version][semver].
Expand Down Expand Up @@ -323,7 +323,7 @@ custom pattern for traversing large lists.

## Working with GitHub Enterprise

With a bit of setup, you can also use Octokit with your Github Enterprise instance.
With a bit of setup, you can also use Octokit with your GitHub Enterprise instance.

### Interacting with the GitHub.com APIs in GitHub Enterprise

Expand Down
11 changes: 11 additions & 0 deletions lib/octokit/client/actions_workflow_runs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@ def cancel_workflow_run(repo, id, options = {})
boolean_from_response :post, "#{Repository.path repo}/actions/runs/#{id}/cancel", options
end

# Deletes a workflow run
#
# @param repo [Integer, String, Repository, Hash] A GitHub repository
# @param id [Integer] Id of a workflow run
#
# @return [Boolean] Returns true if the run is deleted
# @see https://docs.github.com/en/rest/reference/actions#delete-a-workflow-run
def delete_workflow_run(repo, id, options = {})
boolean_from_response :delete, "#{Repository.path repo}/actions/runs/#{id}", options
end

# Get a download url for archived log files of a workflow run
#
# @param repo [Integer, String, Repository, Hash] A GitHub repository
Expand Down
3 changes: 1 addition & 2 deletions lib/octokit/client/apps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,7 @@ def find_installation_repositories_for_user(installation, options = {})
#
# @return [Boolean] Success
def delete_installation(installation, options = {})
opts = ensure_api_media_type(:uninstall_github_app, options)
boolean_from_response :delete, "app/installations/#{installation}", opts
boolean_from_response :delete, "app/installations/#{installation}", options
end
end
end
Expand Down
20 changes: 0 additions & 20 deletions lib/octokit/client/checks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ module Checks
# check_run.head_sha # => "7638417db6d59f3c431d3e1f261cc637155684cd"
# check_run.status # => "queued"
def create_check_run(repo, name, head_sha, options = {})
ensure_api_media_type(:checks, options)
options[:name] = name
options[:head_sha] = head_sha

Expand All @@ -41,8 +40,6 @@ def create_check_run(repo, name, head_sha, options = {})
# check_run.id # => 51295429
# check_run.status # => "in_progress"
def update_check_run(repo, id, options = {})
ensure_api_media_type(:checks, options)

patch "#{Repository.path repo}/check-runs/#{id}", options
end

Expand All @@ -63,8 +60,6 @@ def update_check_run(repo, id, options = {})
# result.check_runs[0].id # => 51295429
# result.check_runs[0].status # => "in_progress"
def check_runs_for_ref(repo, ref, options = {})
ensure_api_media_type(:checks, options)

get "#{Repository.path repo}/commits/#{ref}/check-runs", options
end
alias :list_check_runs_for_ref :check_runs_for_ref
Expand All @@ -86,8 +81,6 @@ def check_runs_for_ref(repo, ref, options = {})
# result.check_runs[0].check_suite.id # => 50440400
# result.check_runs[0].status # => "in_progress"
def check_runs_for_check_suite(repo, id, options = {})
ensure_api_media_type(:checks, options)

get "#{Repository.path repo}/check-suites/#{id}/check-runs", options
end
alias :list_check_runs_for_check_suite :check_runs_for_check_suite
Expand All @@ -99,8 +92,6 @@ def check_runs_for_check_suite(repo, id, options = {})
# @return [Sawyer::Resource] A hash representing the check run
# @see https://developer.github.com/v3/checks/runs/#get-a-single-check-run
def check_run(repo, id, options = {})
ensure_api_media_type(:checks, options)

get "#{Repository.path repo}/check-runs/#{id}", options
end

Expand All @@ -116,8 +107,6 @@ def check_run(repo, id, options = {})
# annotations[0].path # => "README.md"
# annotations[0].message # => "Looks good!"
def check_run_annotations(repo, id, options = {})
ensure_api_media_type(:checks, options)

get "#{Repository.path repo}/check-runs/#{id}/annotations", options
end

Expand All @@ -132,8 +121,6 @@ def check_run_annotations(repo, id, options = {})
# @return [Sawyer::Resource] A hash representing the check suite
# @see https://developer.github.com/v3/checks/suites/#get-a-single-check-suite
def check_suite(repo, id, options = {})
ensure_api_media_type(:checks, options)

get "#{Repository.path repo}/check-suites/#{id}", options
end

Expand All @@ -153,8 +140,6 @@ def check_suite(repo, id, options = {})
# result.check_suites[0].id # => 50440400
# result.check_suites[0].app.id # => 76765
def check_suites_for_ref(repo, ref, options = {})
ensure_api_media_type(:checks, options)

get "#{Repository.path repo}/commits/#{ref}/check-suites", options
end
alias :list_check_suites_for_ref :check_suites_for_ref
Expand All @@ -172,8 +157,6 @@ def check_suites_for_ref(repo, ref, options = {})
# result.preferences.auto_trigger_checks[0].setting # => false
# result.repository.full_name # => "octocat/Hello-World"
def set_check_suite_preferences(repo, options = {})
ensure_api_media_type(:checks, options)

patch "#{Repository.path repo}/check-suites/preferences", options
end

Expand All @@ -188,7 +171,6 @@ def set_check_suite_preferences(repo, options = {})
# check_suite.head_sha # => "7638417db6d59f3c431d3e1f261cc637155684cd"
# check_suite.status # => "queued"
def create_check_suite(repo, head_sha, options = {})
ensure_api_media_type(:checks, options)
options[:head_sha] = head_sha

post "#{Repository.path repo}/check-suites", options
Expand All @@ -201,8 +183,6 @@ def create_check_suite(repo, head_sha, options = {})
# @return [Boolean] True if successful, raises an error otherwise
# @see https://developer.github.com/v3/checks/suites/#rerequest-check-suite
def rerequest_check_suite(repo, id, options = {})
ensure_api_media_type(:checks, options)

post "#{Repository.path repo}/check-suites/#{id}/rerequest", options
true
end
Expand Down
4 changes: 4 additions & 0 deletions lib/octokit/client/contents.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ module Contents
# @see https://developer.github.com/v3/repos/contents/#get-the-readme
# @example Get the readme file for a repo
# Octokit.readme("octokit/octokit.rb")
# @example Get the readme file for a particular branch of the repo
# Octokit.readme("octokit/octokit.rb", :query => {:ref => 'some-other-branch'})
def readme(repo, options={})
get "#{Repository.path repo}/readme", options
end
Expand All @@ -29,6 +31,8 @@ def readme(repo, options={})
# @see https://developer.github.com/v3/repos/contents/#get-contents
# @example List the contents of lib/octokit.rb
# Octokit.contents("octokit/octokit.rb", :path => 'lib/octokit.rb')
# @example Lists the contents of lib /octokit.rb on a particular branch
# Octokit.contents("octokit/octokit.rb", :path => 'lib/octokit.rb', :query => {:ref => 'some-other-branch'})
def contents(repo, options={})
options = options.dup
repo_path = options.delete :path
Expand Down
14 changes: 14 additions & 0 deletions lib/octokit/client/organizations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,20 @@ def unlock_repository(org, id, repo, options = {})
options = ensure_api_media_type(:migrations, options)
delete "#{Organization.path(org)}/migrations/#{id}/repos/#{repo}/lock", options
end

# Get GitHub Actions billing for an organization
#
# Requires authenticated organization owner.
#
# @param org [String, Integer] Organization GitHub login or id.
# @return [Sawyer::Resource] Hash representing GitHub Actions billing for an organization.
# @see https://docs.github.com/en/rest/reference/billing#get-github-actions-billing-for-an-organization
#
# @example
# @client.billing_actions('github')
def billing_actions(org)
get "#{Organization.path(org)}/settings/billing/actions"
end
end
end
end
12 changes: 12 additions & 0 deletions lib/octokit/client/refs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ def refs(repo, namespace = nil, options = {})
alias :references :refs
alias :list_references :refs

# Fetch matching refs
#
# @param repo [Integer, String, Repository, Hash] A GitHub repository
# @param ref [String] The ref, e.g. <tt>tags/v0.0.3</tt> or <tt>heads/rails-3</tt>
# @return [Array<Sawyer::Resource>] The reference matching the given repo and the ref id
# @see https://developer.github.com/v3/git/refs/#list-matching-references
# @example Fetch refs matching tags/v2 for sferik/rails_admin
# Octokit.ref("sferik/rails_admin","tags/v2")
def matching_refs(repo, ref, options = {})
paginate "#{Repository.path repo}/git/matching-refs/#{ref}", options
end

# Fetch a given reference
#
# @param repo [Integer, String, Repository, Hash] A GitHub repository
Expand Down
61 changes: 61 additions & 0 deletions lib/octokit/client/repositories.rb
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,24 @@ def unprotect_branch(repo, branch, options = {})
boolean_from_response :delete, "#{Repository.path repo}/branches/#{branch}/protection", opts
end

# Rename a single branch from a repository
#
# Requires authenticated client
#
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
# @param branch [String] Current branch name
# @param new_name [String] New branch name
# @return [Sawyer::Resource] The renamed branch
# @see https://developer.github.com/v3/repos/#rename-a-branch
# @example
# @client.rename_branch('octokit/octokit.rb', 'master', 'main')
def rename_branch(repo, branch, new_name, options = {})
params = {
new_name: new_name,
}
post "#{Repository.path repo}/branches/#{branch}/rename", params.merge(options)
end

# List users available for assigning to issues.
#
# Requires authenticated client for private repos.
Expand Down Expand Up @@ -733,6 +751,49 @@ def delete_subscription(repo, options = {})
def dispatch_event(repo, event_type, options = {})
boolean_from_response :post, "#{Repository.path repo}/dispatches", options.merge({ event_type: event_type })
end

# Check to see if vulnerability alerts are enabled for a repository
#
# The authenticated user must have admin access to the repository.
#
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
# @return [Boolean] True if vulnerability alerts are enabled, false otherwise.
# @see https://docs.github.com/en/rest/reference/repos#check-if-vulnerability-alerts-are-enabled-for-a-repository
#
# @example
# @client.vulnerability_alerts_enabled?("octokit/octokit.rb")
def vulnerability_alerts_enabled?(repo, options = {})
opts = ensure_api_media_type(:vulnerability_alerts, options)
boolean_from_response(:get, "#{Repository.path repo}/vulnerability-alerts", opts)
end

# Enable vulnerability alerts for a repository
#
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
# @param options [Hash]
#
# @return [Boolean] True if vulnerability alerts enabled, false otherwise.
# @see https://docs.github.com/en/rest/reference/repos#enable-vulnerability-alerts
# @example Enable vulnerability alerts for a repository
# @client.enable_vulnerability_alerts("octokit/octokit.rb")
def enable_vulnerability_alerts(repo, options = {})
opts = ensure_api_media_type(:vulnerability_alerts, options)
boolean_from_response(:put, "#{Repository.path repo}/vulnerability-alerts", opts)
end

# Disable vulnerability alerts for a repository
#
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
# @param options [Hash]
#
# @return [Boolean] True if vulnerability alerts disabled, false otherwise.
# @see https://docs.github.com/en/rest/reference/repos#disable-vulnerability-alerts
# @example Disable vulnerability alerts for a repository
# @client.disable_vulnerability_alerts("octokit/octokit.rb")
def disable_vulnerability_alerts(repo, options = {})
opts = ensure_api_media_type(:vulnerability_alerts, options)
boolean_from_response(:delete, "#{Repository.path repo}/vulnerability-alerts", opts)
end
end
end
end
24 changes: 22 additions & 2 deletions lib/octokit/error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def self.from_response(response)
when 406 then Octokit::NotAcceptable
when 409 then Octokit::Conflict
when 415 then Octokit::UnsupportedMediaType
when 422 then Octokit::UnprocessableEntity
when 422 then error_for_422(body)
when 451 then Octokit::UnavailableForLegalReasons
when 400..499 then Octokit::ClientError
when 500 then Octokit::InternalServerError
Expand Down Expand Up @@ -84,7 +84,7 @@ def self.error_for_403(body)
Octokit::BillingIssue
elsif body =~ /Resource protected by organization SAML enforcement/i
Octokit::SAMLProtected
elsif body =~ /suspended your access/i
elsif body =~ /suspended your access|This installation has been suspended/i
Octokit::InstallationSuspended
else
Octokit::Forbidden
Expand All @@ -101,6 +101,18 @@ def self.error_for_404(body)
end
end

# Return most appropriate error for 422 HTTP status code
# @private
def self.error_for_422(body)
if body =~ /PullRequestReviewComment/i && body =~ /(commit_id|end_commit_oid) is not part of the pull request/i
Octokit::CommitIsNotPartOfPullRequest
elsif body =~ /Path diff too large/i
Octokit::PathDiffTooLarge
else
Octokit::UnprocessableEntity
end
end

# Array of validation errors
# @return [Array<Hash>] Error info
def errors
Expand Down Expand Up @@ -300,6 +312,14 @@ class UnsupportedMediaType < ClientError; end
# Raised when GitHub returns a 422 HTTP status code
class UnprocessableEntity < ClientError; end

# Raised when GitHub returns a 422 HTTP status code
# and body matches 'PullRequestReviewComment' and 'commit_id (or end_commit_oid) is not part of the pull request'
class CommitIsNotPartOfPullRequest < UnprocessableEntity; end

# Raised when GitHub returns a 422 HTTP status code and body matches 'Path diff too large'.
# It could occur when attempting to post review comments on a "too large" file.
class PathDiffTooLarge < UnprocessableEntity; end

# Raised when GitHub returns a 451 HTTP status code
class UnavailableForLegalReasons < ClientError; end

Expand Down
4 changes: 1 addition & 3 deletions lib/octokit/preview.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ module Preview
PREVIEW_TYPES = {
:applications_api => 'application/vnd.github.doctor-strange-preview+json'.freeze,
:branch_protection => 'application/vnd.github.luke-cage-preview+json'.freeze,
:checks => 'application/vnd.github.antiope-preview+json'.freeze,
:commit_search => 'application/vnd.github.cloak-preview+json'.freeze,
:commit_pulls => 'application/vnd.github.groot-preview+json'.freeze,
:commit_branches => 'application/vnd.github.groot-preview+json'.freeze,
Expand All @@ -23,10 +22,9 @@ module Preview
:topics => 'application/vnd.github.mercy-preview+json'.freeze,
:community_profile => 'application/vnd.github.black-panther-preview+json'.freeze,
:strict_validation => 'application/vnd.github.speedy-preview+json'.freeze,
:drafts => 'application/vnd.github.shadow-cat-preview'.freeze,
:template_repositories => 'application/vnd.github.baptiste-preview+json'.freeze,
:uninstall_github_app => 'application/vnd.github.gambit-preview+json'.freeze,
:project_card_events => 'application/vnd.github.starfox-preview+json'.freeze,
:vulnerability_alerts => 'application/vnd.github.dorian-preview+json'.freeze,
}

def ensure_api_media_type(type, options)
Expand Down
2 changes: 0 additions & 2 deletions lib/octokit/response/feed_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ module Response
# Parses RSS and Atom feed responses.
class FeedParser < Faraday::Response::Middleware

private

def on_complete(env)
if env[:response_headers]["content-type"] =~ /(\batom|\brss)/
require 'rss'
Expand Down
2 changes: 0 additions & 2 deletions lib/octokit/response/raise_error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ module Response
# HTTP status codes returned by the API
class RaiseError < Faraday::Response::Middleware

private

def on_complete(response)
if error = Octokit::Error.from_response(response)
raise error
Expand Down
2 changes: 1 addition & 1 deletion lib/octokit/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module Octokit

# Current minor release.
# @return [Integer]
MINOR = 19
MINOR = 20

# Current patch level.
# @return [Integer]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"http_interactions":[{"request":{"method":"get","uri":"https://api.github.com/orgs/<GITHUB_TEST_ORGANIZATION>/settings/billing/actions","body":{"encoding":"US-ASCII","base64_string":""},"headers":{"Accept":["application/vnd.github.v3+json"],"User-Agent":["Octokit Ruby Gem 4.20.0"],"Content-Type":["application/json"],"Authorization":["token <<ACCESS_TOKEN>>"],"Accept-Encoding":["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"]}},"response":{"status":{"code":200,"message":"OK"},"headers":{"Server":["GitHub.com"],"Date":["Tue, 06 Apr 2021 15:42:19 GMT"],"Content-Type":["application/json; charset=utf-8"],"Transfer-Encoding":["chunked"],"Cache-Control":["private, max-age=60, s-maxage=60"],"Vary":["Accept, Authorization, Cookie, X-GitHub-OTP","Accept-Encoding, Accept, X-Requested-With"],"Etag":["W/\"e461a8f8aea4807ed8d068bd354f27111621a3c5ea4d29d886feea9c50d8ebbf\""],"X-Oauth-Scopes":["repo"],"X-Accepted-Oauth-Scopes":["admin:org, repo"],"X-Github-Media-Type":["github.v3; format=json"],"X-Ratelimit-Limit":["5000"],"X-Ratelimit-Remaining":["4996"],"X-Ratelimit-Reset":["1617725364"],"X-Ratelimit-Used":["4"],"Access-Control-Expose-Headers":["ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, Deprecation, Sunset"],"Access-Control-Allow-Origin":["*"],"Strict-Transport-Security":["max-age=31536000; includeSubdomains; preload"],"X-Frame-Options":["deny"],"X-Content-Type-Options":["nosniff"],"X-Xss-Protection":["0"],"Referrer-Policy":["origin-when-cross-origin, strict-origin-when-cross-origin"],"Content-Security-Policy":["default-src 'none'"],"X-Github-Request-Id":["FD50:79A2:5BA998:68DBA1:606C815B"]},"body":{"encoding":"ASCII-8BIT","base64_string":"eyJ0b3RhbF9taW51dGVzX3VzZWQiOjAsInRvdGFsX3BhaWRfbWludXRlc191\nc2VkIjowLCJpbmNsdWRlZF9taW51dGVzIjoyMDAwLCJtaW51dGVzX3VzZWRf\nYnJlYWtkb3duIjp7fX0=\n"},"http_version":null},"recorded_at":"Tue, 06 Apr 2021 15:42:19 GMT"}],"recorded_with":"VCR 5.1.0"}
Loading

0 comments on commit 3b2741d

Please sign in to comment.