class GithubBot::Github::Client
Public: The Client
class manages the client interactions with GitHub such as file retrieval, pull request comments, and pull request checks
Constants
- FILE_REMOVED_STATUS
- RAW_TYPE
Public Class Methods
Public: Initialize the singleton with the incoming request information
@param request [Object] The incoming request payload
# File lib/github_bot/github/client.rb, line 21 def initialize(request) @instance = new(request) end
Public: Returns the current instance of the Client
@raise [StandardError] Raises error if instance has not been initialized before usage
# File lib/github_bot/github/client.rb, line 28 def instance raise StandardError, 'client not initialize' unless @instance @instance end
Public: Creates a new instance of the Client
to manage the GitHub api transactions
@param request [Object] The incoming request payload
# File lib/github_bot/github/client.rb, line 38 def initialize(request) @request = request end
Public Instance Methods
Public: Returns the current list of approving pull request reviewers
@return [Array<Sawyer::Resource>] The list of approving pull request reviewers
# File lib/github_bot/github/client.rb, line 117 def approving_reviewers pull_request_reviewers.select { |r| r.state == 'APPROVED' } end
Public: Added a comment to the existing pull request
@param opts [Hash] The parameter options for adding a comment @option opts [:symbol] :message The message to add to the pull request
# File lib/github_bot/github/client.rb, line 80 def comment(message:, **opts) client.add_comment(repository_full_name, pull_request_number, message, **opts) end
Public: Creates a GitHub check run for execution
@return [GithubBot::Github::CheckRun] The created check run
# File lib/github_bot/github/client.rb, line 87 def create_check_run(name:, **opts) CheckRun.new( name: name, repo: repository_full_name, sha: head_sha, client_api: client, **opts ) end
Public: Retrieve the contents of a file
@param file [Sawyer::Resource] The file for retrieving contents
# File lib/github_bot/github/client.rb, line 45 def file_content(file) raw_contents file rescue Octokit::NotFound '' rescue Octokit::Forbidden => e if e.errors.any? && e.errors.first[:code] == 'too_large' # revert to using the raw_url for getting the content return URI.parse(file.raw_url).open.read end raise e end
Public: Returns an array of all the files impacted with the current pull request
@return [Array<Sawyer::Resource>] A list of all files impacted with the current pull request
# File lib/github_bot/github/client.rb, line 70 def files return [] if pull_request.nil? @files ||= client.pull_request_files(repository_full_name, pull_request_number) end
Public: Return the modified files, excluding those that have been removed, from the pull request
@return [Array<Sawyer::Resource>] A list of modified files impacted with the current pull request
# File lib/github_bot/github/client.rb, line 61 def modified_files files.reject do |github_file| github_file.status == FILE_REMOVED_STATUS end end
Public: Returns the current list of request comments
@return [Array<Sawyer::Resource>] The list of pull request comments
# File lib/github_bot/github/client.rb, line 124 def pull_request_comments @pull_request_comments ||= client.issue_comments( repository[:full_name], pull_request[:number] ).sort_by(&:created_at) end
Public: Returns a GitHub pull request object with the details of the current request
@return [Sawyer::Resource] The pull request details associated to current request
# File lib/github_bot/github/client.rb, line 100 def pull_request_details @pull_request_details ||= client.pull_request(repository[:full_name], pull_request[:number]) end
Public: Returns the current list of pull request reviewers
@return [Array<Sawyer::Resource>] The list of current pull request reviewers
# File lib/github_bot/github/client.rb, line 107 def pull_request_reviewers @pull_request_reviewers ||= client.pull_request_reviews( repository[:full_name], pull_request[:number] ).sort_by(&:submitted_at) end
Private Instance Methods
Returns an instance of the GitHub client API to utilize
# File lib/github_bot/github/client.rb, line 152 def client @client ||= Octokit::Client.new(access_token: installation_access_token, auto_paginate: true) end
Decode the content retrieved from GitHub
@param content [Sawyer::Resource] The content returned from GitHub to decode @return [String] Returns the Base64-decoded version of the content
# File lib/github_bot/github/client.rb, line 137 def decode(content) content&.content ? Base64.decode64(content.content).force_encoding('UTF-8') : '' end
Decode the contents of the file
# File lib/github_bot/github/client.rb, line 142 def decode_contents(file) decode(client.contents(repository_full_name, path: file.filename, ref: head_sha)) end
Gets an access token associated to the request
# File lib/github_bot/github/client.rb, line 157 def installation_access_token Octokit::Client.new(bearer_token: private_key).create_installation_access_token(installation_id)[:token] end
relay messages to Octokit::Client if responds to allow extension of the client and extend/overwrite those concerned with
GithubBot::Github::Payload#method_missing
# File lib/github_bot/github/client.rb, line 188 def method_missing(method, *args, &block) return super unless respond_to_missing?(method) return payload[method] if payload.key?(method) client.send(method, *args, &block) end
Gets the private key associated to the GitHub application
# File lib/github_bot/github/client.rb, line 162 def private_key private_pem = if ENV['GITHUB_APP_PEM_PATH'] File.read(Rails.root.join(ENV['GITHUB_APP_PEM_PATH'])) elsif ENV['GITHUB_APP_PEM_V2'] ENV['GITHUB_APP_PEM_V2'].gsub('\\\n', "\n") elsif ENV['GITHUB_APP_PEM'] ENV['GITHUB_APP_PEM'].gsub('\n', "\n") else raise StandardError, "'GITHUB_APP_PEM_PATH' or 'GITHUB_APP_PEM' needs to be set" end private_key = OpenSSL::PKey::RSA.new(private_pem) current = Time.current.to_i payload = { iat: current, exp: current + (10 * 60), iss: ENV['GITHUB_APP_IDENTIFIER'] } JWT.encode(payload, private_key, 'RS256') end
Get raw contents from passed file
# File lib/github_bot/github/client.rb, line 147 def raw_contents(file) client.contents(repository_full_name, path: file.filename, ref: head_sha, headers: { 'Accept': RAW_TYPE }) end
because tasks are executed by a validator, some methods are relayed across from the task back to the validator. this override checks for that existence
# File lib/github_bot/github/client.rb, line 198 def respond_to_missing?(method, *args) payload.key?(method) || client.respond_to?(method, *args) end