This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
lib/**/*.rb
|
||||
bin/*
|
||||
features/**/*.feature
|
||||
-
|
||||
LICENSE.md
|
||||
@@ -0,0 +1,23 @@
|
||||
## Submitting a Pull Request
|
||||
|
||||
0. Read our [Code of Conduct](CODE_OF_CONDUCT.md).
|
||||
1. Check out [Hacking on Octokit](README.md#hacking-on-octokitrb) in the
|
||||
README for bootstrapping the project for local development.
|
||||
2. [Fork the repository.][fork]
|
||||
3. [Create a topic branch.][branch]
|
||||
4. Add specs for your unimplemented feature or bug fix.
|
||||
5. Run `script/test`. If your specs pass, return to step 3.
|
||||
6. Implement your feature or bug fix.
|
||||
7. Run `script/test`. If your specs fail, return to step 5.
|
||||
8. Run `open coverage/index.html`. If your changes are not completely covered
|
||||
by your tests, return to step 4.
|
||||
9. Add documentation for your feature or bug fix.
|
||||
10. Run `bundle exec rake doc:yard`. If your changes are not 100% documented, go
|
||||
back to step 8.
|
||||
11. Add, commit, and push your changes. For documentation-only fixes, please
|
||||
add "[ci skip]" to your commit message to avoid needless CI builds.
|
||||
12. [Submit a pull request.][pr]
|
||||
|
||||
[fork]: https://help.github.com/articles/fork-a-repo
|
||||
[branch]: https://help.github.com/articles/creating-and-deleting-branches-within-your-repository/
|
||||
[pr]: https://help.github.com/articles/using-pull-requests
|
||||
@@ -0,0 +1,20 @@
|
||||
Copyright (c) 2009-2017 Wynn Netherland, Adam Stacoviak, Erik Michaels-Ober
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -0,0 +1,833 @@
|
||||
# Octokit
|
||||
|
||||
> **Note**
|
||||
> We've recently renamed the `4-stable` branch to `main`. This might affect you if you're making changes to Octokit's code locally. For more details and for the steps to reconfigure your local clone for the new branch name, check out [this post](https://github.com/octokit/octokit.rb/discussions/1455).
|
||||
|
||||
Ruby toolkit for the GitHub API.
|
||||
|
||||

|
||||
|
||||
Upgrading? Check the [Upgrade Guide](#upgrading-guide) before bumping to a new
|
||||
[major version][semver].
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Philosophy](#philosophy)
|
||||
2. [Installation](#installation)
|
||||
3. [Making requests](#making-requests)
|
||||
1. [Additional Query Parameters](#additional-query-parameters)
|
||||
4. [Consuming resources](#consuming-resources)
|
||||
5. [Accessing HTTP responses](#accessing-http-responses)
|
||||
6. [Handling errors](#handling-errors)
|
||||
7. [Authentication](#authentication)
|
||||
1. [Basic Authentication](#basic-authentication)
|
||||
2. [OAuth access tokens](#oauth-access-tokens)
|
||||
3. [Two-Factor Authentication](#two-factor-authentication)
|
||||
4. [Using a .netrc file](#using-a-netrc-file)
|
||||
5. [Application authentication](#application-authentication)
|
||||
6. [GitHub App](#github-app)
|
||||
8. [Default results per_page](#default-results-per_page)
|
||||
9. [Pagination](#pagination)
|
||||
1. [Auto pagination](#auto-pagination)
|
||||
10. [Working with GitHub Enterprise](#working-with-github-enterprise)
|
||||
1. [Interacting with the GitHub.com APIs in GitHub Enterprise](#interacting-with-the-githubcom-apis-in-github-enterprise)
|
||||
2. [Interacting with the GitHub Enterprise Admin APIs](#interacting-with-the-github-enterprise-admin-apis)
|
||||
3. [Interacting with the GitHub Enterprise Management Console APIs](#interacting-with-the-github-enterprise-management-console-apis)
|
||||
4. [SSL Connection Errors](#ssl-connection-errors)
|
||||
11. [Configuration and defaults](#configuration-and-defaults)
|
||||
1. [Configuring module defaults](#configuring-module-defaults)
|
||||
2. [Using ENV variables](#using-env-variables)
|
||||
3. [Timeouts](#timeouts)
|
||||
12. [Hypermedia agent](#hypermedia-agent)
|
||||
1. [Hypermedia in Octokit](#hypermedia-in-octokit)
|
||||
2. [URI templates](#uri-templates)
|
||||
3. [The Full Hypermedia Experience™](#the-full-hypermedia-experience)
|
||||
13. [Upgrading guide](#upgrading-guide)
|
||||
1. [Upgrading from 1.x.x](#upgrading-from-1xx)
|
||||
14. [Advanced usage](#advanced-usage)
|
||||
1. [Debugging](#debugging)
|
||||
2. [Caching](#caching)
|
||||
15. [Hacking on Octokit.rb](#hacking-on-octokitrb)
|
||||
1. [Code of Conduct](#code-of-conduct)
|
||||
2. [Running and writing new tests](#running-and-writing-new-tests)
|
||||
16. [Supported Ruby Versions](#supported-ruby-versions)
|
||||
17. [Versioning](#versioning)
|
||||
18. [Making Repeating Requests](#making-repeating-requests)
|
||||
19. [License](#license)
|
||||
|
||||
## Philosophy
|
||||
|
||||
API wrappers [should reflect the idioms of the language in which they were
|
||||
written][wrappers]. Octokit.rb wraps the [GitHub API][github-api] in a flat API
|
||||
client that follows Ruby conventions and requires little knowledge of REST.
|
||||
Most methods have positional arguments for required input and an options hash
|
||||
for optional parameters, headers, or other options:
|
||||
|
||||
```ruby
|
||||
client = Octokit::Client.new
|
||||
|
||||
# Fetch a README with Accept header for HTML format
|
||||
client.readme 'al3x/sovereign', :accept => 'application/vnd.github.html'
|
||||
```
|
||||
|
||||
[wrappers]: http://wynnnetherland.com/journal/what-makes-a-good-api-wrapper
|
||||
[github-api]: https://developer.github.com/v3/
|
||||
|
||||
## Installation
|
||||
|
||||
Install via Rubygems
|
||||
|
||||
gem install octokit
|
||||
|
||||
... or add to your Gemfile
|
||||
|
||||
gem "octokit", "~> 5.0"
|
||||
|
||||
Access the library in Ruby:
|
||||
|
||||
require 'octokit'
|
||||
|
||||
## Making requests
|
||||
|
||||
[API methods][] are available as client instance methods.
|
||||
|
||||
```ruby
|
||||
# Provide authentication credentials
|
||||
client = Octokit::Client.new(:access_token => 'personal_access_token')
|
||||
|
||||
# You can still use the username/password syntax by replacing the password value with your PAT.
|
||||
# client = Octokit::Client.new(:login => 'defunkt', :password => 'personal_access_token')
|
||||
|
||||
# Fetch the current user
|
||||
client.user
|
||||
```
|
||||
|
||||
### Additional query parameters
|
||||
|
||||
When passing additional parameters to GET based request use the following syntax:
|
||||
|
||||
```ruby
|
||||
# query: { parameter_name: 'value' }
|
||||
# Example: Get repository listing by owner in ascending order
|
||||
client.repos({}, query: {type: 'owner', sort: 'asc'})
|
||||
|
||||
# Example: Get contents of a repository by ref
|
||||
# https://api.github.com/repos/octokit/octokit.rb/contents/path/to/file.rb?ref=some-other-branch
|
||||
client.contents('octokit/octokit.rb', path: 'path/to/file.rb', query: {ref: 'some-other-branch'})
|
||||
```
|
||||
|
||||
[api methods]: http://octokit.github.io/octokit.rb/method_list.html
|
||||
|
||||
## Consuming resources
|
||||
|
||||
Most methods return a `Resource` object which provides dot notation and `[]`
|
||||
access for fields returned in the API response.
|
||||
|
||||
```ruby
|
||||
client = Octokit::Client.new
|
||||
|
||||
# Fetch a user
|
||||
user = client.user 'jbarnette'
|
||||
puts user.name
|
||||
# => "John Barnette"
|
||||
puts user.fields
|
||||
# => <Set: {:login, :id, :gravatar_id, :type, :name, :company, :blog, :location, :email, :hireable, :bio, :public_repos, :followers, :following, :created_at, :updated_at, :public_gists}>
|
||||
puts user[:company]
|
||||
# => "GitHub"
|
||||
user.rels[:gists].href
|
||||
# => "https://api.github.com/users/jbarnette/gists"
|
||||
```
|
||||
|
||||
**Note:** URL fields are culled into a separate `.rels` collection for easier
|
||||
[Hypermedia](#hypermedia-agent) support.
|
||||
|
||||
## Accessing HTTP responses
|
||||
|
||||
While most methods return a `Resource` object or a Boolean, sometimes you may
|
||||
need access to the raw HTTP response headers. You can access the last HTTP
|
||||
response with `Client#last_response`:
|
||||
|
||||
```ruby
|
||||
user = client.user 'andrewpthorp'
|
||||
response = client.last_response
|
||||
etag = response.headers[:etag]
|
||||
```
|
||||
|
||||
## Handling errors
|
||||
|
||||
When the API returns an error response, Octokit will raise a Ruby exception.
|
||||
|
||||
A range of different exceptions can be raised depending on the error returned
|
||||
by the API - for example:
|
||||
|
||||
* A `400 Bad Request` response will lead to an `Octokit::BadRequest` error
|
||||
* A `403 Forbidden` error with a "rate limited exceeded" message will lead
|
||||
to a `Octokit::TooManyRequests` error
|
||||
|
||||
All of the different exception classes inherit from `Octokit::Error` and
|
||||
expose the `#response_status`, `#response_headers` and `#response_body`.
|
||||
For validation errors, `#errors` will return an `Array` of `Hash`es
|
||||
with the detailed information
|
||||
[returned by the API](https://docs.github.com/en/rest/overview/resources-in-the-rest-api#client-errors).
|
||||
|
||||
## Authentication
|
||||
|
||||
Octokit supports the various [authentication methods supported by the GitHub
|
||||
API][auth]:
|
||||
|
||||
### Basic Authentication
|
||||
|
||||
Using your GitHub username and password is the easiest way to get started
|
||||
making authenticated requests:
|
||||
|
||||
```ruby
|
||||
client = Octokit::Client.new(:login => 'defunkt', :password => 'c0d3b4ssssss!')
|
||||
|
||||
user = client.user
|
||||
user.login
|
||||
# => "defunkt"
|
||||
```
|
||||
|
||||
While Basic Authentication allows you to get started quickly, OAuth access
|
||||
tokens are the preferred way to authenticate on behalf of users.
|
||||
|
||||
### OAuth access tokens
|
||||
|
||||
[OAuth access tokens][oauth] provide two main benefits over using your username
|
||||
and password:
|
||||
|
||||
- **Revocable access**. Access tokens can be revoked, removing access for only
|
||||
that token without having to change your password everywhere.
|
||||
- **Limited access**. Access tokens have [access scopes][] which allow for more
|
||||
granular access to API resources. For instance, you can grant a third party
|
||||
access to your gists but not your private repositories.
|
||||
|
||||
To use an access token with the Octokit client, pass your token in the
|
||||
`:access_token` options parameter in lieu of your username and password:
|
||||
|
||||
```ruby
|
||||
client = Octokit::Client.new(:access_token => "<your 40 char token>")
|
||||
|
||||
user = client.user
|
||||
user.login
|
||||
# => "defunkt"
|
||||
```
|
||||
|
||||
You can [create access tokens through your GitHub Account Settings](https://help.github.com/articles/creating-an-access-token-for-command-line-use)
|
||||
or with a basic authenticated Octokit client:
|
||||
|
||||
```ruby
|
||||
client = Octokit::Client.new(:login => 'defunkt', :password => 'c0d3b4ssssss!')
|
||||
|
||||
client.create_authorization(:scopes => ["user"], :note => "Name of token")
|
||||
# => <your new oauth token>
|
||||
```
|
||||
|
||||
### Two-Factor Authentication
|
||||
|
||||
[Two-Factor Authentication](https://help.github.com/articles/about-two-factor-authentication) brings added security to the account by requiring more information to login.
|
||||
|
||||
Using two-factor authentication for API calls is as simple as adding the [required header](http://developer.github.com/v3/auth/#working-with-two-factor-authentication) as an option:
|
||||
|
||||
```ruby
|
||||
client = Octokit::Client.new \
|
||||
:login => 'defunkt',
|
||||
:password => 'c0d3b4ssssss!'
|
||||
|
||||
user = client.user("defunkt", :headers => { "X-GitHub-OTP" => "<your 2FA token>" })
|
||||
```
|
||||
|
||||
As you can imagine, this gets annoying quickly since two-factor auth tokens are very short lived. So it is recommended to create an oauth token for the user to communicate with the API:
|
||||
|
||||
```ruby
|
||||
client = Octokit::Client.new \
|
||||
:login => 'defunkt',
|
||||
:password => 'c0d3b4ssssss!'
|
||||
|
||||
client.create_authorization(:scopes => ["user"], :note => "Name of token",
|
||||
:headers => { "X-GitHub-OTP" => "<your 2FA token>" })
|
||||
# => <your new oauth token>
|
||||
```
|
||||
|
||||
### Using a .netrc file
|
||||
|
||||
Octokit supports reading credentials from a netrc file (defaulting to
|
||||
`~/.netrc`). Given these lines in your netrc:
|
||||
|
||||
```
|
||||
machine api.github.com
|
||||
login defunkt
|
||||
password c0d3b4ssssss!
|
||||
```
|
||||
|
||||
You can now create a client with those credentials:
|
||||
|
||||
```ruby
|
||||
client = Octokit::Client.new(:netrc => true)
|
||||
client.login
|
||||
# => "defunkt"
|
||||
```
|
||||
|
||||
But _I want to use OAuth_ you say. Since the GitHub API supports using an OAuth
|
||||
token as a Basic password, you totally can:
|
||||
|
||||
```
|
||||
machine api.github.com
|
||||
login defunkt
|
||||
password <your 40 char token>
|
||||
```
|
||||
|
||||
**Note:** Support for netrc requires adding the [netrc gem][] to your Gemfile
|
||||
or `.gemspec`.
|
||||
|
||||
### Application authentication
|
||||
|
||||
Octokit also supports application-only authentication [using OAuth application client
|
||||
credentials][app-creds]. Using application credentials will result in making
|
||||
anonymous API calls on behalf of an application in order to take advantage of
|
||||
the higher rate limit.
|
||||
|
||||
```ruby
|
||||
client = Octokit::Client.new \
|
||||
:client_id => "<your 20 char id>",
|
||||
:client_secret => "<your 40 char secret>"
|
||||
|
||||
user = client.user 'defunkt'
|
||||
```
|
||||
|
||||
[auth]: http://developer.github.com/v3/#authentication
|
||||
[oauth]: http://developer.github.com/v3/oauth/
|
||||
[access scopes]: http://developer.github.com/v3/oauth/#scopes
|
||||
[app-creds]: http://developer.github.com/v3/#increasing-the-unauthenticated-rate-limit-for-oauth-applications
|
||||
|
||||
### GitHub App
|
||||
Octokit.rb also supports authentication [using a GitHub App](https://docs.github.com/en/developers/apps/managing-github-apps/installing-github-apps), which [requires a generated JWT token](https://docs.github.com/en/developers/apps/building-github-apps/authenticating-with-github-apps#authenticating-as-a-github-app).
|
||||
|
||||
```ruby
|
||||
client = Octokit::Client.new(:bearer_token => "<your jwt token>")
|
||||
client.app
|
||||
# => about GitHub App info
|
||||
```
|
||||
|
||||
## Default results per_page
|
||||
|
||||
Default results from the GitHub API are 30, if you wish to add more you must do so during Octokit configuration.
|
||||
|
||||
```ruby
|
||||
Octokit::Client.new(access_token: "<your 40 char token>", per_page: 100)
|
||||
```
|
||||
|
||||
## Pagination
|
||||
|
||||
Many GitHub API resources are [paginated][]. While you may be tempted to start
|
||||
adding `:page` parameters to your calls, the API returns links to the next,
|
||||
previous, and last pages for you in the `Link` response header as [Hypermedia
|
||||
link relations](#hypermedia-agent).
|
||||
|
||||
```ruby
|
||||
issues = client.issues 'rails/rails'
|
||||
issues.concat client.get(client.last_response.rels[:next].href)
|
||||
```
|
||||
|
||||
### Auto pagination
|
||||
|
||||
For smallish resource lists, Octokit provides auto pagination. When this is
|
||||
enabled, calls for paginated resources will fetch and concatenate the results
|
||||
from every page into a single array:
|
||||
|
||||
```ruby
|
||||
client.auto_paginate = true
|
||||
issues = client.issues 'rails/rails'
|
||||
issues.length
|
||||
|
||||
# => 702
|
||||
```
|
||||
|
||||
You can also enable auto pagination for all Octokit client instances:
|
||||
|
||||
```ruby
|
||||
Octokit.configure do |c|
|
||||
c.auto_paginate = true
|
||||
end
|
||||
```
|
||||
|
||||
**Note:** While Octokit auto pagination will set the page size to the maximum
|
||||
`100`, and seek to not overstep your rate limit, you probably want to use a
|
||||
custom pattern for traversing large lists.
|
||||
|
||||
[paginated]: http://developer.github.com/v3/#pagination
|
||||
|
||||
## Working with GitHub Enterprise
|
||||
|
||||
With a bit of setup, you can also use Octokit with your GitHub Enterprise instance.
|
||||
|
||||
### Interacting with the GitHub.com APIs in GitHub Enterprise
|
||||
|
||||
To interact with the "regular" GitHub.com APIs in GitHub Enterprise, simply configure the `api_endpoint` to match your hostname. For example:
|
||||
|
||||
```ruby
|
||||
Octokit.configure do |c|
|
||||
c.api_endpoint = "https://<hostname>/api/v3/"
|
||||
end
|
||||
|
||||
client = Octokit::Client.new(:access_token => "<your 40 char token>")
|
||||
```
|
||||
|
||||
### Interacting with the GitHub Enterprise Admin APIs
|
||||
|
||||
The GitHub Enterprise Admin APIs are under a different client: `EnterpriseAdminClient`. You'll need to have an administrator account in order to use these APIs.
|
||||
|
||||
```ruby
|
||||
admin_client = Octokit::EnterpriseAdminClient.new(
|
||||
:access_token => "<your 40 char token>",
|
||||
:api_endpoint => "https://<hostname>/api/v3/"
|
||||
)
|
||||
|
||||
# or
|
||||
Octokit.configure do |c|
|
||||
c.api_endpoint = "https://<hostname>/api/v3/"
|
||||
c.access_token = "<your 40 char token>"
|
||||
end
|
||||
|
||||
admin_client = Octokit.enterprise_admin_client.new
|
||||
```
|
||||
|
||||
### Interacting with the GitHub Enterprise Management Console APIs
|
||||
|
||||
The GitHub Enterprise Management Console APIs are also under a separate client: `EnterpriseManagementConsoleClient`. In order to use it, you'll need to provide both your management console password as well as the endpoint to your management console. This is different from the API endpoint provided above.
|
||||
|
||||
```ruby
|
||||
management_console_client = Octokit::EnterpriseManagementConsoleClient.new(
|
||||
:management_console_password => "secret",
|
||||
:management_console_endpoint = "https://hostname:8633"
|
||||
)
|
||||
|
||||
# or
|
||||
Octokit.configure do |c|
|
||||
c.management_console_endpoint = "https://hostname:8633"
|
||||
c.management_console_password = "secret"
|
||||
end
|
||||
|
||||
management_console_client = Octokit.enterprise_management_console_client.new
|
||||
```
|
||||
|
||||
### SSL Connection Errors
|
||||
|
||||
You _may_ need to disable SSL temporarily while first setting up your GitHub Enterprise install. You can do that with the following configuration:
|
||||
|
||||
```ruby
|
||||
client.connection_options[:ssl] = { :verify => false }
|
||||
```
|
||||
|
||||
Do remember to turn `:verify` back to `true`, as it's important for secure communication.
|
||||
|
||||
## Configuration and defaults
|
||||
|
||||
While `Octokit::Client` accepts a range of options when creating a new client
|
||||
instance, Octokit's configuration API allows you to set your configuration
|
||||
options at the module level. This is particularly handy if you're creating a
|
||||
number of client instances based on some shared defaults. Changing options
|
||||
affects new instances only and will not modify existing `Octokit::Client`
|
||||
instances created with previous options.
|
||||
|
||||
### Configuring module defaults
|
||||
|
||||
Every writable attribute in {Octokit::Configurable} can be set one at a time:
|
||||
|
||||
```ruby
|
||||
Octokit.api_endpoint = 'http://api.github.dev'
|
||||
Octokit.web_endpoint = 'http://github.dev'
|
||||
```
|
||||
|
||||
or in batch:
|
||||
|
||||
```ruby
|
||||
Octokit.configure do |c|
|
||||
c.api_endpoint = 'http://api.github.dev'
|
||||
c.web_endpoint = 'http://github.dev'
|
||||
end
|
||||
```
|
||||
|
||||
### Using ENV variables
|
||||
|
||||
Default configuration values are specified in {Octokit::Default}. Many
|
||||
attributes will look for a default value from the ENV before returning
|
||||
Octokit's default.
|
||||
|
||||
```ruby
|
||||
# Given $OCTOKIT_API_ENDPOINT is "http://api.github.dev"
|
||||
client.api_endpoint
|
||||
|
||||
# => "http://api.github.dev"
|
||||
```
|
||||
|
||||
Deprecation warnings and API endpoints in development preview warnings are
|
||||
printed to STDOUT by default, these can be disabled by setting the ENV
|
||||
`OCTOKIT_SILENT=true`.
|
||||
|
||||
### Timeouts
|
||||
|
||||
By default, Octokit does not timeout network requests. To set a timeout, pass in Faraday timeout settings to Octokit's `connection_options` setting.
|
||||
|
||||
```ruby
|
||||
Octokit.configure do |c|
|
||||
c.api_endpoint = ENV.fetch('GITHUB_API_ENDPOINT', 'https://api.github.com/')
|
||||
c.connection_options = {
|
||||
request: {
|
||||
open_timeout: 5,
|
||||
timeout: 5
|
||||
}
|
||||
}
|
||||
end
|
||||
```
|
||||
|
||||
You should set a timeout in order to avoid Ruby’s Timeout module, which can hose your server. Here are some resources for more information on this:
|
||||
|
||||
- [The Oldest Bug In Ruby - Why Rack::Timeout Might Hose your Server](https://www.schneems.com/2017/02/21/the-oldest-bug-in-ruby-why-racktimeout-might-hose-your-server/)
|
||||
- [Timeout: Ruby's Most Dangerous API](https://www.mikeperham.com/2015/05/08/timeout-rubys-most-dangerous-api/)
|
||||
- [The Ultimate Guide to Ruby Timeouts](https://github.com/ankane/the-ultimate-guide-to-ruby-timeouts)
|
||||
|
||||
## Hypermedia agent
|
||||
|
||||
Starting in version 2.0, Octokit is [hypermedia][]-enabled. Under the hood,
|
||||
{Octokit::Client} uses [Sawyer][], a hypermedia client built on [Faraday][].
|
||||
|
||||
### Hypermedia in Octokit
|
||||
|
||||
Resources returned by Octokit methods contain not only data but hypermedia
|
||||
link relations:
|
||||
|
||||
```ruby
|
||||
user = client.user 'technoweenie'
|
||||
|
||||
# Get the repos rel, returned from the API
|
||||
# as repos_url in the resource
|
||||
user.rels[:repos].href
|
||||
# => "https://api.github.com/users/technoweenie/repos"
|
||||
|
||||
repos = user.rels[:repos].get.data
|
||||
repos.last.name
|
||||
# => "faraday-zeromq"
|
||||
```
|
||||
|
||||
When processing API responses, all `*_url` attributes are culled into the link
|
||||
relations collection. Any `url` attribute becomes `.rels[:self]`.
|
||||
|
||||
### URI templates
|
||||
|
||||
You might notice many link relations have variable placeholders. Octokit
|
||||
supports [URI Templates][uri-templates] for parameterized URI expansion:
|
||||
|
||||
```ruby
|
||||
repo = client.repo 'pengwynn/pingwynn'
|
||||
rel = repo.rels[:issues]
|
||||
# => #<Sawyer::Relation: issues: get https://api.github.com/repos/pengwynn/pingwynn/issues{/number}>
|
||||
|
||||
# Get a page of issues
|
||||
rel.get.data
|
||||
|
||||
# Get issue #2
|
||||
rel.get(:uri => {:number => 2}).data
|
||||
```
|
||||
|
||||
### The Full Hypermedia Experience™
|
||||
|
||||
If you want to use Octokit as a pure hypermedia API client, you can start at
|
||||
the API root and follow link relations from there:
|
||||
|
||||
```ruby
|
||||
root = client.root
|
||||
root.rels[:repository].get :uri => {:owner => "octokit", :repo => "octokit.rb" }
|
||||
root.rels[:user_repositories].get :uri => { :user => "octokit" },
|
||||
:query => { :type => "owner" }
|
||||
```
|
||||
|
||||
Octokit 3.0 aims to be hypermedia-driven, removing the internal URL
|
||||
construction currently used throughout the client.
|
||||
|
||||
[hypermedia]: http://en.wikipedia.org/wiki/Hypermedia
|
||||
[sawyer]: https://github.com/lostisland/sawyer
|
||||
[faraday]: https://github.com/lostisland/faraday
|
||||
[uri-templates]: http://tools.ietf.org/html/rfc6570
|
||||
|
||||
## Upgrading guide
|
||||
|
||||
Version 4.0
|
||||
|
||||
- **removes support for a [long-deprecated overload][list-pulls] for
|
||||
passing state as a positional argument** when listing pull requests. Instead,
|
||||
pass `state` in the method options.
|
||||
- **drops support for Ruby < 2.0**.
|
||||
- adds support for new [Enterprise-only APIs](#working-with-github-enterprise).
|
||||
- adds support for [Repository redirects][redirects].
|
||||
|
||||
[list-pulls]: https://github.com/octokit/octokit.rb/commit/e48e91f736d5fce51e3bf74d7c9022aaa52f5c5c
|
||||
[redirects]: https://developer.github.com/changes/2015-05-26-repository-redirects-are-coming/
|
||||
|
||||
Version 3.0 includes a couple breaking changes when upgrading from v2.x.x:
|
||||
|
||||
The [default media type][default-media-type] is now `v3` instead of `beta`. If
|
||||
you need to request the older media type, you can set the default media type
|
||||
for the client:
|
||||
|
||||
```ruby
|
||||
Octokit.default_media_type = "application/vnd.github.beta+json"
|
||||
```
|
||||
|
||||
or per-request
|
||||
|
||||
```ruby
|
||||
client.emails(:accept => "application/vnd.github.beta+json")
|
||||
```
|
||||
|
||||
The long-deprecated `Octokit::Client#create_download` method has been removed.
|
||||
|
||||
[default-media-type]: https://developer.github.com/changes/2014-01-07-upcoming-change-to-default-media-type/
|
||||
|
||||
### Upgrading from 1.x.x
|
||||
|
||||
Version 2.0 includes a completely rewritten `Client` factory that now memoizes
|
||||
client instances based on unique configuration options. Breaking changes also
|
||||
include:
|
||||
|
||||
- `:oauth_token` is now `:access_token`
|
||||
- `:auto_traversal` is now `:auto_paginate`
|
||||
- `Hashie::Mash` has been removed. Responses now return a `Sawyer::Resource`
|
||||
object. This new type behaves mostly like a Ruby `Hash`, but does not fully
|
||||
support the `Hashie::Mash` API.
|
||||
- Two new client error types are raised where appropriate:
|
||||
`Octokit::TooManyRequests` and `Octokit::TooManyLoginAttempts`
|
||||
- The `search_*` methods from v1.x are now found at `legacy_search_*`
|
||||
- Support for netrc requires including the [netrc gem][] in your Gemfile or
|
||||
gemspec.
|
||||
- DateTime fields are now proper `DateTime` objects. Previous versions outputted DateTime fields as 'String' objects.
|
||||
|
||||
[netrc gem]: https://rubygems.org/gems/netrc
|
||||
|
||||
## Advanced usage
|
||||
|
||||
Since Octokit employs [Faraday][faraday] under the hood, some behavior can be
|
||||
extended via middleware.
|
||||
|
||||
### Debugging
|
||||
|
||||
Often, it helps to know what Octokit is doing under the hood. You can add a
|
||||
logger to the middleware that enables you to peek into the underlying HTTP
|
||||
traffic:
|
||||
|
||||
```ruby
|
||||
stack = Faraday::RackBuilder.new do |builder|
|
||||
builder.use Faraday::Retry::Middleware, exceptions: Faraday::Request::Retry::DEFAULT_EXCEPTIONS + [Octokit::ServerError] # or Faraday::Request::Retry for Faraday < 2.0
|
||||
builder.use Octokit::Middleware::FollowRedirects
|
||||
builder.use Octokit::Response::RaiseError
|
||||
builder.use Octokit::Response::FeedParser
|
||||
builder.response :logger do |logger|
|
||||
logger.filter(/(Authorization: "(token|Bearer) )(\w+)/, '\1[REMOVED]')
|
||||
end
|
||||
builder.adapter Faraday.default_adapter
|
||||
end
|
||||
Octokit.middleware = stack
|
||||
|
||||
client = Octokit::Client.new
|
||||
client.user 'pengwynn'
|
||||
```
|
||||
|
||||
```
|
||||
I, [2013-08-22T15:54:38.583300 #88227] INFO -- : get https://api.github.com/users/pengwynn
|
||||
D, [2013-08-22T15:54:38.583401 #88227] DEBUG -- request: Accept: "application/vnd.github.beta+json"
|
||||
User-Agent: "Octokit Ruby Gem 2.0.0.rc4"
|
||||
I, [2013-08-22T15:54:38.843313 #88227] INFO -- Status: 200
|
||||
D, [2013-08-22T15:54:38.843459 #88227] DEBUG -- response: server: "GitHub.com"
|
||||
date: "Thu, 22 Aug 2013 20:54:40 GMT"
|
||||
content-type: "application/json; charset=utf-8"
|
||||
transfer-encoding: "chunked"
|
||||
connection: "close"
|
||||
status: "200 OK"
|
||||
x-ratelimit-limit: "60"
|
||||
x-ratelimit-remaining: "39"
|
||||
x-ratelimit-reset: "1377205443"
|
||||
...
|
||||
```
|
||||
|
||||
See the [Faraday README][faraday] for more middleware magic.
|
||||
|
||||
### Caching
|
||||
|
||||
If you want to boost performance, stretch your API rate limit, or avoid paying
|
||||
the hypermedia tax, you can use [Faraday Http Cache][cache].
|
||||
|
||||
Add the gem to your Gemfile
|
||||
|
||||
gem 'faraday-http-cache'
|
||||
|
||||
Next, construct your own Faraday middleware:
|
||||
|
||||
```ruby
|
||||
stack = Faraday::RackBuilder.new do |builder|
|
||||
builder.use Faraday::HttpCache, serializer: Marshal, shared_cache: false
|
||||
builder.use Octokit::Response::RaiseError
|
||||
builder.adapter Faraday.default_adapter
|
||||
end
|
||||
Octokit.middleware = stack
|
||||
```
|
||||
|
||||
Once configured, the middleware will store responses in cache based on ETag
|
||||
fingerprint and serve those back up for future `304` responses for the same
|
||||
resource. See the [project README][cache] for advanced usage.
|
||||
|
||||
[cache]: https://github.com/sourcelevel/faraday-http-cache
|
||||
[faraday]: https://github.com/lostisland/faraday
|
||||
|
||||
## Hacking on Octokit.rb
|
||||
|
||||
If you want to hack on Octokit locally, we try to make [bootstrapping the
|
||||
project][bootstrapping] as painless as possible. To start hacking, clone and run:
|
||||
|
||||
script/bootstrap
|
||||
|
||||
This will install project dependencies and get you up and running. If you want
|
||||
to run a Ruby console to poke on Octokit, you can crank one up with:
|
||||
|
||||
script/console
|
||||
|
||||
Using the scripts in `./script` instead of `bundle exec rspec`, `bundle console`, etc. ensures your dependencies are up-to-date.
|
||||
|
||||
### Code of Conduct
|
||||
|
||||
We want both the Octokit.rb and larger Octokit communities to be open
|
||||
and welcoming environments. Please read and follow both in spirit and
|
||||
letter [Code of Conduct](CODE_OF_CONDUCT.md).
|
||||
|
||||
### Running and writing new tests
|
||||
|
||||
Octokit uses [VCR][] for recording and playing back API fixtures during test
|
||||
runs. These cassettes (fixtures) are part of the Git project in the `spec/cassettes`
|
||||
folder. If you're not recording new cassettes you can run the specs with existing
|
||||
cassettes with:
|
||||
|
||||
script/test
|
||||
|
||||
Octokit uses environmental variables for storing credentials used in testing.
|
||||
If you are testing an API endpoint that doesn't require authentication, you
|
||||
can get away without any additional configuration. For the most part, tests
|
||||
use an authenticated client, using a token stored in `ENV['OCTOKIT_TEST_GITHUB_TOKEN']`.
|
||||
There are several different authentication methods used across the api.
|
||||
Here is the full list of configurable environmental variables for testing
|
||||
Octokit:
|
||||
|
||||
| ENV Variable | Description |
|
||||
| :----------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `OCTOKIT_TEST_GITHUB_LOGIN` | GitHub login name (preferably one created specifically for testing against). |
|
||||
| `OCTOKIT_TEST_GITHUB_PASSWORD` | Password for the test GitHub login. |
|
||||
| `OCTOKIT_TEST_GITHUB_TOKEN` | [Personal Access Token](https://github.com/blog/1509-personal-api-tokens) for the test GitHub login. |
|
||||
| `OCTOKIT_TEST_GITHUB_CLIENT_ID` | Test OAuth application client id. |
|
||||
| `OCTOKIT_TEST_GITHUB_CLIENT_SECRET` | Test OAuth application client secret. |
|
||||
| `OCTOKIT_TEST_GITHUB_REPOSITORY` | Test repository to perform destructive actions against, this should not be set to any repository of importance. **Automatically created by the test suite if nonexistent** Default: `api-sandbox` |
|
||||
| `OCTOKIT_TEST_GITHUB_ORGANIZATION` | Test organization. |
|
||||
| `OCTOKIT_TEST_GITHUB_ENTERPRISE_LOGIN` | GitHub Enterprise login name. |
|
||||
| `OCTOKIT_TEST_GITHUB_ENTERPRISE_TOKEN` | GitHub Enterprise token. |
|
||||
| `OCTOKIT_TEST_GITHUB_ENTERPRISE_MANAGEMENT_CONSOLE_PASSWORD` | GitHub Enterprise management console password. |
|
||||
| `OCTOKIT_TEST_GITHUB_ENTERPRISE_ENDPOINT` | GitHub Enterprise hostname. |
|
||||
| `OCTOKIT_TEST_GITHUB_ENTERPRISE_MANAGEMENT_CONSOLE_ENDPOINT` | GitHub Enterprise Management Console endpoint. |
|
||||
| `OCTOKIT_TEST_GITHUB_INTEGRATION` | [GitHub Integration](https://developer.github.com/early-access/integrations/) owned by your test organization. |
|
||||
| `OCTOKIT_TEST_GITHUB_INTEGRATION_INSTALLATION` | Installation of the GitHub Integration specified above. |
|
||||
| `OCTOKIT_TEST_INTEGRATION_PEM_KEY` | File path to the private key generated from your integration. |
|
||||
|
||||
Since we periodically refresh our cassettes, please keep some points in mind
|
||||
when writing new specs.
|
||||
|
||||
- **Specs should be idempotent**. The HTTP calls made during a spec should be
|
||||
able to be run over and over. This means deleting a known resource prior to
|
||||
creating it if the name has to be unique.
|
||||
- **Specs should be able to be run in random order.** If a spec depends on
|
||||
another resource as a fixture, make sure that's created in the scope of the
|
||||
spec and not depend on a previous spec to create the data needed.
|
||||
- **Do not depend on authenticated user info.** Instead of asserting
|
||||
actual values in resources, try to assert the existence of a key or that a
|
||||
response is an Array. We're testing the client, not the API.
|
||||
|
||||
[bootstrapping]: http://wynnnetherland.com/linked/2013012801/bootstrapping-consistency
|
||||
[vcr]: https://github.com/vcr/vcr
|
||||
|
||||
## Supported Ruby Versions
|
||||
|
||||
This library aims to support and is [tested against][actions] the following Ruby
|
||||
implementations:
|
||||
|
||||
* Ruby 2.7
|
||||
* Ruby 3.0
|
||||
* Ruby 3.1
|
||||
* Ruby 3.2
|
||||
|
||||
If something doesn't work on one of these Ruby versions, it's a bug.
|
||||
|
||||
This library may inadvertently work (or seem to work) on other Ruby
|
||||
implementations, but support will only be provided for the versions listed
|
||||
above.
|
||||
|
||||
If you would like this library to support another Ruby version, you may
|
||||
volunteer to be a maintainer. Being a maintainer entails making sure all tests
|
||||
run and pass on that implementation. When something breaks on your
|
||||
implementation, you will be responsible for providing patches in a timely
|
||||
fashion. If critical issues for a particular implementation exist at the time
|
||||
of a major release, support for that Ruby version may be dropped.
|
||||
|
||||
[actions]: https://github.com/octokit/octokit.rb/actions
|
||||
|
||||
## Versioning
|
||||
|
||||
This library aims to adhere to [Semantic Versioning 2.0.0][semver]. Violations
|
||||
of this scheme should be reported as bugs. Specifically, if a minor or patch
|
||||
version is released that breaks backward compatibility, that version should be
|
||||
immediately yanked and/or a new version should be immediately released that
|
||||
restores compatibility. Breaking changes to the public API will only be
|
||||
introduced with new major versions. As a result of this policy, you can (and
|
||||
should) specify a dependency on this gem using the [Pessimistic Version
|
||||
Constraint][pvc] with two digits of precision. For example:
|
||||
|
||||
spec.add_dependency 'octokit', '~> 3.0'
|
||||
|
||||
The changes made between versions can be seen on the [project releases page][releases].
|
||||
|
||||
[semver]: http://semver.org/
|
||||
[pvc]: http://guides.rubygems.org/patterns/#pessimistic-version-constraint
|
||||
[releases]: https://github.com/octokit/octokit.rb/releases
|
||||
|
||||
## Making Repeating Requests
|
||||
|
||||
In most cases it would be best to use [webhooks](https://developer.github.com/webhooks/), but sometimes webhooks don't provide all of the information needed. In those cases where one might need to poll for progress or retry a request on failure, we designed [Octopoller](https://github.com/octokit/octopoller.rb). Octopoller is a micro gem perfect for making repeating requests.
|
||||
|
||||
```ruby
|
||||
Octopoller.poll(timeout: 15.seconds) do
|
||||
begin
|
||||
client.request_progress # ex. request a long running job's status
|
||||
rescue Error
|
||||
:re_poll
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
This is useful when making requests for a long running job's progress (ex. requesting a [Source Import's progress](https://developer.github.com/v3/migrations/source_imports/#get-import-progress)).
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) 2009-2014 Wynn Netherland, Adam Stacoviak, Erik Michaels-Ober
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -0,0 +1,22 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'bundler'
|
||||
Bundler::GemHelper.install_tasks
|
||||
|
||||
require 'rspec/core/rake_task'
|
||||
RSpec::Core::RakeTask.new(:spec)
|
||||
|
||||
task test: :spec
|
||||
task default: :spec
|
||||
|
||||
namespace :doc do
|
||||
require 'yard'
|
||||
YARD::Rake::YardocTask.new do |task|
|
||||
task.files = ['README.md', 'LICENSE.md', 'lib/**/*.rb']
|
||||
task.options = [
|
||||
'--output-dir', 'doc/yard',
|
||||
'--markup', 'markdown'
|
||||
]
|
||||
end
|
||||
rescue LoadError
|
||||
end
|
||||
@@ -0,0 +1,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'sawyer'
|
||||
|
||||
patch = Module.new do
|
||||
def href(options = nil)
|
||||
# Temporary workaround for: https://github.com/octokit/octokit.rb/issues/727
|
||||
name.to_s == 'ssh' ? @href : super
|
||||
end
|
||||
end
|
||||
|
||||
Sawyer::Relation.send(:prepend, patch)
|
||||
@@ -0,0 +1,66 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'octokit/default'
|
||||
require 'octokit/client'
|
||||
require 'octokit/enterprise_admin_client'
|
||||
require 'octokit/enterprise_management_console_client'
|
||||
|
||||
# Ruby toolkit for the GitHub API
|
||||
module Octokit
|
||||
class << self
|
||||
include Octokit::Configurable
|
||||
|
||||
# API client based on configured options {Configurable}
|
||||
#
|
||||
# @return [Octokit::Client] API wrapper
|
||||
def client
|
||||
return @client if defined?(@client) && @client.same_options?(options)
|
||||
|
||||
@client = Octokit::Client.new(options)
|
||||
end
|
||||
|
||||
# EnterpriseAdminClient client based on configured options {Configurable}
|
||||
#
|
||||
# @return [Octokit::EnterpriseAdminClient] API wrapper
|
||||
def enterprise_admin_client
|
||||
if defined?(@enterprise_admin_client) && @enterprise_admin_client.same_options?(options)
|
||||
return @enterprise_admin_client
|
||||
end
|
||||
|
||||
@enterprise_admin_client = Octokit::EnterpriseAdminClient.new(options)
|
||||
end
|
||||
|
||||
# EnterpriseManagementConsoleClient client based on configured options {Configurable}
|
||||
#
|
||||
# @return [Octokit::EnterpriseManagementConsoleClient] API wrapper
|
||||
def enterprise_management_console_client
|
||||
if defined?(@enterprise_management_console_client) && @enterprise_management_console_client.same_options?(options)
|
||||
return @enterprise_management_console_client
|
||||
end
|
||||
|
||||
@enterprise_management_console_client = Octokit::EnterpriseManagementConsoleClient.new(options)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def respond_to_missing?(method_name, include_private = false)
|
||||
client.respond_to?(method_name, include_private) ||
|
||||
enterprise_admin_client.respond_to?(method_name, include_private) ||
|
||||
enterprise_management_console_client.respond_to?(method_name, include_private)
|
||||
end
|
||||
|
||||
def method_missing(method_name, *args, &block)
|
||||
if client.respond_to?(method_name)
|
||||
return client.send(method_name, *args, &block)
|
||||
elsif enterprise_admin_client.respond_to?(method_name)
|
||||
return enterprise_admin_client.send(method_name, *args, &block)
|
||||
elsif enterprise_management_console_client.respond_to?(method_name)
|
||||
return enterprise_management_console_client.send(method_name, *args, &block)
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Octokit.setup
|
||||
@@ -0,0 +1,14 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
# Extracts options from method arguments
|
||||
# @private
|
||||
class Arguments < Array
|
||||
attr_reader :options
|
||||
|
||||
def initialize(args)
|
||||
@options = args.last.is_a?(::Hash) ? args.pop : {}
|
||||
super(args)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,80 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
# Authentication methods for {Octokit::Client}
|
||||
module Authentication
|
||||
# In Faraday 2.x, the authorization middleware uses new interface
|
||||
FARADAY_BASIC_AUTH_KEYS =
|
||||
if Gem::Version.new(Faraday::VERSION) >= Gem::Version.new('2.0')
|
||||
%i[authorization basic]
|
||||
else
|
||||
[:basic_auth]
|
||||
end
|
||||
|
||||
# Indicates if the client was supplied Basic Auth
|
||||
# username and password
|
||||
#
|
||||
# @see https://developer.github.com/v3/#authentication
|
||||
# @return [Boolean]
|
||||
def basic_authenticated?
|
||||
!!(@login && @password)
|
||||
end
|
||||
|
||||
# Indicates if the client was supplied an OAuth
|
||||
# access token
|
||||
#
|
||||
# @see https://developer.github.com/v3/#authentication
|
||||
# @return [Boolean]
|
||||
def token_authenticated?
|
||||
!!@access_token
|
||||
end
|
||||
|
||||
# Indicates if the client was supplied a bearer token
|
||||
#
|
||||
# @see https://developer.github.com/early-access/integrations/authentication/#as-an-integration
|
||||
# @return [Boolean]
|
||||
def bearer_authenticated?
|
||||
!!@bearer_token
|
||||
end
|
||||
|
||||
# Indicates if the client was supplied an OAuth
|
||||
# access token or Basic Auth username and password
|
||||
#
|
||||
# @see https://developer.github.com/v3/#authentication
|
||||
# @return [Boolean]
|
||||
def user_authenticated?
|
||||
basic_authenticated? || token_authenticated?
|
||||
end
|
||||
|
||||
# Indicates if the client has OAuth Application
|
||||
# client_id and secret credentials to make anonymous
|
||||
# requests at a higher rate limit
|
||||
#
|
||||
# @see https://developer.github.com/v3/#unauthenticated-rate-limited-requests
|
||||
# @return [Boolean]
|
||||
def application_authenticated?
|
||||
!!(@client_id && @client_secret)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def login_from_netrc
|
||||
return unless netrc?
|
||||
|
||||
require 'netrc'
|
||||
info = Netrc.read netrc_file
|
||||
netrc_host = URI.parse(api_endpoint).host
|
||||
creds = info[netrc_host]
|
||||
if creds.nil?
|
||||
# creds will be nil if there is no netrc for this end point
|
||||
octokit_warn "Error loading credentials from netrc file for #{api_endpoint}"
|
||||
else
|
||||
creds = creds.to_a
|
||||
self.login = creds.shift
|
||||
self.password = creds.shift
|
||||
end
|
||||
rescue LoadError
|
||||
octokit_warn 'Please install netrc gem for .netrc support'
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,272 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'octokit/connection'
|
||||
require 'octokit/warnable'
|
||||
require 'octokit/arguments'
|
||||
require 'octokit/repo_arguments'
|
||||
require 'octokit/configurable'
|
||||
require 'octokit/authentication'
|
||||
require 'octokit/gist'
|
||||
require 'octokit/rate_limit'
|
||||
require 'octokit/repository'
|
||||
require 'octokit/user'
|
||||
require 'octokit/organization'
|
||||
require 'octokit/client/actions_artifacts'
|
||||
require 'octokit/client/actions_secrets'
|
||||
require 'octokit/client/actions_workflows'
|
||||
require 'octokit/client/actions_workflow_jobs'
|
||||
require 'octokit/client/actions_workflow_runs'
|
||||
require 'octokit/client/apps'
|
||||
require 'octokit/client/checks'
|
||||
require 'octokit/client/commits'
|
||||
require 'octokit/client/commit_comments'
|
||||
require 'octokit/client/commit_pulls'
|
||||
require 'octokit/client/commit_branches'
|
||||
require 'octokit/client/community_profile'
|
||||
require 'octokit/client/contents'
|
||||
require 'octokit/client/downloads'
|
||||
require 'octokit/client/deployments'
|
||||
require 'octokit/client/environments'
|
||||
require 'octokit/client/emojis'
|
||||
require 'octokit/client/events'
|
||||
require 'octokit/client/feeds'
|
||||
require 'octokit/client/gists'
|
||||
require 'octokit/client/gitignore'
|
||||
require 'octokit/client/hooks'
|
||||
require 'octokit/client/issues'
|
||||
require 'octokit/client/labels'
|
||||
require 'octokit/client/legacy_search'
|
||||
require 'octokit/client/licenses'
|
||||
require 'octokit/client/meta'
|
||||
require 'octokit/client/markdown'
|
||||
require 'octokit/client/marketplace'
|
||||
require 'octokit/client/milestones'
|
||||
require 'octokit/client/notifications'
|
||||
require 'octokit/client/oauth_applications'
|
||||
require 'octokit/client/objects'
|
||||
require 'octokit/client/organizations'
|
||||
require 'octokit/client/pages'
|
||||
require 'octokit/client/projects'
|
||||
require 'octokit/client/pub_sub_hubbub'
|
||||
require 'octokit/client/pull_requests'
|
||||
require 'octokit/client/rate_limit'
|
||||
require 'octokit/client/reactions'
|
||||
require 'octokit/client/refs'
|
||||
require 'octokit/client/releases'
|
||||
require 'octokit/client/repositories'
|
||||
require 'octokit/client/repository_invitations'
|
||||
require 'octokit/client/reviews'
|
||||
require 'octokit/client/say'
|
||||
require 'octokit/client/search'
|
||||
require 'octokit/client/service_status'
|
||||
require 'octokit/client/source_import'
|
||||
require 'octokit/client/stats'
|
||||
require 'octokit/client/statuses'
|
||||
require 'octokit/client/tokens'
|
||||
require 'octokit/client/traffic'
|
||||
require 'octokit/client/users'
|
||||
require 'ext/sawyer/relation'
|
||||
|
||||
module Octokit
|
||||
# Client for the GitHub API
|
||||
#
|
||||
# @see https://developer.github.com
|
||||
class Client
|
||||
include Octokit::Authentication
|
||||
include Octokit::Configurable
|
||||
include Octokit::Connection
|
||||
include Octokit::Warnable
|
||||
include Octokit::Client::ActionsArtifacts
|
||||
include Octokit::Client::ActionsSecrets
|
||||
include Octokit::Client::Checks
|
||||
include Octokit::Client::Commits
|
||||
include Octokit::Client::CommitComments
|
||||
include Octokit::Client::CommitPulls
|
||||
include Octokit::Client::CommitBranches
|
||||
include Octokit::Client::CommunityProfile
|
||||
include Octokit::Client::Contents
|
||||
include Octokit::Client::Deployments
|
||||
include Octokit::Client::Downloads
|
||||
include Octokit::Client::Environments
|
||||
include Octokit::Client::Emojis
|
||||
include Octokit::Client::Events
|
||||
include Octokit::Client::Feeds
|
||||
include Octokit::Client::Gists
|
||||
include Octokit::Client::Gitignore
|
||||
include Octokit::Client::Hooks
|
||||
include Octokit::Client::ActionsWorkflows
|
||||
include Octokit::Client::ActionsWorkflowJobs
|
||||
include Octokit::Client::ActionsWorkflowRuns
|
||||
include Octokit::Client::Apps
|
||||
include Octokit::Client::Issues
|
||||
include Octokit::Client::Labels
|
||||
include Octokit::Client::LegacySearch
|
||||
include Octokit::Client::Licenses
|
||||
include Octokit::Client::Meta
|
||||
include Octokit::Client::Markdown
|
||||
include Octokit::Client::Marketplace
|
||||
include Octokit::Client::Milestones
|
||||
include Octokit::Client::Notifications
|
||||
include Octokit::Client::OauthApplications
|
||||
include Octokit::Client::Objects
|
||||
include Octokit::Client::Organizations
|
||||
include Octokit::Client::Pages
|
||||
include Octokit::Client::Projects
|
||||
include Octokit::Client::PubSubHubbub
|
||||
include Octokit::Client::PullRequests
|
||||
include Octokit::Client::RateLimit
|
||||
include Octokit::Client::Reactions
|
||||
include Octokit::Client::Refs
|
||||
include Octokit::Client::Releases
|
||||
include Octokit::Client::Repositories
|
||||
include Octokit::Client::RepositoryInvitations
|
||||
include Octokit::Client::Reviews
|
||||
include Octokit::Client::Say
|
||||
include Octokit::Client::Search
|
||||
include Octokit::Client::ServiceStatus
|
||||
include Octokit::Client::SourceImport
|
||||
include Octokit::Client::Stats
|
||||
include Octokit::Client::Statuses
|
||||
include Octokit::Client::Tokens
|
||||
include Octokit::Client::Traffic
|
||||
include Octokit::Client::Users
|
||||
|
||||
# Header keys that can be passed in options hash to {#get},{#head}
|
||||
CONVENIENCE_HEADERS = Set.new(%i[accept content_type])
|
||||
|
||||
def initialize(options = {})
|
||||
# Use options passed in, but fall back to module defaults
|
||||
#
|
||||
# rubocop:disable Style/HashEachMethods
|
||||
#
|
||||
# This may look like a `.keys.each` which should be replaced with `#each_key`, but
|
||||
# this doesn't actually work, since `#keys` is just a method we've defined ourselves.
|
||||
# The class doesn't fulfill the whole `Enumerable` contract.
|
||||
Octokit::Configurable.keys.each do |key|
|
||||
# rubocop:enable Style/HashEachMethods
|
||||
value = options[key].nil? ? Octokit.instance_variable_get(:"@#{key}") : options[key]
|
||||
instance_variable_set(:"@#{key}", value)
|
||||
end
|
||||
|
||||
login_from_netrc unless user_authenticated? || application_authenticated?
|
||||
end
|
||||
|
||||
# Text representation of the client, masking tokens and passwords
|
||||
#
|
||||
# @return [String]
|
||||
def inspect
|
||||
inspected = super
|
||||
|
||||
# mask password
|
||||
inspected.gsub! @password, '*******' if @password
|
||||
if @management_console_password
|
||||
inspected.gsub! @management_console_password, '*******'
|
||||
end
|
||||
inspected.gsub! @bearer_token, '********' if @bearer_token
|
||||
# Only show last 4 of token, secret
|
||||
if @access_token
|
||||
inspected.gsub! @access_token, "#{'*' * 36}#{@access_token[36..]}"
|
||||
end
|
||||
if @client_secret
|
||||
inspected.gsub! @client_secret, "#{'*' * 36}#{@client_secret[36..]}"
|
||||
end
|
||||
|
||||
inspected
|
||||
end
|
||||
|
||||
# Duplicate client using client_id and client_secret as
|
||||
# Basic Authentication credentials.
|
||||
# @example
|
||||
# Octokit.client_id = "foo"
|
||||
# Octokit.client_secret = "bar"
|
||||
#
|
||||
# # GET https://api.github.com/?client_id=foo&client_secret=bar
|
||||
# Octokit.get "/"
|
||||
#
|
||||
# Octokit.client.as_app do |client|
|
||||
# # GET https://foo:bar@api.github.com/
|
||||
# client.get "/"
|
||||
# end
|
||||
def as_app(key = client_id, secret = client_secret)
|
||||
if key.to_s.empty? || secret.to_s.empty?
|
||||
raise ApplicationCredentialsRequired, 'client_id and client_secret required'
|
||||
end
|
||||
|
||||
app_client = dup
|
||||
app_client.client_id = app_client.client_secret = nil
|
||||
app_client.login = key
|
||||
app_client.password = secret
|
||||
|
||||
yield app_client if block_given?
|
||||
end
|
||||
|
||||
# Set username for authentication
|
||||
#
|
||||
# @param value [String] GitHub username
|
||||
def login=(value)
|
||||
reset_agent
|
||||
@login = value
|
||||
end
|
||||
|
||||
# Set password for authentication
|
||||
#
|
||||
# @param value [String] GitHub password
|
||||
def password=(value)
|
||||
reset_agent
|
||||
@password = value
|
||||
end
|
||||
|
||||
# Set OAuth access token for authentication
|
||||
#
|
||||
# @param value [String] 40 character GitHub OAuth access token
|
||||
def access_token=(value)
|
||||
reset_agent
|
||||
@access_token = value
|
||||
end
|
||||
|
||||
# Set Bearer Token for authentication
|
||||
#
|
||||
# @param value [String] JWT
|
||||
def bearer_token=(value)
|
||||
reset_agent
|
||||
@bearer_token = value
|
||||
end
|
||||
|
||||
# Set OAuth app client_id
|
||||
#
|
||||
# @param value [String] 20 character GitHub OAuth app client_id
|
||||
def client_id=(value)
|
||||
reset_agent
|
||||
@client_id = value
|
||||
end
|
||||
|
||||
# Set OAuth app client_secret
|
||||
#
|
||||
# @param value [String] 40 character GitHub OAuth app client_secret
|
||||
def client_secret=(value)
|
||||
reset_agent
|
||||
@client_secret = value
|
||||
end
|
||||
|
||||
def client_without_redirects(options = {})
|
||||
conn_opts = @connection_options
|
||||
conn_opts[:url] = @api_endpoint
|
||||
conn_opts[:builder] = @middleware.dup if @middleware
|
||||
conn_opts[:proxy] = @proxy if @proxy
|
||||
conn_opts[:ssl] = { verify_mode: @ssl_verify_mode } if @ssl_verify_mode
|
||||
conn = Faraday.new(conn_opts) do |http|
|
||||
if basic_authenticated?
|
||||
http.request(*FARADAY_BASIC_AUTH_KEYS, @login, @password)
|
||||
elsif token_authenticated?
|
||||
http.request :authorization, 'token', @access_token
|
||||
elsif bearer_authenticated?
|
||||
http.request :authorization, 'Bearer', @bearer_token
|
||||
end
|
||||
http.headers['accept'] = options[:accept] if options.key?(:accept)
|
||||
end
|
||||
conn.builder.delete(Octokit::Middleware::FollowRedirects)
|
||||
|
||||
conn
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,71 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Actions Artifacts API
|
||||
#
|
||||
# @see https://developer.github.com/v3/actions/artifacts
|
||||
module ActionsArtifacts
|
||||
# List all artifacts for a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
#
|
||||
# @return [Sawyer::Resource] the total count and an array of artifacts
|
||||
# @see https://developer.github.com/v3/actions/artifacts#list-artifacts-for-a-repository
|
||||
def repository_artifacts(repo, options = {})
|
||||
paginate "#{Repository.path repo}/actions/artifacts", options do |data, last_response|
|
||||
data.artifacts.concat last_response.data.artifacts
|
||||
end
|
||||
end
|
||||
|
||||
# List all artifacts for a workflow run
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param workflow_run_id [Integer] Id of a workflow run
|
||||
#
|
||||
# @return [Sawyer::Resource] the total count and an array of artifacts
|
||||
# @see https://docs.github.com/en/rest/actions/artifacts#list-workflow-run-artifacts
|
||||
def workflow_run_artifacts(repo, workflow_run_id, options = {})
|
||||
paginate "#{Repository.path repo}/actions/runs/#{workflow_run_id}/artifacts", options do |data, last_response|
|
||||
data.artifacts.concat last_response.data.artifacts
|
||||
end
|
||||
end
|
||||
|
||||
# Get an artifact
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param id [Integer] Id of an artifact
|
||||
#
|
||||
# @return [Sawyer::Resource] Artifact information
|
||||
# @see https://docs.github.com/en/rest/actions/artifacts#get-an-artifact
|
||||
def artifact(repo, id, options = {})
|
||||
get "#{Repository.path repo}/actions/artifacts/#{id}", options
|
||||
end
|
||||
|
||||
# Get a download URL for an artifact
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param id [Integer] Id of an artifact
|
||||
#
|
||||
# @return [String] URL to the .zip archive of the artifact
|
||||
# @see https://docs.github.com/en/rest/actions/artifacts#download-an-artifact
|
||||
def artifact_download_url(repo, id, options = {})
|
||||
url = "#{Repository.path repo}/actions/artifacts/#{id}/zip"
|
||||
|
||||
response = client_without_redirects.head(url, options)
|
||||
response.headers['Location']
|
||||
end
|
||||
|
||||
# Delete an artifact
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param id [Integer] Id of an artifact
|
||||
#
|
||||
# @return [Boolean] Return true if the artifact was successfully deleted
|
||||
# @see https://docs.github.com/en/rest/actions/artifacts#delete-an-artifact
|
||||
def delete_artifact(repo, id, options = {})
|
||||
boolean_from_response :delete, "#{Repository.path repo}/actions/artifacts/#{id}", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,59 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Actions Secrets API
|
||||
#
|
||||
# @see https://developer.github.com/v3/actions/secrets/
|
||||
module ActionsSecrets
|
||||
# Get public key for secrets encryption
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @return [Hash] key_id and key
|
||||
# @see https://developer.github.com/v3/actions/secrets/#get-your-public-key
|
||||
def get_public_key(repo)
|
||||
get "#{Repository.path repo}/actions/secrets/public-key"
|
||||
end
|
||||
|
||||
# List secrets
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @return [Hash] total_count and list of secrets (each item is hash with name, created_at and updated_at)
|
||||
# @see https://developer.github.com/v3/actions/secrets/#list-secrets-for-a-repository
|
||||
def list_secrets(repo)
|
||||
paginate "#{Repository.path repo}/actions/secrets" do |data, last_response|
|
||||
data.secrets.concat last_response.data.secrets
|
||||
end
|
||||
end
|
||||
|
||||
# Get a secret
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param name [String] Name of secret
|
||||
# @return [Hash] name, created_at and updated_at
|
||||
# @see https://developer.github.com/v3/actions/secrets/#get-a-secret
|
||||
def get_secret(repo, name)
|
||||
get "#{Repository.path repo}/actions/secrets/#{name}"
|
||||
end
|
||||
|
||||
# Create or update secrets
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param name [String] Name of secret
|
||||
# @param options [Hash] encrypted_value and key_id
|
||||
# @see https://developer.github.com/v3/actions/secrets/#create-or-update-a-secret-for-a-repository
|
||||
def create_or_update_secret(repo, name, options)
|
||||
put "#{Repository.path repo}/actions/secrets/#{name}", options
|
||||
end
|
||||
|
||||
# Delete a secret
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param name [String] Name of secret
|
||||
# @see https://developer.github.com/v3/actions/secrets/#delete-a-secret-from-a-repository
|
||||
def delete_secret(repo, name)
|
||||
boolean_from_response :delete, "#{Repository.path repo}/actions/secrets/#{name}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,65 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Actions Workflows jobs API
|
||||
#
|
||||
# @see https://docs.github.com/rest/actions/workflow-jobs
|
||||
module ActionsWorkflowJobs
|
||||
# Get a job for a workflow run
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param job_id [Integer, String] Id of the job
|
||||
#
|
||||
# @return [Sawyer::Resource] Job information
|
||||
# @see https://docs.github.com/rest/actions/workflow-jobs#get-a-job-for-a-workflow-run
|
||||
def workflow_run_job(repo, job_id, options = {})
|
||||
get "#{Repository.path repo}/actions/jobs/#{job_id}", options
|
||||
end
|
||||
|
||||
# Download job logs for a workflow run
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param job_id [Integer, String] Id of the job
|
||||
#
|
||||
# @return [String] URL to the archived log files of the job
|
||||
# @see https://docs.github.com/rest/actions/workflow-jobs#download-job-logs-for-a-workflow-run
|
||||
def workflow_run_job_logs(repo, job_id, options = {})
|
||||
url = "#{Repository.path repo}/actions/jobs/#{job_id}/logs"
|
||||
|
||||
response = client_without_redirects.head(url, options)
|
||||
response.headers['Location']
|
||||
end
|
||||
|
||||
# List jobs for a workflow run attempt
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param run_id [Integer, String] Id of the workflow run
|
||||
# @param attempt_number [Integer, String] Attempt number of the workflow run
|
||||
#
|
||||
# @return [Sawyer::Resource] Jobs information
|
||||
# @see https://docs.github.com/rest/actions/workflow-jobs#list-jobs-for-a-workflow-run-attempt
|
||||
def workflow_run_attempt_jobs(repo, run_id, attempt_number, options = {})
|
||||
paginate "#{Repository.path repo}/actions/runs/#{run_id}/attempts/#{attempt_number}/jobs", options do |data, last_response|
|
||||
data.jobs.concat last_response.data.jobs
|
||||
end
|
||||
end
|
||||
alias list_workflow_run_attempt_jobs workflow_run_attempt_jobs
|
||||
|
||||
# List jobs for a workflow run
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param run_id [Integer, String] Id of the workflow run
|
||||
# @option options [String] :filter Optional filtering by a `completed_at` timestamp
|
||||
#
|
||||
# @return [Sawyer::Resource] Jobs information
|
||||
# @see https://docs.github.com/rest/actions/workflow-jobs#list-jobs-for-a-workflow-run
|
||||
def workflow_run_jobs(repo, run_id, options = {})
|
||||
paginate "#{Repository.path repo}/actions/runs/#{run_id}/jobs", options do |data, last_response|
|
||||
data.jobs.concat last_response.data.jobs
|
||||
end
|
||||
end
|
||||
alias list_workflow_run_jobs workflow_run_jobs
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,125 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Actions Workflows runs API
|
||||
#
|
||||
# @see https://docs.github.com/rest/actions/workflow-runs
|
||||
module ActionsWorkflowRuns
|
||||
# List all runs for a repository workflow
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param workflow [Integer, String] Id or file name of the workflow
|
||||
# @option options [String] :actor Optional filtering by a user
|
||||
# @option options [String] :branch Optional filtering by a branch
|
||||
# @option options [String] :event Optional filtering by the event type
|
||||
# @option options [String] :status Optional filtering by a status or conclusion
|
||||
#
|
||||
# @return [Sawyer::Resource] the total count and an array of workflows
|
||||
# @see https://developer.github.com/v3/actions/workflow-runs/#list-workflow-runs
|
||||
def workflow_runs(repo, workflow, options = {})
|
||||
paginate "#{Repository.path repo}/actions/workflows/#{workflow}/runs", options do |data, last_response|
|
||||
data.workflow_runs.concat last_response.data.workflow_runs
|
||||
end
|
||||
end
|
||||
alias list_workflow_runs workflow_runs
|
||||
|
||||
# List all workflow runs for a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @option options [String] :actor Optional filtering by the login of a user
|
||||
# @option options [String] :branch Optional filtering by a branch
|
||||
# @option options [String] :event Optional filtering by the event type (e.g. push, pull_request, issue)
|
||||
# @option options [String] :status Optional filtering by a status or conclusion (e.g. success, completed...)
|
||||
#
|
||||
# @return [Sawyer::Resource] the total count and an array of workflows
|
||||
# @see https://developer.github.com/v3/actions/workflow-runs/#list-repository-workflow-runs
|
||||
def repository_workflow_runs(repo, options = {})
|
||||
paginate "#{Repository.path repo}/actions/runs", options do |data, last_response|
|
||||
data.workflow_runs.concat last_response.data.workflow_runs
|
||||
end
|
||||
end
|
||||
alias list_repository_workflow_runs repository_workflow_runs
|
||||
|
||||
# Get a workflow run
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param id [Integer] Id of a workflow run
|
||||
#
|
||||
# @return [Sawyer::Resource] Run information
|
||||
# @see https://developer.github.com/v3/actions/workflow-runs/#get-a-workflow-run
|
||||
def workflow_run(repo, id, options = {})
|
||||
get "#{Repository.path repo}/actions/runs/#{id}", options
|
||||
end
|
||||
|
||||
# Re-runs 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 re-run request was accepted
|
||||
# @see https://developer.github.com/v3/actions/workflow-runs/#re-run-a-workflow
|
||||
def rerun_workflow_run(repo, id, options = {})
|
||||
boolean_from_response :post, "#{Repository.path repo}/actions/runs/#{id}/rerun", options
|
||||
end
|
||||
|
||||
# Cancels 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 cancellation was accepted
|
||||
# @see https://developer.github.com/v3/actions/workflow-runs/#cancel-a-workflow-run
|
||||
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
|
||||
# @param id [Integer] Id of a workflow run
|
||||
#
|
||||
# @return [String] URL to the archived log files of the run
|
||||
# @see https://developer.github.com/v3/actions/workflow-runs/#download-workflow-run-logs
|
||||
def workflow_run_logs(repo, id, options = {})
|
||||
url = "#{Repository.path repo}/actions/runs/#{id}/logs"
|
||||
|
||||
response = client_without_redirects.head(url, options)
|
||||
response.headers['Location']
|
||||
end
|
||||
|
||||
# Delete all log files of 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 logs are deleted
|
||||
# @see https://developer.github.com/v3/actions/workflow-runs/#delete-workflow-run-logs
|
||||
def delete_workflow_run_logs(repo, id, options = {})
|
||||
boolean_from_response :delete, "#{Repository.path repo}/actions/runs/#{id}/logs", options
|
||||
end
|
||||
|
||||
# Get workflow run usage
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param id [Integer] Id of a workflow run
|
||||
#
|
||||
# @return [Sawyer::Resource] Run usage
|
||||
# @see https://developer.github.com/v3/actions/workflow-runs/#get-workflow-run-usage
|
||||
def workflow_run_usage(repo, id, options = {})
|
||||
get "#{Repository.path repo}/actions/runs/#{id}/timing", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,68 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Actions Workflows API
|
||||
#
|
||||
# @see https://developer.github.com/v3/actions/workflows
|
||||
module ActionsWorkflows
|
||||
# Get the workflows in a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
#
|
||||
# @return [Sawyer::Resource] the total count and an array of workflows
|
||||
# @see https://developer.github.com/v3/actions/workflows/#list-repository-workflows
|
||||
def workflows(repo, options = {})
|
||||
paginate "#{Repository.path repo}/actions/workflows", options do |data, last_response|
|
||||
data.workflows.concat last_response.data.workflows
|
||||
end
|
||||
end
|
||||
alias list_workflows workflows
|
||||
|
||||
# Get single workflow in a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param id [Integer, String] Id or file name of the workflow
|
||||
#
|
||||
# @return [Sawyer::Resource] A single workflow
|
||||
# @see https://developer.github.com/v3/actions/workflows/#get-a-workflow
|
||||
def workflow(repo, id, options = {})
|
||||
get "#{Repository.path repo}/actions/workflows/#{id}", options
|
||||
end
|
||||
|
||||
# Create a workflow dispatch event
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param id [Integer, String] Id or file name of the workflow
|
||||
# @param ref [String] A SHA, branch name, or tag name
|
||||
#
|
||||
# @return [Boolean] True if event was dispatched, false otherwise
|
||||
# @see https://docs.github.com/en/rest/reference/actions#create-a-workflow-dispatch-event
|
||||
def workflow_dispatch(repo, id, ref, options = {})
|
||||
boolean_from_response :post, "#{Repository.path repo}/actions/workflows/#{id}/dispatches", options.merge({ ref: ref })
|
||||
end
|
||||
|
||||
# Enable a workflow
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param id [Integer, String] Id or file name of the workflow
|
||||
#
|
||||
# @return [Boolean] True if workflow was enabled, false otherwise
|
||||
# @see https://docs.github.com/en/rest/actions/workflows#enable-a-workflow
|
||||
def workflow_enable(repo, id, options = {})
|
||||
boolean_from_response :put, "#{Repository.path repo}/actions/workflows/#{id}/enable", options
|
||||
end
|
||||
|
||||
# Disable a workflow
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param id [Integer, String] Id or file name of the workflow
|
||||
#
|
||||
# @return [Boolean] True if workflow was disabled, false otherwise
|
||||
# @see https://docs.github.com/en/rest/actions/workflows#disable-a-workflow
|
||||
def workflow_disable(repo, id, options = {})
|
||||
boolean_from_response :put, "#{Repository.path repo}/actions/workflows/#{id}/disable", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,222 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Apps API
|
||||
module Apps
|
||||
# Get the authenticated App
|
||||
#
|
||||
# @param options [Hash] A customizable set of options
|
||||
#
|
||||
# @see https://developer.github.com/v3/apps/#get-the-authenticated-app
|
||||
#
|
||||
# @return [Sawyer::Resource] App information
|
||||
def app(options = {})
|
||||
get 'app', options
|
||||
end
|
||||
|
||||
# Find all installations that belong to an App
|
||||
#
|
||||
# @param options [Hash] A customizable set of options
|
||||
#
|
||||
# @see https://developer.github.com/v3/apps/#list-installations
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] the total_count and an array of installations
|
||||
def find_app_installations(options = {})
|
||||
paginate 'app/installations', options
|
||||
end
|
||||
alias find_installations find_app_installations
|
||||
|
||||
def find_integration_installations(options = {})
|
||||
octokit_warn(
|
||||
'Deprecated: Octokit::Client::Apps#find_integration_installations ' \
|
||||
'method is deprecated. Please update your call to use ' \
|
||||
'Octokit::Client::Apps#find_app_installations before the next major ' \
|
||||
'Octokit version update.'
|
||||
)
|
||||
find_app_installations(options)
|
||||
end
|
||||
|
||||
# Find all installations that are accessible to the authenticated user
|
||||
#
|
||||
# @param options [Hash] A customizable set of options
|
||||
#
|
||||
# @see https://developer.github.com/v3/apps/installations/#list-installations-for-a-user
|
||||
#
|
||||
# @return [Sawyer::Resource] the total_count and an array of installations
|
||||
def find_user_installations(options = {})
|
||||
paginate('user/installations', options) do |data, last_response|
|
||||
data.installations.concat last_response.data.installations
|
||||
end
|
||||
end
|
||||
|
||||
# Get a single installation
|
||||
#
|
||||
# @param id [Integer] Installation id
|
||||
#
|
||||
# @see https://developer.github.com/v3/apps/#get-an-installation
|
||||
#
|
||||
# @return [Sawyer::Resource] Installation information
|
||||
def installation(id, options = {})
|
||||
get "app/installations/#{id}", options
|
||||
end
|
||||
|
||||
# Create a new installation token
|
||||
#
|
||||
# @param installation [Integer] The id of a GitHub App Installation
|
||||
# @param options [Hash] A customizable set of options
|
||||
#
|
||||
# @see https://developer.github.com/v3/apps/#create-a-new-installation-token
|
||||
#
|
||||
# @return [<Sawyer::Resource>] An installation token
|
||||
def create_app_installation_access_token(installation, options = {})
|
||||
post "app/installations/#{installation}/access_tokens", options
|
||||
end
|
||||
alias create_installation_access_token create_app_installation_access_token
|
||||
|
||||
def create_integration_installation_access_token(installation, options = {})
|
||||
octokit_warn(
|
||||
'Deprecated: Octokit::Client::Apps#create_integration_installation_access_token ' \
|
||||
'method is deprecated. Please update your call to use ' \
|
||||
'Octokit::Client::Apps#create_app_installation_access_token before the next major ' \
|
||||
'Octokit version update.'
|
||||
)
|
||||
create_app_installation_access_token(installation, options)
|
||||
end
|
||||
|
||||
# Enables an app to find the organization's installation information.
|
||||
#
|
||||
# @param organization [String] Organization GitHub login
|
||||
# @param options [Hash] A customizable set of options
|
||||
#
|
||||
# @see https://developer.github.com/v3/apps/#get-an-organization-installation
|
||||
#
|
||||
# @return [Sawyer::Resource] Installation information
|
||||
def find_organization_installation(organization, options = {})
|
||||
get "#{Organization.path(organization)}/installation", options
|
||||
end
|
||||
|
||||
# Enables an app to find the repository's installation information.
|
||||
#
|
||||
# @param repo [String] A GitHub repository
|
||||
# @param options [Hash] A customizable set of options
|
||||
#
|
||||
# @see https://developer.github.com/v3/apps/#get-a-repository-installation
|
||||
#
|
||||
# @return [Sawyer::Resource] Installation information
|
||||
def find_repository_installation(repo, options = {})
|
||||
get "#{Repository.path(repo)}/installation", options
|
||||
end
|
||||
|
||||
# Enables an app to find the user's installation information.
|
||||
#
|
||||
# @param user [String] GitHub user login
|
||||
# @param options [Hash] A customizable set of options
|
||||
#
|
||||
# @see https://developer.github.com/v3/apps/#get-a-user-installation
|
||||
#
|
||||
# @return [Sawyer::Resource] Installation information
|
||||
def find_user_installation(user, options = {})
|
||||
get "#{User.path(user)}/installation", options
|
||||
end
|
||||
|
||||
# List repositories that are accessible to the authenticated installation
|
||||
#
|
||||
# @param options [Hash] A customizable set of options
|
||||
#
|
||||
# @see https://developer.github.com/v3/apps/installations/#list-repositories
|
||||
#
|
||||
# @return [Sawyer::Resource] the total_count and an array of repositories
|
||||
def list_app_installation_repositories(options = {})
|
||||
paginate('installation/repositories', options) do |data, last_response|
|
||||
data.repositories.concat last_response.data.repositories
|
||||
end
|
||||
end
|
||||
alias list_installation_repos list_app_installation_repositories
|
||||
|
||||
def list_integration_installation_repositories(options = {})
|
||||
octokit_warn(
|
||||
'Deprecated: Octokit::Client::Apps#list_integration_installation_repositories ' \
|
||||
'method is deprecated. Please update your call to use ' \
|
||||
'Octokit::Client::Apps#list_app_installation_repositories before the next major ' \
|
||||
'Octokit version update.'
|
||||
)
|
||||
list_app_installation_repositories(options)
|
||||
end
|
||||
|
||||
# Add a single repository to an installation
|
||||
#
|
||||
# @param installation [Integer] The id of a GitHub App Installation
|
||||
# @param repo [Integer] The id of the GitHub repository
|
||||
# @param options [Hash] A customizable set of options
|
||||
#
|
||||
# @see https://developer.github.com/v3/apps/installations/#add-repository-to-installation
|
||||
#
|
||||
# @return [Boolean] Success
|
||||
def add_repository_to_app_installation(installation, repo, options = {})
|
||||
boolean_from_response :put, "user/installations/#{installation}/repositories/#{repo}", options
|
||||
end
|
||||
alias add_repo_to_installation add_repository_to_app_installation
|
||||
|
||||
def add_repository_to_integration_installation(installation, repo, options = {})
|
||||
octokit_warn(
|
||||
'Deprecated: Octokit::Client::Apps#add_repository_to_integration_installation ' \
|
||||
'method is deprecated. Please update your call to use ' \
|
||||
'Octokit::Client::Apps#add_repository_to_app_installation before the next major ' \
|
||||
'Octokit version update.'
|
||||
)
|
||||
add_repository_to_app_installation(installation, repo, options)
|
||||
end
|
||||
|
||||
# Remove a single repository to an installation
|
||||
#
|
||||
# @param installation [Integer] The id of a GitHub App Installation
|
||||
# @param repo [Integer] The id of the GitHub repository
|
||||
# @param options [Hash] A customizable set of options
|
||||
#
|
||||
# @see https://developer.github.com/v3/apps/installations/#remove-repository-from-installation
|
||||
#
|
||||
# @return [Boolean] Success
|
||||
def remove_repository_from_app_installation(installation, repo, options = {})
|
||||
boolean_from_response :delete, "user/installations/#{installation}/repositories/#{repo}", options
|
||||
end
|
||||
alias remove_repo_from_installation remove_repository_from_app_installation
|
||||
|
||||
def remove_repository_from_integration_installation(installation, repo, options = {})
|
||||
octokit_warn(
|
||||
'Deprecated: Octokit::Client::Apps#remove_repository_from_integration_installation ' \
|
||||
'method is deprecated. Please update your call to use ' \
|
||||
'Octokit::Client::Apps#remove_repository_from_app_installation before the next major ' \
|
||||
'Octokit version update.'
|
||||
)
|
||||
remove_repository_from_app_installation(installation, repo, options)
|
||||
end
|
||||
|
||||
# List repositories accessible to the user for an installation
|
||||
#
|
||||
# @param installation [Integer] The id of a GitHub App Installation
|
||||
# @param options [Hash] A customizable set of options
|
||||
#
|
||||
# @see https://developer.github.com/v3/apps/installations/#list-repositories-accessible-to-the-user-for-an-installation
|
||||
#
|
||||
# @return [Sawyer::Resource] the total_count and an array of repositories
|
||||
def find_installation_repositories_for_user(installation, options = {})
|
||||
paginate("user/installations/#{installation}/repositories", options) do |data, last_response|
|
||||
data.repositories.concat last_response.data.repositories
|
||||
end
|
||||
end
|
||||
|
||||
# Delete an installation and uninstall a GitHub App
|
||||
#
|
||||
# @param installation [Integer] The id of a GitHub App Installation
|
||||
# @param options [Hash] A customizable set of options
|
||||
#
|
||||
# @see https://developer.github.com/v3/apps/#delete-an-installation
|
||||
#
|
||||
# @return [Boolean] Success
|
||||
def delete_installation(installation, options = {})
|
||||
boolean_from_response :delete, "app/installations/#{installation}", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,200 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Checks API
|
||||
#
|
||||
# @see https://developer.github.com/v3/checks/
|
||||
module Checks
|
||||
# Methods for Check Runs
|
||||
#
|
||||
# @see https://developer.github.com/v3/checks/runs/
|
||||
|
||||
# Create a check run
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param name [String] The name of the check
|
||||
# @param head_sha [String] The SHA of the commit to check
|
||||
# @return [Sawyer::Resource] A hash representing the new check run
|
||||
# @see https://developer.github.com/v3/checks/runs/#create-a-check-run
|
||||
# @example Create a check run
|
||||
# check_run = @client.create_check_run("octocat/Hello-World", "my-check", "7638417db6d59f3c431d3e1f261cc637155684cd")
|
||||
# check_run.name # => "my-check"
|
||||
# check_run.head_sha # => "7638417db6d59f3c431d3e1f261cc637155684cd"
|
||||
# check_run.status # => "queued"
|
||||
def create_check_run(repo, name, head_sha, options = {})
|
||||
options[:name] = name
|
||||
options[:head_sha] = head_sha
|
||||
|
||||
post "#{Repository.path repo}/check-runs", options
|
||||
end
|
||||
|
||||
# Update a check run
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param id [Integer] The ID of the check run
|
||||
# @return [Sawyer::Resource] A hash representing the updated check run
|
||||
# @see https://developer.github.com/v3/checks/runs/#update-a-check-run
|
||||
# @example Update a check run
|
||||
# check_run = @client.update_check_run("octocat/Hello-World", 51295429, status: "in_progress")
|
||||
# check_run.id # => 51295429
|
||||
# check_run.status # => "in_progress"
|
||||
def update_check_run(repo, id, options = {})
|
||||
patch "#{Repository.path repo}/check-runs/#{id}", options
|
||||
end
|
||||
|
||||
# List check runs for a specific ref
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param ref [String] A SHA, branch name, or tag name
|
||||
# @param options [Hash] A set of optional filters
|
||||
# @option options [String] :check_name Returns check runs with the specified <tt>name</tt>
|
||||
# @option options [String] :status Returns check runs with the specified <tt>status</tt>
|
||||
# @option options [String] :filter Filters check runs by their <tt>completed_at</tt> timestamp
|
||||
# @return [Sawyer::Resource] A hash representing a collection of check runs
|
||||
# @see https://developer.github.com/v3/checks/runs/#list-check-runs-for-a-specific-ref
|
||||
# @example List check runs for a specific ref
|
||||
# result = @client.check_runs_for_ref("octocat/Hello-World", "7638417db6d59f3c431d3e1f261cc637155684cd", status: "in_progress")
|
||||
# result.total_count # => 1
|
||||
# result.check_runs.count # => 1
|
||||
# result.check_runs[0].id # => 51295429
|
||||
# result.check_runs[0].status # => "in_progress"
|
||||
def check_runs_for_ref(repo, ref, options = {})
|
||||
paginate "#{Repository.path repo}/commits/#{ref}/check-runs", options do |data, last_response|
|
||||
data.check_runs.concat last_response.data.check_runs
|
||||
data.total_count += last_response.data.total_count
|
||||
end
|
||||
end
|
||||
alias list_check_runs_for_ref check_runs_for_ref
|
||||
|
||||
# List check runs in a check suite
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param id [Integer] The ID of the check suite
|
||||
# @param options [Hash] A set of optional filters
|
||||
# @option options [String] :check_name Returns check runs with the specified <tt>name</tt>
|
||||
# @option options [String] :status Returns check runs with the specified <tt>status</tt>
|
||||
# @option options [String] :filter Filters check runs by their <tt>completed_at</tt> timestamp
|
||||
# @return [Sawyer::Resource] A hash representing a collection of check runs
|
||||
# @see https://developer.github.com/v3/checks/runs/#list-check-runs-in-a-check-suite
|
||||
# @example List check runs in a check suite
|
||||
# result = @client.check_runs_for_check_suite("octocat/Hello-World", 50440400, status: "in_progress")
|
||||
# result.total_count # => 1
|
||||
# result.check_runs.count # => 1
|
||||
# result.check_runs[0].check_suite.id # => 50440400
|
||||
# result.check_runs[0].status # => "in_progress"
|
||||
def check_runs_for_check_suite(repo, id, options = {})
|
||||
paginate "#{Repository.path repo}/check-suites/#{id}/check-runs", options do |data, last_response|
|
||||
data.check_runs.concat last_response.data.check_runs
|
||||
data.total_count += last_response.data.total_count
|
||||
end
|
||||
end
|
||||
alias list_check_runs_for_check_suite check_runs_for_check_suite
|
||||
|
||||
# Get a single check run
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param id [Integer] The ID of the check run
|
||||
# @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 = {})
|
||||
get "#{Repository.path repo}/check-runs/#{id}", options
|
||||
end
|
||||
|
||||
# List annotations for a check run
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param id [Integer] The ID of the check run
|
||||
# @return [Array<Sawyer::Resource>] An array of hashes representing check run annotations
|
||||
# @see https://developer.github.com/v3/checks/runs/#list-annotations-for-a-check-run
|
||||
# @example List annotations for a check run
|
||||
# annotations = @client.check_run_annotations("octocat/Hello-World", 51295429)
|
||||
# annotations.count # => 1
|
||||
# annotations[0].path # => "README.md"
|
||||
# annotations[0].message # => "Looks good!"
|
||||
def check_run_annotations(repo, id, options = {})
|
||||
paginate "#{Repository.path repo}/check-runs/#{id}/annotations", options
|
||||
end
|
||||
|
||||
# Methods for Check Suites
|
||||
#
|
||||
# @see https://developer.github.com/v3/checks/suites/
|
||||
|
||||
# Get a single check suite
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param id [Integer] The ID of the check suite
|
||||
# @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 = {})
|
||||
get "#{Repository.path repo}/check-suites/#{id}", options
|
||||
end
|
||||
|
||||
# List check suites for a specific ref
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param ref [String] A SHA, branch name, or tag name
|
||||
# @param options [Hash] A set of optional filters
|
||||
# @option options [Integer] :app_id Filters check suites by GitHub App <tt>id</tt>
|
||||
# @option options [String] :check_name Filters checks suites by the <tt>name</tt> of the check run
|
||||
# @return [Sawyer::Resource] A hash representing a collection of check suites
|
||||
# @see https://developer.github.com/v3/checks/suites/#list-check-suites-for-a-specific-ref
|
||||
# @example List check suites for a specific ref
|
||||
# result = @client.check_suites_for_ref("octocat/Hello-World", "7638417db6d59f3c431d3e1f261cc637155684cd", app_id: 76765)
|
||||
# result.total_count # => 1
|
||||
# result.check_suites.count # => 1
|
||||
# result.check_suites[0].id # => 50440400
|
||||
# result.check_suites[0].app.id # => 76765
|
||||
def check_suites_for_ref(repo, ref, options = {})
|
||||
paginate "#{Repository.path repo}/commits/#{ref}/check-suites", options do |data, last_response|
|
||||
data.check_suites.concat last_response.data.check_suites
|
||||
data.total_count += last_response.data.total_count
|
||||
end
|
||||
end
|
||||
alias list_check_suites_for_ref check_suites_for_ref
|
||||
|
||||
# Set preferences for check suites on a repository
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param options [Hash] Preferences to set
|
||||
# @return [Sawyer::Resource] A hash representing the repository's check suite preferences
|
||||
# @see https://developer.github.com/v3/checks/suites/#set-preferences-for-check-suites-on-a-repository
|
||||
# @example Set preferences for check suites on a repository
|
||||
# result = @client.set_check_suite_preferences("octocat/Hello-World", auto_trigger_checks: [{ app_id: 76765, setting: false }])
|
||||
# result.preferences.auto_trigger_checks.count # => 1
|
||||
# result.preferences.auto_trigger_checks[0].app_id # => 76765
|
||||
# result.preferences.auto_trigger_checks[0].setting # => false
|
||||
# result.repository.full_name # => "octocat/Hello-World"
|
||||
def set_check_suite_preferences(repo, options = {})
|
||||
patch "#{Repository.path repo}/check-suites/preferences", options
|
||||
end
|
||||
|
||||
# Create a check suite
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param head_sha [String] The SHA of the commit to check
|
||||
# @return [Sawyer::Resource] A hash representing the new check suite
|
||||
# @see https://developer.github.com/v3/checks/suites/#create-a-check-suite
|
||||
# @example Create a check suite
|
||||
# check_suite = @client.create_check_suite("octocat/Hello-World", "7638417db6d59f3c431d3e1f261cc637155684cd")
|
||||
# check_suite.head_sha # => "7638417db6d59f3c431d3e1f261cc637155684cd"
|
||||
# check_suite.status # => "queued"
|
||||
def create_check_suite(repo, head_sha, options = {})
|
||||
options[:head_sha] = head_sha
|
||||
|
||||
post "#{Repository.path repo}/check-suites", options
|
||||
end
|
||||
|
||||
# Rerequest check suite
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param id [Integer] The ID of the check suite
|
||||
# @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 = {})
|
||||
post "#{Repository.path repo}/check-suites/#{id}/rerequest", options
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,20 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Branches for HEAD API
|
||||
#
|
||||
# @see https://developer.github.com/v3/repos/commits/
|
||||
module CommitBranches
|
||||
# List branches for a single HEAD commit
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param sha [String] The SHA of the commit whose branches will be fetched
|
||||
# @return [Array] List of branches
|
||||
# @see https://developer.github.com/v3/repos/commits/#list-branches-for-head-commit
|
||||
def commit_branches(repo, sha, options = {})
|
||||
paginate "#{Repository.path repo}/commits/#{sha}/branches-where-head", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,95 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Commit Comments API
|
||||
#
|
||||
# @see https://developer.github.com/v3/repos/comments/
|
||||
module CommitComments
|
||||
# List all commit comments
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @return [Array] List of commit comments
|
||||
# @see https://developer.github.com/v3/repos/comments/#list-commit-comments-for-a-repository
|
||||
def list_commit_comments(repo, options = {})
|
||||
paginate "#{Repository.path repo}/comments", options
|
||||
end
|
||||
|
||||
# List comments for a single commit
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param sha [String] The SHA of the commit whose comments will be fetched
|
||||
# @return [Array] List of commit comments
|
||||
# @see https://developer.github.com/v3/repos/comments/#list-comments-for-a-single-commit
|
||||
def commit_comments(repo, sha, options = {})
|
||||
paginate "#{Repository.path repo}/commits/#{sha}/comments", options
|
||||
end
|
||||
|
||||
# Get a single commit comment
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param id [String] The ID of the comment to fetch
|
||||
# @return [Sawyer::Resource] Commit comment
|
||||
# @see https://developer.github.com/v3/repos/comments/#get-a-single-commit-comment
|
||||
def commit_comment(repo, id, options = {})
|
||||
get "#{Repository.path repo}/comments/#{id}", options
|
||||
end
|
||||
|
||||
# Create a commit comment
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param sha [String] Sha of the commit to comment on
|
||||
# @param body [String] Message
|
||||
# @param path [String] Relative path of file to comment on
|
||||
# @param line [Integer] Line number in the file to comment on
|
||||
# @param position [Integer] Line index in the diff to comment on
|
||||
# @return [Sawyer::Resource] Commit comment
|
||||
# @see https://developer.github.com/v3/repos/comments/#create-a-commit-comment
|
||||
# @example Create a commit comment
|
||||
# comment = Octokit.create_commit_comment("octocat/Hello-World", "827efc6d56897b048c772eb4087f854f46256132", "My comment message", "README.md", 10, 1)
|
||||
# comment.commit_id # => "827efc6d56897b048c772eb4087f854f46256132"
|
||||
# comment.id # => 54321
|
||||
# comment.body # => "My comment message"
|
||||
# comment.path # => "README.md"
|
||||
# comment.line # => 10
|
||||
# comment.position # => 1
|
||||
def create_commit_comment(repo, sha, body, path = nil, line = nil, position = nil, options = {})
|
||||
params = {
|
||||
body: body,
|
||||
path: path,
|
||||
line: line,
|
||||
position: position
|
||||
}
|
||||
post "#{Repository.path repo}/commits/#{sha}/comments", options.merge(params)
|
||||
end
|
||||
|
||||
# Update a commit comment
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param id [String] The ID of the comment to update
|
||||
# @param body [String] Message
|
||||
# @return [Sawyer::Resource] Updated commit comment
|
||||
# @see https://developer.github.com/v3/repos/comments/#update-a-commit-comment
|
||||
# @example Update a commit comment
|
||||
# comment = Octokit.update_commit_comment("octocat/Hello-World", "860296", "Updated commit comment")
|
||||
# comment.id # => 860296
|
||||
# comment.body # => "Updated commit comment"
|
||||
def update_commit_comment(repo, id, body, options = {})
|
||||
params = {
|
||||
body: body
|
||||
}
|
||||
patch "#{Repository.path repo}/comments/#{id}", options.merge(params)
|
||||
end
|
||||
|
||||
# Delete a commit comment
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param id [String] The ID of the comment to delete
|
||||
# @return [Boolean] Success
|
||||
# @see https://developer.github.com/v3/repos/comments/#delete-a-commit-comment
|
||||
def delete_commit_comment(repo, id, options = {})
|
||||
boolean_from_response :delete, "#{Repository.path repo}/comments/#{id}", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,20 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Commit Pulls API
|
||||
#
|
||||
# @see https://developer.github.com/v3/repos/comments/
|
||||
module CommitPulls
|
||||
# List pulls for a single commit
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param sha [String] The SHA of the commit whose pulls will be fetched
|
||||
# @return [Array] List of commit pulls
|
||||
# @see https://developer.github.com/v3/repos/commits/#list-pull-requests-associated-with-commit
|
||||
def commit_pulls(repo, sha, options = {})
|
||||
paginate "#{Repository.path repo}/commits/#{sha}/pulls", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,236 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'date'
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Commits API
|
||||
#
|
||||
# @see https://developer.github.com/v3/repos/commits/
|
||||
module Commits
|
||||
# List commits
|
||||
#
|
||||
# @overload commits(repo, sha_or_branch, options = {})
|
||||
# @deprecated
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param sha_or_branch [String] A commit SHA or branch name
|
||||
# @param options [String] :sha Commit SHA or branch name from which to start the list
|
||||
# @overload commits(repo, options = {})
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param options [String] :sha Commit SHA or branch name from which to start the list
|
||||
# @return [Array<Sawyer::Resource>] An array of hashes representing commits
|
||||
# @see https://developer.github.com/v3/repos/commits/#list-commits-on-a-repository
|
||||
def commits(*args)
|
||||
arguments = Octokit::RepoArguments.new(args)
|
||||
sha_or_branch = arguments.pop
|
||||
arguments.options[:sha] = sha_or_branch if sha_or_branch
|
||||
paginate "#{Repository.new(arguments.repo).path}/commits", arguments.options
|
||||
end
|
||||
alias list_commits commits
|
||||
|
||||
# Get commits after a specified date
|
||||
#
|
||||
# @overload commits_since(repo, date, options = {})
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param date [String] Date on which we want to compare
|
||||
# @param options [String] :sha Commit SHA or branch name from which to start the list
|
||||
# @overload commits_since(repo, date, sha_or_branch, options = {})
|
||||
# @deprecated
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param date [String] Date on which we want to compare
|
||||
# @param sha_or_branch [String] A commit SHA or branch name
|
||||
# @param options [String] :sha Commit SHA or branch name from which to start the list
|
||||
# @return [Array<Sawyer::Resource>] An array of hashes representing commits
|
||||
# @see https://developer.github.com/v3/repos/commits/#list-commits-on-a-repository
|
||||
# @example
|
||||
# Octokit.commits_since('octokit/octokit.rb', '2012-10-01')
|
||||
def commits_since(*args)
|
||||
arguments = Octokit::RepoArguments.new(args)
|
||||
date = parse_date(arguments.shift)
|
||||
params = arguments.options
|
||||
params.merge!(since: iso8601(date))
|
||||
sha_or_branch = arguments.pop
|
||||
params[:sha] = sha_or_branch if sha_or_branch
|
||||
commits(arguments.repo, params)
|
||||
end
|
||||
|
||||
# Get commits before a specified date
|
||||
#
|
||||
# @overload commits_before(repo, date, options = {})
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param date [String] Date on which we want to compare
|
||||
# @overload commits_before(repo, date, sha_or_branch, options = {})
|
||||
# @deprecated
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param date [String] Date on which we want to compare
|
||||
# @param sha_or_branch [String] Commit SHA or branch name from which to start the list
|
||||
# @return [Array<Sawyer::Resource>] An array of hashes representing commits
|
||||
# @see https://developer.github.com/v3/repos/commits/#list-commits-on-a-repository
|
||||
# @example
|
||||
# Octokit.commits_before('octokit/octokit.rb', '2012-10-01')
|
||||
def commits_before(*args)
|
||||
arguments = Octokit::RepoArguments.new(args)
|
||||
date = parse_date(arguments.shift)
|
||||
params = arguments.options
|
||||
params.merge!(until: iso8601(date))
|
||||
sha_or_branch = arguments.pop
|
||||
params[:sha] = sha_or_branch if sha_or_branch
|
||||
commits(arguments.repo, params)
|
||||
end
|
||||
|
||||
# Get commits on a specified date
|
||||
#
|
||||
# @overload commits_on(repo, date, options = {})
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param date [String] Date on which we want to compare
|
||||
# @overload commits_on(repo, date, sha_or_branch, options = {})
|
||||
# @deprecated
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param date [String] Date on which we want to compare
|
||||
# @param sha_or_branch [String] Commit SHA or branch name from which to start the list
|
||||
# @return [Array<Sawyer::Resource>] An array of hashes representing commits
|
||||
# @see https://developer.github.com/v3/repos/commits/#list-commits-on-a-repository
|
||||
# @example
|
||||
# Octokit.commits_on('octokit/octokit.rb', '2012-10-01')
|
||||
def commits_on(*args)
|
||||
arguments = Octokit::RepoArguments.new(args)
|
||||
date = parse_date(arguments.shift)
|
||||
params = arguments.options
|
||||
end_date = date + 1
|
||||
params.merge!(since: iso8601(date), until: iso8601(end_date))
|
||||
sha_or_branch = arguments.pop
|
||||
params[:sha] = sha_or_branch if sha_or_branch
|
||||
commits(arguments.repo, params)
|
||||
end
|
||||
|
||||
# Get commits made between two nominated dates
|
||||
#
|
||||
# @overload commits_between(repo, start_date, end_date, options = {})
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param start_date [String] Start Date on which we want to compare
|
||||
# @param end_date [String] End Date on which we want to compare
|
||||
# @overload commits_between(repo, start_date, end_date, sha_or_branch, options = {})
|
||||
# @deprecated
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param start_date [String] Start Date on which we want to compare
|
||||
# @param end_date [String] End Date on which we want to compare
|
||||
# @param sha_or_branch [String] Commit SHA or branch name from which to start the list
|
||||
# @return [Array<Sawyer::Resource>] An array of hashes representing commits
|
||||
# @see https://developer.github.com/v3/repos/commits/#list-commits-on-a-repository
|
||||
# @example
|
||||
# Octokit.commits_between('octokit/octokit.rb', '2012-10-01', '2012-11-01')
|
||||
def commits_between(*args)
|
||||
arguments = Octokit::RepoArguments.new(args)
|
||||
date = parse_date(arguments.shift)
|
||||
end_date = parse_date(arguments.shift)
|
||||
if date > end_date
|
||||
raise ArgumentError, "Start date #{date} does not precede #{end_date}"
|
||||
end
|
||||
|
||||
params = arguments.options
|
||||
params.merge!(since: iso8601(date), until: iso8601(end_date))
|
||||
sha_or_branch = arguments.pop
|
||||
params[:sha] = sha_or_branch if sha_or_branch
|
||||
commits(arguments.repo, params)
|
||||
end
|
||||
|
||||
# Get a single commit
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param sha [String] The SHA of the commit to fetch
|
||||
# @return [Sawyer::Resource] A hash representing the commit
|
||||
# @see https://developer.github.com/v3/repos/commits/#get-a-single-commit
|
||||
def commit(repo, sha, options = {})
|
||||
get "#{Repository.path repo}/commits/#{sha}", options
|
||||
end
|
||||
|
||||
# Get a detailed git commit
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param sha [String] The SHA of the commit to fetch
|
||||
# @return [Sawyer::Resource] A hash representing the commit
|
||||
# @see https://developer.github.com/v3/git/commits/#get-a-commit
|
||||
def git_commit(repo, sha, options = {})
|
||||
get "#{Repository.path repo}/git/commits/#{sha}", options
|
||||
end
|
||||
|
||||
# Create a commit
|
||||
#
|
||||
# Optionally pass <tt>author</tt> and <tt>committer</tt> hashes in <tt>options</tt>
|
||||
# if you'd like manual control over those parameters. If absent, details will be
|
||||
# inferred from the authenticated user. See <a href="http://developer.github.com/v3/git/commits/">GitHub's documentation</a>
|
||||
# for details about how to format committer identities.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param message [String] The commit message
|
||||
# @param tree [String] The SHA of the tree object the new commit will point to
|
||||
# @param parents [String, Array] One SHA (for a normal commit) or an array of SHAs (for a merge) of the new commit's parent commits. If ommitted or empty, a root commit will be created
|
||||
# @return [Sawyer::Resource] A hash representing the new commit
|
||||
# @see https://developer.github.com/v3/git/commits/#create-a-commit
|
||||
# @example Create a commit
|
||||
# commit = Octokit.create_commit("octocat/Hello-World", "My commit message", "827efc6d56897b048c772eb4087f854f46256132", "7d1b31e74ee336d15cbd21741bc88a537ed063a0")
|
||||
# commit.sha # => "7638417db6d59f3c431d3e1f261cc637155684cd"
|
||||
# commit.tree.sha # => "827efc6d56897b048c772eb4087f854f46256132"
|
||||
# commit.message # => "My commit message"
|
||||
# commit.committer # => { "name" => "Wynn Netherland", "email" => "wynn@github.com", ... }
|
||||
def create_commit(repo, message, tree, parents = nil, options = {})
|
||||
params = { message: message, tree: tree }
|
||||
params[:parents] = [parents].flatten if parents
|
||||
post "#{Repository.path repo}/git/commits", options.merge(params)
|
||||
end
|
||||
|
||||
# Compare two commits
|
||||
#
|
||||
# When using auto_pagination, commits from all pages will be concatenated
|
||||
# into the <tt>commits</tt> attribute of the first page's response.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param start [String] The sha of the starting commit
|
||||
# @param endd [String] The sha of the ending commit
|
||||
# @return [Sawyer::Resource] A hash representing the comparison
|
||||
# @see https://developer.github.com/v3/repos/commits/#compare-two-commits
|
||||
def compare(repo, start, endd, options = {})
|
||||
paginate "#{Repository.path repo}/compare/#{start}...#{endd}", options do |data, last_response|
|
||||
data.commits.concat last_response.data.commits
|
||||
end
|
||||
end
|
||||
|
||||
# Merge a branch or sha
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param base [String] The name of the base branch to merge into
|
||||
# @param head [String] The branch or SHA1 to merge
|
||||
# @option options [String] :commit_message The commit message for the merge
|
||||
# @return [Sawyer::Resource] A hash representing the comparison
|
||||
# @see https://developer.github.com/v3/repos/merging/#perform-a-merge
|
||||
def merge(repo, base, head, options = {})
|
||||
params = {
|
||||
base: base,
|
||||
head: head
|
||||
}.merge(options)
|
||||
post "#{Repository.path repo}/merges", params
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def iso8601(date)
|
||||
if date.respond_to?(:iso8601)
|
||||
date.iso8601
|
||||
else
|
||||
date.strftime('%Y-%m-%dT%H:%M:%S%Z')
|
||||
end
|
||||
end
|
||||
|
||||
# Parses the given string representation of a date, throwing a meaningful exception
|
||||
# (containing the date that failed to parse) in case of failure.
|
||||
#
|
||||
# @param date [String] String representation of a date
|
||||
# @return [DateTime]
|
||||
def parse_date(date)
|
||||
date = DateTime.parse(date.to_s)
|
||||
rescue ArgumentError
|
||||
raise ArgumentError, "#{date} is not a valid date"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Community Profile API
|
||||
#
|
||||
# @see https://developer.github.com/v3/repos/community/
|
||||
module CommunityProfile
|
||||
# Get community profile metrics for a repository
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @return [Sawyer::Resource] Community profile metrics
|
||||
# @see https://developer.github.com/v3/repos/community/#retrieve-community-profile-metrics
|
||||
# @example Get community profile metrics for octokit/octokit.rb
|
||||
# @client.community_profile('octokit/octokit.rb')
|
||||
def community_profile(repo, options = {})
|
||||
get "#{Repository.path repo}/community/profile", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,167 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'base64'
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Repo Contents API
|
||||
#
|
||||
# @see https://developer.github.com/v3/repos/contents/
|
||||
module Contents
|
||||
# Receive the default Readme for a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @option options [String] :ref name of the Commit/Branch/Tag. Defaults to “master”.
|
||||
# @return [Sawyer::Resource] The detail of the readme
|
||||
# @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
|
||||
|
||||
# Receive a listing of a repository folder or the contents of a file
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @option options [String] :path A folder or file path
|
||||
# @option options [String] :ref name of the Commit/Branch/Tag. Defaults to “master”.
|
||||
# @return [Sawyer::Resource] The contents of a file or list of the files in the folder
|
||||
# @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
|
||||
url = "#{Repository.path repo}/contents/#{repo_path}"
|
||||
get url, options
|
||||
end
|
||||
alias content contents
|
||||
|
||||
# Add content to a repository
|
||||
#
|
||||
# @overload create_contents(repo, path, message, content = nil, options = {})
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param path [String] A path for the new content
|
||||
# @param message [String] A commit message for adding the content
|
||||
# @param optional content [String] The content for the file
|
||||
# @option options [String] :branch The branch on which to add the content
|
||||
# @option options [String] :file Path or Ruby File object for content
|
||||
# @return [Sawyer::Resource] The contents and commit info for the addition
|
||||
# @see https://developer.github.com/v3/repos/contents/#create-a-file
|
||||
# @example Add content at lib/octokit.rb
|
||||
# Octokit.create_contents("octokit/octokit.rb",
|
||||
# "lib/octokit.rb",
|
||||
# "Adding content",
|
||||
# "File content",
|
||||
# :branch => "my-new-feature")
|
||||
def create_contents(*args)
|
||||
args = args.map { |item| item&.dup }
|
||||
options = args.last.is_a?(Hash) ? args.pop : {}
|
||||
repo = args.shift
|
||||
path = args.shift
|
||||
message = args.shift
|
||||
content = args.shift
|
||||
if content.nil? && file = options.delete(:file)
|
||||
case file
|
||||
when String
|
||||
if File.exist?(file)
|
||||
file = File.open(file, 'r')
|
||||
content = file.read
|
||||
file.close
|
||||
end
|
||||
when File, Tempfile
|
||||
content = file.read
|
||||
file.close
|
||||
end
|
||||
end
|
||||
raise ArgumentError, 'content or :file option required' if content.nil?
|
||||
|
||||
options[:content] = Base64.strict_encode64(content)
|
||||
options[:message] = message
|
||||
url = "#{Repository.path repo}/contents/#{path}"
|
||||
put url, options
|
||||
end
|
||||
alias create_content create_contents
|
||||
alias add_content create_contents
|
||||
alias add_contents create_contents
|
||||
|
||||
# Update content in a repository
|
||||
#
|
||||
# @overload update_contents(repo, path, message, sha, content = nil, options = {})
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param path [String] A path for the content to update
|
||||
# @param message [String] A commit message for updating the content
|
||||
# @param sha [String] The _blob sha_ of the content to update
|
||||
# @param content [String] The content for the file
|
||||
# @option options [String] :branch The branch on which to update the content
|
||||
# @option options [String] :file Path or Ruby File object for content
|
||||
# @return [Sawyer::Resource] The contents and commit info for the update
|
||||
# @see https://developer.github.com/v3/repos/contents/#update-a-file
|
||||
# @example Update content at lib/octokit.rb
|
||||
# Octokit.update_contents("octokit/octokit.rb",
|
||||
# "lib/octokit.rb",
|
||||
# "Updating content",
|
||||
# "7eb95f97e1a0636015df3837478d3f15184a5f49",
|
||||
# "File content",
|
||||
# :branch => "my-new-feature")
|
||||
def update_contents(*args)
|
||||
options = args.last.is_a?(Hash) ? args.pop : {}
|
||||
repo = args.shift
|
||||
path = args.shift
|
||||
message = args.shift
|
||||
sha = args.shift
|
||||
content = args.shift
|
||||
options.merge!(sha: sha)
|
||||
create_contents(repo, path, message, content, options)
|
||||
end
|
||||
alias update_content update_contents
|
||||
|
||||
# Delete content in a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param path [String] A path for the content to delete
|
||||
# @param message [String] A commit message for deleting the content
|
||||
# @param sha [String] The _blob sha_ of the content to delete
|
||||
# @option options [String] :branch The branch on which to delete the content
|
||||
# @return [Sawyer::Resource] The commit info for the delete
|
||||
# @see https://developer.github.com/v3/repos/contents/#delete-a-file
|
||||
# @example Delete content at lib/octokit.rb
|
||||
# Octokit.delete_contents("octokit/octokit.rb",
|
||||
# "lib/octokit.rb",
|
||||
# "Deleting content",
|
||||
# "7eb95f97e1a0636015df3837478d3f15184a5f49",
|
||||
# :branch => "my-new-feature")
|
||||
def delete_contents(repo, path, message, sha, options = {})
|
||||
options[:message] = message
|
||||
options[:sha] = sha
|
||||
url = "#{Repository.path repo}/contents/#{path}"
|
||||
delete url, options
|
||||
end
|
||||
alias delete_content delete_contents
|
||||
alias remove_content delete_contents
|
||||
alias remove_contents delete_contents
|
||||
|
||||
# This method will provide a URL to download a tarball or zipball archive for a repository.
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository.
|
||||
# @option options format [String] Either tarball (default) or zipball.
|
||||
# @option options [String] :ref Optional valid Git reference, defaults to master.
|
||||
# @return [String] Location of the download
|
||||
# @see https://developer.github.com/v3/repos/contents/#get-archive-link
|
||||
# @example Get archive link for octokit/octokit.rb
|
||||
# Octokit.archive_link("octokit/octokit.rb")
|
||||
def archive_link(repo, options = {})
|
||||
repo_ref = ERB::Util.url_encode(options.delete(:ref))
|
||||
format = (options.delete :format) || 'tarball'
|
||||
url = "#{Repository.path repo}/#{format}/#{repo_ref}"
|
||||
|
||||
response = client_without_redirects.head(url, options)
|
||||
response.headers['Location']
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,82 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Deployments API
|
||||
#
|
||||
# @see https://developer.github.com/v3/repos/commits/deployments/
|
||||
module Deployments
|
||||
# Fetch a single deployment for a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param deployment_id [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @return <Sawyer::Resource> A single deployment
|
||||
# @see https://developer.github.com/v3/repos/deployments/#get-a-single-deployment
|
||||
def deployment(repo, deployment_id, options = {})
|
||||
get("#{Repository.path repo}/deployments/#{deployment_id}", options)
|
||||
end
|
||||
|
||||
# List all deployments for a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @return [Array<Sawyer::Resource>] A list of deployments
|
||||
# @see https://developer.github.com/v3/repos/deployments/#list-deployments
|
||||
def deployments(repo, options = {})
|
||||
get("#{Repository.path repo}/deployments", options)
|
||||
end
|
||||
alias list_deployments deployments
|
||||
|
||||
# Create a deployment for a ref
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param ref [String] The ref to deploy
|
||||
# @option options [String] :task Used by the deployment system to allow different execution paths. Defaults to "deploy".
|
||||
# @option options [String] :payload Meta info about the deployment
|
||||
# @option options [Boolean] :auto_merge Optional parameter to merge the default branch into the requested deployment branch if necessary. Default: true
|
||||
# @option options [Array<String>] :required_contexts Optional array of status contexts verified against commit status checks.
|
||||
# @option options [String] :environment Optional name for the target deployment environment (e.g., production, staging, qa). Default: "production"
|
||||
# @option options [String] :description Optional short description.
|
||||
# @return [Sawyer::Resource] A deployment
|
||||
# @see https://developer.github.com/v3/repos/deployments/#create-a-deployment
|
||||
def create_deployment(repo, ref, options = {})
|
||||
options[:ref] = ref
|
||||
post("#{Repository.path repo}/deployments", options)
|
||||
end
|
||||
|
||||
# Delete a Deployment
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param deployment_id [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @return [No Content]
|
||||
# @see https://developer.github.com/v3/repos/deployments/#delete-a-deployment
|
||||
def delete_deployment(repo, deployment_id, options = {})
|
||||
delete("#{Repository.path repo}/deployments/#{deployment_id}", options)
|
||||
end
|
||||
|
||||
# List all statuses for a Deployment
|
||||
#
|
||||
# @param deployment_url [String] A URL for a deployment resource
|
||||
# @return [Array<Sawyer::Resource>] A list of deployment statuses
|
||||
# @see https://developer.github.com/v3/repos/deployments/#list-deployment-statuses
|
||||
def deployment_statuses(deployment_url, options = {})
|
||||
deployment = get(deployment_url, accept: options[:accept])
|
||||
get(deployment.rels[:statuses].href, options)
|
||||
end
|
||||
alias list_deployment_statuses deployment_statuses
|
||||
|
||||
# Create a deployment status for a Deployment
|
||||
#
|
||||
# @param deployment_url [String] A URL for a deployment resource
|
||||
# @param state [String] The state: pending, success, failure, error
|
||||
# @option options [String] :target_url The target URL to associate with this status. Default: ""
|
||||
# @option options [String] :description A short description of the status. Maximum length of 140 characters. Default: ""
|
||||
# @return [Sawyer::Resource] A deployment status
|
||||
# @see https://developer.github.com/v3/repos/deployments/#create-a-deployment-status
|
||||
def create_deployment_status(deployment_url, state, options = {})
|
||||
deployment = get(deployment_url, accept: options[:accept])
|
||||
options[:state] = state.to_s.downcase
|
||||
post(deployment.rels[:statuses].href, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,49 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Repo Downloads API
|
||||
#
|
||||
# @see https://developer.github.com/v3/repos/downloads/
|
||||
module Downloads
|
||||
# List available downloads for a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A Github Repository
|
||||
# @return [Array] A list of available downloads
|
||||
# @deprecated As of December 11th, 2012: https://github.com/blog/1302-goodbye-uploads
|
||||
# @see https://developer.github.com/v3/repos/downloads/#list-downloads-for-a-repository
|
||||
# @example List all downloads for Github/Hubot
|
||||
# Octokit.downloads("github/hubot")
|
||||
def downloads(repo, options = {})
|
||||
paginate "#{Repository.path repo}/downloads", options
|
||||
end
|
||||
alias list_downloads downloads
|
||||
|
||||
# Get single download for a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param id [Integer] ID of the download
|
||||
# @return [Sawyer::Resource] A single download from the repository
|
||||
# @deprecated As of December 11th, 2012: https://github.com/blog/1302-goodbye-uploads
|
||||
# @see https://developer.github.com/v3/repos/downloads/#get-a-single-download
|
||||
# @example Get the "Robawt" download from Github/Hubot
|
||||
# Octokit.download("github/hubot")
|
||||
def download(repo, id, options = {})
|
||||
get "#{Repository.path repo}/downloads/#{id}", options
|
||||
end
|
||||
|
||||
# Delete a single download for a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param id [Integer] ID of the download
|
||||
# @deprecated As of December 11th, 2012: https://github.com/blog/1302-goodbye-uploads
|
||||
# @see https://developer.github.com/v3/repos/downloads/#delete-a-download
|
||||
# @return [Boolean] Status
|
||||
# @example Get the "Robawt" download from Github/Hubot
|
||||
# Octokit.delete_download("github/hubot", 1234)
|
||||
def delete_download(repo, id, options = {})
|
||||
boolean_from_response :delete, "#{Repository.path repo}/downloads/#{id}", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Emojis API
|
||||
module Emojis
|
||||
# List all emojis used on GitHub
|
||||
#
|
||||
# @return [Sawyer::Resource] A list of all emojis on GitHub
|
||||
# @see https://developer.github.com/v3/emojis/#emojis
|
||||
# @example List all emojis
|
||||
# Octokit.emojis
|
||||
def emojis(options = {})
|
||||
get 'emojis', options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,55 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Environments API
|
||||
#
|
||||
# @see https://docs.github.com/en/rest/deployments/environments
|
||||
module Environments
|
||||
# Fetch a single environment for a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param environment_name [String] The name of the environment
|
||||
# @return <Sawyer::Resource> A single environment
|
||||
# @see https://docs.github.com/en/rest/deployments/environments#get-an-environment
|
||||
def environment(repo, environment_name, options = {})
|
||||
get("#{Repository.path repo}/environments/#{environment_name}", options)
|
||||
end
|
||||
|
||||
# Lists the environments for a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @option options [Integer] :per_page The number of results per page (max 100). Default: 30
|
||||
# @option options [Integer] :page Page number of the results to fetch. Default: 1
|
||||
# @return [Sawyer::Resource] Total count of environments and list of environments
|
||||
# @see https://docs.github.com/en/rest/deployments/environments#list-environments
|
||||
def environments(repo, options = {})
|
||||
get("#{Repository.path repo}/environments", options)
|
||||
end
|
||||
alias list_environments environments
|
||||
|
||||
# Create or update an environment with protection rules, such as required reviewers
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param environment_name [String] The name of the environment
|
||||
# @option options [Integer] :wait_timer The amount of time to delay a job after the job is initially triggered. The time (in minutes) must be an integer between 0 and 43,200 (30 days).
|
||||
# @option options [Array] :reviewers The people or teams that may review jobs that reference the environment. You can list up to six users or teams as reviewers.
|
||||
# @option options [Object] :deployment_branch_policy The type of deployment branch policy for this environment. To allow all branches to deploy, set to null.
|
||||
# @return [Sawyer::Resource] An environment
|
||||
# @see https://docs.github.com/en/rest/deployments/environments#create-or-update-an-environment
|
||||
def create_or_update_environment(repo, environment_name, options = {})
|
||||
put("#{Repository.path repo}/environments/#{environment_name}", options)
|
||||
end
|
||||
|
||||
# Delete an Environment
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param environment_name [String] The name of the environment
|
||||
# @return [No Content]
|
||||
# @see https://docs.github.com/en/rest/deployments/environments#delete-an-environment
|
||||
def delete_environment(repo, environment_name, options = {})
|
||||
delete("#{Repository.path repo}/environments/#{environment_name}", options)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,151 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Method for the Events API
|
||||
#
|
||||
# @see https://developer.github.com/v3/activity/events/
|
||||
# @see https://developer.github.com/v3/issues/events/
|
||||
module Events
|
||||
# List all public events for GitHub
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] A list of all public events from GitHub
|
||||
# @see https://developer.github.com/v3/activity/events/#list-public-events
|
||||
# @example List all pubilc events
|
||||
# Octokit.public_events
|
||||
def public_events(options = {})
|
||||
paginate 'events', options
|
||||
end
|
||||
|
||||
# List all user events
|
||||
#
|
||||
# @param user [Integer, String] GitHub user login or id.
|
||||
# @return [Array<Sawyer::Resource>] A list of all user events
|
||||
# @see https://developer.github.com/v3/activity/events/#list-events-performed-by-a-user
|
||||
# @example List all user events
|
||||
# Octokit.user_events("sferik")
|
||||
def user_events(user, options = {})
|
||||
paginate "#{User.path user}/events", options
|
||||
end
|
||||
|
||||
# List public user events
|
||||
#
|
||||
# @param user [Integer, String] GitHub user login or id
|
||||
# @return [Array<Sawyer::Resource>] A list of public user events
|
||||
# @see https://developer.github.com/v3/activity/events/#list-public-events-performed-by-a-user
|
||||
# @example List public user events
|
||||
# Octokit.user_events("sferik")
|
||||
def user_public_events(user, options = {})
|
||||
paginate "#{User.path user}/events/public", options
|
||||
end
|
||||
|
||||
# List events that a user has received
|
||||
#
|
||||
# @param user [Integer, String] GitHub user login or id
|
||||
# @return [Array<Sawyer::Resource>] A list of all user received events
|
||||
# @see https://developer.github.com/v3/activity/events/#list-events-that-a-user-has-received
|
||||
# @example List all user received events
|
||||
# Octokit.received_events("sferik")
|
||||
def received_events(user, options = {})
|
||||
paginate "#{User.path user}/received_events", options
|
||||
end
|
||||
|
||||
# List public events a user has received
|
||||
#
|
||||
# @param user [Integer, String] GitHub user login or id
|
||||
# @return [Array<Sawyer::Resource>] A list of public user received events
|
||||
# @see https://developer.github.com/v3/activity/events/#list-public-events-that-a-user-has-received
|
||||
# @example List public user received events
|
||||
# Octokit.received_public_events("sferik")
|
||||
def received_public_events(user, options = {})
|
||||
paginate "#{User.path user}/received_events/public", options
|
||||
end
|
||||
|
||||
# List events for a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @return [Array<Sawyer::Resource>] A list of events for a repository
|
||||
# @see https://developer.github.com/v3/activity/events/#list-repository-events
|
||||
# @example List events for a repository
|
||||
# Octokit.repository_events("sferik/rails_admin")
|
||||
def repository_events(repo, options = {})
|
||||
paginate "#{Repository.path repo}/events", options
|
||||
end
|
||||
|
||||
# List public events for a repository's network
|
||||
#
|
||||
# @param repo [String, Repository, Hash] A GitHub repository
|
||||
# @return [Array<Sawyer::Resource>] A list of events for a repository's network
|
||||
# @see https://developer.github.com/v3/activity/events/#list-public-events-for-a-network-of-repositories
|
||||
# @example List events for a repository's network
|
||||
# Octokit.repository_network_events("sferik/rails_admin")
|
||||
def repository_network_events(repo, options = {})
|
||||
paginate "networks/#{Repository.new(repo)}/events", options
|
||||
end
|
||||
|
||||
# List all events for an organization
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param org [String] Organization GitHub handle
|
||||
# @return [Array<Sawyer::Resource>] List of all events from a GitHub organization
|
||||
# @see https://developer.github.com/v3/activity/events/#list-events-for-an-organization
|
||||
# @example List events for the lostisland organization
|
||||
# @client.organization_events("lostisland")
|
||||
def organization_events(org, options = {})
|
||||
paginate "users/#{login}/events/orgs/#{org}", options
|
||||
end
|
||||
|
||||
# List an organization's public events
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @return [Array<Sawyer::Resource>] List of public events from a GitHub organization
|
||||
# @see https://developer.github.com/v3/activity/events/#list-public-events-for-an-organization
|
||||
# @example List public events for GitHub
|
||||
# Octokit.organization_public_events("GitHub")
|
||||
def organization_public_events(org, options = {})
|
||||
paginate "#{Organization.path org}/events", options
|
||||
end
|
||||
|
||||
# Get all Issue Events for a given Repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] Array of all Issue Events for this Repository
|
||||
# @see https://developer.github.com/v3/issues/events/#list-events-for-a-repository
|
||||
# @see https://developer.github.com/v3/activity/events/#list-issue-events-for-a-repository
|
||||
# @example Get all Issue Events for Octokit
|
||||
# Octokit.repository_issue_events("octokit/octokit.rb")
|
||||
def repository_issue_events(repo, options = {})
|
||||
paginate "#{Repository.path repo}/issues/events", options
|
||||
end
|
||||
alias repo_issue_events repository_issue_events
|
||||
|
||||
# List events for an Issue
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param number [Integer] Issue number
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] Array of events for that issue
|
||||
# @see https://developer.github.com/v3/issues/events/#list-events-for-an-issue
|
||||
# @example List all issues events for issue #38 on octokit/octokit.rb
|
||||
# Octokit.issue_events("octokit/octokit.rb", 38)
|
||||
def issue_events(repo, number, options = {})
|
||||
paginate "#{Repository.path repo}/issues/#{number}/events", options
|
||||
end
|
||||
|
||||
# Get information on a single Issue Event
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param number [Integer] Event number
|
||||
#
|
||||
# @return [Sawyer::Resource] A single Event for an Issue
|
||||
# @see https://developer.github.com/v3/issues/events/#get-a-single-event
|
||||
# @example Get Event information for ID 3094334 (a pull request was closed)
|
||||
# Octokit.issue_event("octokit/octokit.rb", 3094334)
|
||||
def issue_event(repo, number, options = {})
|
||||
paginate "#{Repository.path repo}/issues/events/#{number}", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,32 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Feeds API
|
||||
#
|
||||
# @see https://developer.github.com/v3/activity/feeds/
|
||||
module Feeds
|
||||
# List Feeds
|
||||
#
|
||||
# The feeds returned depend on authentication, see the GitHub API docs
|
||||
# for more information.
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] list of feeds
|
||||
# @see https://developer.github.com/v3/activity/feeds/#list-feeds
|
||||
def feeds
|
||||
get 'feeds'
|
||||
end
|
||||
|
||||
# Get a Feed by name
|
||||
#
|
||||
# @param name [Symbol, String] Name of feed to retrieve.
|
||||
# @return [Feed] Parsed feed in the format returned by the configured
|
||||
# parser.
|
||||
def feed(name, options = {})
|
||||
if rel = feeds._links[name]
|
||||
get rel.href, accept: rel.type, options: options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,234 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Gists API
|
||||
#
|
||||
# @see https://developer.github.com/v3/gists/
|
||||
module Gists
|
||||
# List gists for a user or all public gists
|
||||
#
|
||||
# @param user [String] An optional user to filter listing
|
||||
# @return [Array<Sawyer::Resource>] A list of gists
|
||||
# @example Fetch all gists for defunkt
|
||||
# Octokit.gists('defunkt')
|
||||
# @example Fetch all public gists
|
||||
# Octokit.gists
|
||||
# @see https://developer.github.com/v3/gists/#list-gists
|
||||
def gists(user = nil, options = {})
|
||||
if user.nil?
|
||||
paginate 'gists', options
|
||||
else
|
||||
paginate "#{User.path user}/gists", options
|
||||
end
|
||||
end
|
||||
alias list_gists gists
|
||||
|
||||
# List public gists
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] A list of gists
|
||||
# @example Fetch all public gists
|
||||
# Octokit.public_gists
|
||||
# @see https://developer.github.com/v3/gists/#list-gists
|
||||
def public_gists(options = {})
|
||||
paginate 'gists/public', options
|
||||
end
|
||||
|
||||
# List the authenticated user’s starred gists
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] A list of gists
|
||||
# @see https://developer.github.com/v3/gists/#list-gists
|
||||
def starred_gists(options = {})
|
||||
paginate 'gists/starred', options
|
||||
end
|
||||
|
||||
# Get a single gist
|
||||
#
|
||||
# @param gist [String] ID of gist to fetch
|
||||
# @option options [String] :sha Specific gist revision SHA
|
||||
# @return [Sawyer::Resource] Gist information
|
||||
# @see https://developer.github.com/v3/gists/#get-a-single-gist
|
||||
# @see https://developer.github.com/v3/gists/#get-a-specific-revision-of-a-gist
|
||||
def gist(gist, options = {})
|
||||
options = options.dup
|
||||
if sha = options.delete(:sha)
|
||||
get "gists/#{Gist.new(gist)}/#{sha}", options
|
||||
else
|
||||
get "gists/#{Gist.new(gist)}", options
|
||||
end
|
||||
end
|
||||
|
||||
# Create a gist
|
||||
#
|
||||
# @param options [Hash] Gist information.
|
||||
# @option options [String] :description
|
||||
# @option options [Boolean] :public Sets gist visibility
|
||||
# @option options [Array<Hash>] :files Files that make up this gist. Keys
|
||||
# should be the filename, the value a Hash with a :content key with text
|
||||
# content of the Gist.
|
||||
# @return [Sawyer::Resource] Newly created gist info
|
||||
# @see https://developer.github.com/v3/gists/#create-a-gist
|
||||
def create_gist(options = {})
|
||||
post 'gists', options
|
||||
end
|
||||
|
||||
# Edit a gist
|
||||
#
|
||||
# @param options [Hash] Gist information.
|
||||
# @option options [String] :description
|
||||
# @option options [Hash] :files Files that make up this gist. Keys
|
||||
# should be the filename, the value a Hash with a :content key with text
|
||||
# content of the Gist.
|
||||
#
|
||||
# NOTE: All files from the previous version of the
|
||||
# gist are carried over by default if not included in the hash. Deletes
|
||||
# can be performed by including the filename with a null hash.
|
||||
# @return
|
||||
# [Sawyer::Resource] Newly created gist info
|
||||
# @see https://developer.github.com/v3/gists/#edit-a-gist
|
||||
# @example Update a gist
|
||||
# @client.edit_gist('some_id', {
|
||||
# :files => {"boo.md" => {"content" => "updated stuff"}}
|
||||
# })
|
||||
def edit_gist(gist, options = {})
|
||||
patch "gists/#{Gist.new(gist)}", options
|
||||
end
|
||||
|
||||
# List gist commits
|
||||
#
|
||||
# @param gist [String] Gist ID
|
||||
# @return [Array] List of commits to the gist
|
||||
# @see https://developer.github.com/v3/gists/#list-gist-commits
|
||||
# @example List commits for a gist
|
||||
# @client.gist_commits('some_id')
|
||||
def gist_commits(gist, options = {})
|
||||
paginate "gists/#{Gist.new(gist)}/commits", options
|
||||
end
|
||||
|
||||
#
|
||||
# Star a gist
|
||||
#
|
||||
# @param gist [String] Gist ID
|
||||
# @return [Boolean] Indicates if gist is starred successfully
|
||||
# @see https://developer.github.com/v3/gists/#star-a-gist
|
||||
def star_gist(gist, options = {})
|
||||
boolean_from_response :put, "gists/#{Gist.new(gist)}/star", options
|
||||
end
|
||||
|
||||
# Unstar a gist
|
||||
#
|
||||
# @param gist [String] Gist ID
|
||||
# @return [Boolean] Indicates if gist is unstarred successfully
|
||||
# @see https://developer.github.com/v3/gists/#unstar-a-gist
|
||||
def unstar_gist(gist, options = {})
|
||||
boolean_from_response :delete, "gists/#{Gist.new(gist)}/star", options
|
||||
end
|
||||
|
||||
# Check if a gist is starred
|
||||
#
|
||||
# @param gist [String] Gist ID
|
||||
# @return [Boolean] Indicates if gist is starred
|
||||
# @see https://developer.github.com/v3/gists/#check-if-a-gist-is-starred
|
||||
def gist_starred?(gist, options = {})
|
||||
boolean_from_response :get, "gists/#{Gist.new(gist)}/star", options
|
||||
end
|
||||
|
||||
# Fork a gist
|
||||
#
|
||||
# @param gist [String] Gist ID
|
||||
# @return [Sawyer::Resource] Data for the new gist
|
||||
# @see https://developer.github.com/v3/gists/#fork-a-gist
|
||||
def fork_gist(gist, options = {})
|
||||
post "gists/#{Gist.new(gist)}/forks", options
|
||||
end
|
||||
|
||||
# List gist forks
|
||||
#
|
||||
# @param gist [String] Gist ID
|
||||
# @return [Array] List of gist forks
|
||||
# @see https://developer.github.com/v3/gists/#list-gist-forks
|
||||
# @example List gist forks
|
||||
# @client.gist_forks('some-id')
|
||||
def gist_forks(gist, options = {})
|
||||
paginate "gists/#{Gist.new(gist)}/forks", options
|
||||
end
|
||||
|
||||
# Delete a gist
|
||||
#
|
||||
# @param gist [String] Gist ID
|
||||
# @return [Boolean] Indicating success of deletion
|
||||
# @see https://developer.github.com/v3/gists/#delete-a-gist
|
||||
def delete_gist(gist, options = {})
|
||||
boolean_from_response :delete, "gists/#{Gist.new(gist)}", options
|
||||
end
|
||||
|
||||
# List gist comments
|
||||
#
|
||||
# @param gist_id [String] Gist Id.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing comments.
|
||||
# @see https://developer.github.com/v3/gists/comments/#list-comments-on-a-gist
|
||||
# @example
|
||||
# Octokit.gist_comments('3528ae645')
|
||||
def gist_comments(gist_id, options = {})
|
||||
paginate "gists/#{gist_id}/comments", options
|
||||
end
|
||||
|
||||
# Get gist comment
|
||||
#
|
||||
# @param gist_id [String] Id of the gist.
|
||||
# @param gist_comment_id [Integer] Id of the gist comment.
|
||||
# @return [Sawyer::Resource] Hash representing gist comment.
|
||||
# @see https://developer.github.com/v3/gists/comments/#get-a-single-comment
|
||||
# @example
|
||||
# Octokit.gist_comment('208sdaz3', 1451398)
|
||||
def gist_comment(gist_id, gist_comment_id, options = {})
|
||||
get "gists/#{gist_id}/comments/#{gist_comment_id}", options
|
||||
end
|
||||
|
||||
# Create gist comment
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param gist_id [String] Id of the gist.
|
||||
# @param comment [String] Comment contents.
|
||||
# @return [Sawyer::Resource] Hash representing the new comment.
|
||||
# @see https://developer.github.com/v3/gists/comments/#create-a-comment
|
||||
# @example
|
||||
# @client.create_gist_comment('3528645', 'This is very helpful.')
|
||||
def create_gist_comment(gist_id, comment, options = {})
|
||||
options = options.merge({ body: comment })
|
||||
post "gists/#{gist_id}/comments", options
|
||||
end
|
||||
|
||||
# Update gist comment
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param gist_id [String] Id of the gist.
|
||||
# @param gist_comment_id [Integer] Id of the gist comment to update.
|
||||
# @param comment [String] Updated comment contents.
|
||||
# @return [Sawyer::Resource] Hash representing the updated comment.
|
||||
# @see https://developer.github.com/v3/gists/comments/#edit-a-comment
|
||||
# @example
|
||||
# @client.update_gist_comment('208sdaz3', '3528645', ':heart:')
|
||||
def update_gist_comment(gist_id, gist_comment_id, comment, options = {})
|
||||
options = options.merge({ body: comment })
|
||||
patch "gists/#{gist_id}/comments/#{gist_comment_id}", options
|
||||
end
|
||||
|
||||
# Delete gist comment
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param gist_id [String] Id of the gist.
|
||||
# @param gist_comment_id [Integer] Id of the gist comment to delete.
|
||||
# @return [Boolean] True if comment deleted, false otherwise.
|
||||
# @see https://developer.github.com/v3/gists/comments/#delete-a-comment
|
||||
# @example
|
||||
# @client.delete_gist_comment('208sdaz3', '586399')
|
||||
def delete_gist_comment(gist_id, gist_comment_id, options = {})
|
||||
boolean_from_response(:delete, "gists/#{gist_id}/comments/#{gist_comment_id}", options)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,43 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Gitignore API
|
||||
#
|
||||
# @see https://developer.github.com/v3/gitignore/
|
||||
module Gitignore
|
||||
# Listing available gitignore templates.
|
||||
#
|
||||
# These templates can be passed option when creating a repository.
|
||||
#
|
||||
# @see https://developer.github.com/v3/gitignore/#listing-available-templates
|
||||
#
|
||||
# @return [Array<String>] List of templates.
|
||||
#
|
||||
# @example Git all the gitignore templates
|
||||
# @client.gitignore_templates
|
||||
def gitignore_templates(options = {})
|
||||
get 'gitignore/templates', options
|
||||
end
|
||||
|
||||
# Get a gitignore template.
|
||||
#
|
||||
# Use the raw {http://developer.github.com/v3/media/ media type} to get
|
||||
# the raw contents.
|
||||
#
|
||||
# @param template_name [String] Name of the template. Template names are
|
||||
# case sensitive, make sure to use a valid name from the
|
||||
# .gitignore_templates list.
|
||||
#
|
||||
# @see https://developer.github.com/v3/gitignore/#get-a-single-template
|
||||
#
|
||||
# @return [Sawyer::Resource] Gitignore template
|
||||
#
|
||||
# @example Get the Ruby gitignore template
|
||||
# @client.gitignore_template('Ruby')
|
||||
def gitignore_template(template_name, options = {})
|
||||
get "gitignore/templates/#{template_name}", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,287 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Hooks API
|
||||
module Hooks
|
||||
# List repo hooks
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing hooks.
|
||||
# @see https://developer.github.com/v3/repos/hooks/#list-hooks
|
||||
# @example
|
||||
# @client.hooks('octokit/octokit.rb')
|
||||
def hooks(repo, options = {})
|
||||
paginate "#{Repository.path repo}/hooks", options
|
||||
end
|
||||
|
||||
# Get single hook
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param id [Integer] Id of the hook to get.
|
||||
# @return [Sawyer::Resource] Hash representing hook.
|
||||
# @see https://developer.github.com/v3/repos/hooks/#get-single-hook
|
||||
# @example
|
||||
# @client.hook('octokit/octokit.rb', 100000)
|
||||
def hook(repo, id, options = {})
|
||||
get "#{Repository.path repo}/hooks/#{id}", options
|
||||
end
|
||||
|
||||
# Create a hook
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param name [String] The name of the service that is being called. See
|
||||
# {https://api.github.com/hooks Hooks} for the possible names.
|
||||
# @param config [Hash] A Hash containing key/value pairs to provide
|
||||
# settings for this hook. These settings vary between the services and
|
||||
# are defined in the {https://github.com/github/github-services github-services} repo.
|
||||
# @option options [Array<String>] :events ('["push"]') Determines what
|
||||
# events the hook is triggered for.
|
||||
# @option options [Boolean] :active Determines whether the hook is
|
||||
# actually triggered on pushes.
|
||||
# @return [Sawyer::Resource] Hook info for the new hook
|
||||
# @see https://api.github.com/hooks
|
||||
# @see https://github.com/github/github-services
|
||||
# @see https://developer.github.com/v3/repos/hooks/#create-a-hook
|
||||
# @example
|
||||
# @client.create_hook(
|
||||
# 'octokit/octokit.rb',
|
||||
# 'web',
|
||||
# {
|
||||
# :url => 'http://something.com/webhook',
|
||||
# :content_type => 'json'
|
||||
# },
|
||||
# {
|
||||
# :events => ['push', 'pull_request'],
|
||||
# :active => true
|
||||
# }
|
||||
# )
|
||||
def create_hook(repo, name, config, options = {})
|
||||
options = { name: name, config: config, events: ['push'], active: true }.merge(options)
|
||||
post "#{Repository.path repo}/hooks", options
|
||||
end
|
||||
|
||||
# Edit a hook
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param id [Integer] Id of the hook being updated.
|
||||
# @param name [String] The name of the service that is being called. See
|
||||
# {https://api.github.com/hooks Hooks} for the possible names.
|
||||
# @param config [Hash] A Hash containing key/value pairs to provide
|
||||
# settings for this hook. These settings vary between the services and
|
||||
# are defined in the {https://github.com/github/github-services github-services} repo.
|
||||
# @option options [Array<String>] :events ('["push"]') Determines what
|
||||
# events the hook is triggered for.
|
||||
# @option options [Array<String>] :add_events Determines a list of events
|
||||
# to be added to the list of events that the Hook triggers for.
|
||||
# @option options [Array<String>] :remove_events Determines a list of events
|
||||
# to be removed from the list of events that the Hook triggers for.
|
||||
# @option options [Boolean] :active Determines whether the hook is
|
||||
# actually triggered on pushes.
|
||||
# @return [Sawyer::Resource] Hook info for the updated hook
|
||||
# @see https://api.github.com/hooks
|
||||
# @see https://github.com/github/github-services
|
||||
# @see https://developer.github.com/v3/repos/hooks/#edit-a-hook
|
||||
# @example
|
||||
# @client.edit_hook(
|
||||
# 'octokit/octokit.rb',
|
||||
# 100000,
|
||||
# 'web',
|
||||
# {
|
||||
# :url => 'http://something.com/webhook',
|
||||
# :content_type => 'json'
|
||||
# },
|
||||
# {
|
||||
# :add_events => ['status'],
|
||||
# :remove_events => ['pull_request'],
|
||||
# :active => true
|
||||
# }
|
||||
# )
|
||||
def edit_hook(repo, id, name, config, options = {})
|
||||
options = { name: name, config: config }.merge(options)
|
||||
patch "#{Repository.path repo}/hooks/#{id}", options
|
||||
end
|
||||
|
||||
# Delete hook
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param id [Integer] Id of the hook to remove.
|
||||
# @return [Boolean] True if hook removed, false otherwise.
|
||||
# @see https://developer.github.com/v3/repos/hooks/#delete-a-hook
|
||||
# @example
|
||||
# @client.remove_hook('octokit/octokit.rb', 1000000)
|
||||
def remove_hook(repo, id, options = {})
|
||||
boolean_from_response :delete, "#{Repository.path repo}/hooks/#{id}", options
|
||||
end
|
||||
|
||||
# Test hook
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param id [Integer] Id of the hook to test.
|
||||
# @return [Boolean] Success
|
||||
# @see https://developer.github.com/v3/repos/hooks/#test-a-push-hook
|
||||
# @example
|
||||
# @client.test_hook('octokit/octokit.rb', 1000000)
|
||||
def test_hook(repo, id, options = {})
|
||||
boolean_from_response :post, "#{Repository.path repo}/hooks/#{id}/tests", options
|
||||
end
|
||||
|
||||
# Ping hook
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param id [Integer] Id of the hook to send a ping.
|
||||
# @return [Boolean] Ping requested?
|
||||
# @see https://developer.github.com/v3/repos/hooks/#ping-a-hook
|
||||
# @example
|
||||
# @client.ping_hook('octokit/octokit.rb', 1000000)
|
||||
def ping_hook(repo, id, options = {})
|
||||
boolean_from_response :post, "#{Repository.path repo}/hooks/#{id}/pings", options
|
||||
end
|
||||
|
||||
# List org hooks
|
||||
#
|
||||
# Requires client authenticated as admin for the org.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing hooks.
|
||||
# @see https://developer.github.com/v3/orgs/hooks/#list-hooks
|
||||
# @example
|
||||
# @client.org_hooks('octokit')
|
||||
def org_hooks(org, options = {})
|
||||
paginate "#{Organization.path org}/hooks", options
|
||||
end
|
||||
alias list_org_hooks org_hooks
|
||||
|
||||
# Get an org hook
|
||||
#
|
||||
# Requires client authenticated as admin for the org.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @param id [Integer] Id of the hook to get.
|
||||
# @return [Sawyer::Resource] Hash representing hook.
|
||||
# @see https://developer.github.com/v3/orgs/hooks/#get-single-hook
|
||||
# @example
|
||||
# @client.org_hook('octokit', 123)
|
||||
def org_hook(org, id, options = {})
|
||||
get "#{Organization.path org}/hooks/#{id}", options
|
||||
end
|
||||
|
||||
# Create an org hook
|
||||
#
|
||||
# Requires client authenticated as admin for the org.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @param config [Hash] A Hash containing key/value pairs to provide
|
||||
# settings for this hook.
|
||||
# @option options [Array<String>] :events ('["push"]') Determines what
|
||||
# events the hook is triggered for.
|
||||
# @option options [Boolean] :active Determines whether the hook is
|
||||
# actually triggered on pushes.
|
||||
# @return [Sawyer::Resource] Hook info for the new hook
|
||||
# @see https://api.github.com/hooks
|
||||
# @see https://developer.github.com/v3/orgs/hooks/#create-a-hook
|
||||
# @example
|
||||
# @client.create_org_hook(
|
||||
# 'octokit',
|
||||
# {
|
||||
# :url => 'http://something.com/webhook',
|
||||
# :content_type => 'json'
|
||||
# },
|
||||
# {
|
||||
# :events => ['push', 'pull_request'],
|
||||
# :active => true
|
||||
# }
|
||||
# )
|
||||
def create_org_hook(org, config, options = {})
|
||||
options = { name: 'web', config: config }.merge(options)
|
||||
post "#{Organization.path org}/hooks", options
|
||||
end
|
||||
|
||||
# Update an org hook
|
||||
#
|
||||
# Requires client authenticated as admin for the org.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @param id [Integer] Id of the hook to update.
|
||||
# @param config [Hash] A Hash containing key/value pairs to provide
|
||||
# settings for this hook.
|
||||
# @option options [Array<String>] :events ('["push"]') Determines what
|
||||
# events the hook is triggered for.
|
||||
# @option options [Boolean] :active Determines whether the hook is
|
||||
# actually triggered on pushes.
|
||||
# @return [Sawyer::Resource] Hook info for the new hook
|
||||
# @see https://api.github.com/hooks
|
||||
# @see https://developer.github.com/v3/orgs/hooks/#edit-a-hook
|
||||
# @example
|
||||
# @client.edit_org_hook(
|
||||
# 'octokit',
|
||||
# 123,
|
||||
# {
|
||||
# :url => 'http://something.com/webhook',
|
||||
# :content_type => 'json'
|
||||
# },
|
||||
# {
|
||||
# :events => ['push', 'pull_request'],
|
||||
# :active => true
|
||||
# }
|
||||
# )
|
||||
def edit_org_hook(org, id, config, options = {})
|
||||
options = { config: config }.merge(options)
|
||||
patch "#{Organization.path org}/hooks/#{id}", options
|
||||
end
|
||||
alias update_org_hook edit_org_hook
|
||||
|
||||
# Ping org hook
|
||||
#
|
||||
# Requires client authenticated as admin for the org.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @param id [Integer] Id of the hook to update.
|
||||
# @return [Boolean] Success
|
||||
# @see https://developer.github.com/v3/orgs/hooks/#ping-a-hook
|
||||
# @example
|
||||
# @client.ping_org_hook('octokit', 1000000)
|
||||
def ping_org_hook(org, id, options = {})
|
||||
boolean_from_response :post, "#{Organization.path org}/hooks/#{id}/pings", options
|
||||
end
|
||||
|
||||
# Remove org hook
|
||||
#
|
||||
# Requires client authenticated as admin for the org.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @param id [Integer] Id of the hook to update.
|
||||
# @return [Boolean] True if hook removed, false otherwise.
|
||||
# @see https://developer.github.com/v3/orgs/hooks/#delete-a-hook
|
||||
# @example
|
||||
# @client.remove_org_hook('octokit', 1000000)
|
||||
def remove_org_hook(org, id, options = {})
|
||||
boolean_from_response :delete, "#{Organization.path org}/hooks/#{id}", options
|
||||
end
|
||||
|
||||
# Parse payload string
|
||||
#
|
||||
# @param payload_string [String] The payload
|
||||
# @return [Sawyer::Resource] The payload object
|
||||
# @see https://developer.github.com/v3/activity/events/types/
|
||||
def parse_payload(payload_string)
|
||||
payload_hash = agent.class.decode payload_string
|
||||
Sawyer::Resource.new agent, payload_hash
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,367 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Issues API
|
||||
#
|
||||
# @see https://developer.github.com/v3/issues/
|
||||
module Issues
|
||||
# List issues for the authenticated user or repository
|
||||
#
|
||||
# @param repository [Integer, String, Repository, Hash] A GitHub repository.
|
||||
# @param options [Sawyer::Resource] A customizable set of options.
|
||||
# @option options [Integer] :milestone Milestone number.
|
||||
# @option options [String] :state (open) State: <tt>open</tt>, <tt>closed</tt>, or <tt>all</tt>.
|
||||
# @option options [String] :assignee User login.
|
||||
# @option options [String] :creator User login.
|
||||
# @option options [String] :mentioned User login.
|
||||
# @option options [String] :labels List of comma separated Label names. Example: <tt>bug,ui,@high</tt>.
|
||||
# @option options [String] :sort (created) Sort: <tt>created</tt>, <tt>updated</tt>, or <tt>comments</tt>.
|
||||
# @option options [String] :direction (desc) Direction: <tt>asc</tt> or <tt>desc</tt>.
|
||||
# @option options [Integer] :page (1) Page number.
|
||||
# @return [Array<Sawyer::Resource>] A list of issues for a repository.
|
||||
# @see https://developer.github.com/v3/issues/#list-issues-for-a-repository
|
||||
# @see https://developer.github.com/v3/issues/#list-issues
|
||||
# @example List issues for a repository
|
||||
# Octokit.list_issues("sferik/rails_admin")
|
||||
# @example List issues for the authenticated user across repositories
|
||||
# @client = Octokit::Client.new(:login => 'foo', :password => 'bar')
|
||||
# @client.list_issues
|
||||
def list_issues(repository = nil, options = {})
|
||||
path = repository ? "#{Repository.new(repository).path}/issues" : 'issues'
|
||||
paginate path, options
|
||||
end
|
||||
alias issues list_issues
|
||||
|
||||
# List all issues across owned and member repositories for the authenticated user
|
||||
#
|
||||
# @param options [Sawyer::Resource] A customizable set of options.
|
||||
# @option options [String] :filter (assigned) State: <tt>assigned</tt>, <tt>created</tt>, <tt>mentioned</tt>, <tt>subscribed</tt> or <tt>closed</tt>.
|
||||
# @option options [String] :state (open) State: <tt>open</tt>, <tt>closed</tt>, or <tt>all</tt>.
|
||||
# @option options [Array<String>] :labels List of Label names. Example: <tt>['bug', 'ui', '@high']</tt>.
|
||||
# @option options [String] :sort (created) Sort: <tt>created</tt>, <tt>updated</tt>, or <tt>comments</tt>.
|
||||
# @option options [String] :direction (desc) Direction: <tt>asc</tt> or <tt>desc</tt>.
|
||||
# @option options [Integer] :page (1) Page number.
|
||||
# @option options [String] :since Timestamp in ISO 8601
|
||||
# format: YYYY-MM-DDTHH:MM:SSZ
|
||||
# @return [Array<Sawyer::Resource>] A list of issues for a repository.
|
||||
# @see https://developer.github.com/v3/issues/#list-issues
|
||||
# @example List issues for the authenticated user across owned and member repositories
|
||||
# @client = Octokit::Client.new(:login => 'foo', :password => 'bar')
|
||||
# @client.user_issues
|
||||
def user_issues(options = {})
|
||||
paginate 'user/issues', options
|
||||
end
|
||||
|
||||
# List all issues for a given organization for the authenticated user
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @param options [Sawyer::Resource] A customizable set of options.
|
||||
# @option options [String] :filter (assigned) State: <tt>assigned</tt>, <tt>created</tt>, <tt>mentioned</tt>, <tt>subscribed</tt> or <tt>closed</tt>.
|
||||
# @option options [String] :state (open) State: <tt>open</tt>, <tt>closed</tt>, or <tt>all</tt>.
|
||||
# @option options [Array<String>] :labels List of Label names. Example: <tt>['bug', 'ui', '@high']</tt>.
|
||||
# @option options [String] :sort (created) Sort: <tt>created</tt>, <tt>updated</tt>, or <tt>comments</tt>.
|
||||
# @option options [String] :direction (desc) Direction: <tt>asc</tt> or <tt>desc</tt>.
|
||||
# @option options [Integer] :page (1) Page number.
|
||||
# @option options [String] :since Timestamp in ISO 8601
|
||||
# format: YYYY-MM-DDTHH:MM:SSZ
|
||||
# @return [Array<Sawyer::Resource>] A list of issues.
|
||||
# @see https://developer.github.com/v3/issues/#list-issues
|
||||
# @example List all issues for a given organization for the authenticated user
|
||||
# @client = Octokit::Client.new(:login => 'foo', :password => 'bar')
|
||||
# @client.org_issues("octokit")
|
||||
def org_issues(org, options = {})
|
||||
paginate "#{Organization.path org}/issues", options
|
||||
end
|
||||
|
||||
# Create an issue for a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param title [String] A descriptive title
|
||||
# @param body [String] An optional concise description
|
||||
# @param options [Hash] A customizable set of options.
|
||||
# @option options [String] :assignee User login.
|
||||
# @option options [Array<String>] :assignees User login.
|
||||
# @option options [Integer] :milestone Milestone number.
|
||||
# @option options [String] :labels List of comma separated Label names. Example: <tt>bug,ui,@high</tt>.
|
||||
# @return [Sawyer::Resource] Your newly created issue
|
||||
# @see https://developer.github.com/v3/issues/#create-an-issue
|
||||
# @example Create a new Issues for a repository
|
||||
# Octokit.create_issue("sferik/rails_admin", 'Updated Docs', 'Added some extra links')
|
||||
def create_issue(repo, title, body = nil, options = {})
|
||||
options[:labels] = case options[:labels]
|
||||
when String
|
||||
options[:labels].split(',').map(&:strip)
|
||||
when Array
|
||||
options[:labels]
|
||||
else
|
||||
[]
|
||||
end
|
||||
parameters = { title: title }
|
||||
parameters[:body] = body unless body.nil?
|
||||
post "#{Repository.path repo}/issues", options.merge(parameters)
|
||||
end
|
||||
alias open_issue create_issue
|
||||
|
||||
# Get a single issue from a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param number [Integer] Number ID of the issue
|
||||
# @return [Sawyer::Resource] The issue you requested, if it exists
|
||||
# @see https://developer.github.com/v3/issues/#get-a-single-issue
|
||||
# @example Get issue #25 from octokit/octokit.rb
|
||||
# Octokit.issue("octokit/octokit.rb", "25")
|
||||
def issue(repo, number, options = {})
|
||||
get "#{Repository.path repo}/issues/#{number}", options
|
||||
end
|
||||
|
||||
# Close an issue
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param number [Integer] Number ID of the issue
|
||||
# @param options [Hash] A customizable set of options.
|
||||
# @option options [String] :assignee User login.
|
||||
# @option options [Array<String>] :assignees User login.
|
||||
# @option options [Integer] :milestone Milestone number.
|
||||
# @option options [Array<String>] :labels List of Label names. Example: <tt>['bug', 'ui', '@high']</tt>.
|
||||
# @return [Sawyer::Resource] The updated Issue
|
||||
# @see https://developer.github.com/v3/issues/#edit-an-issue
|
||||
# @example Close Issue #25 from octokit/octokit.rb
|
||||
# Octokit.close_issue("octokit/octokit.rb", "25")
|
||||
def close_issue(repo, number, options = {})
|
||||
patch "#{Repository.path repo}/issues/#{number}", options.merge({ state: 'closed' })
|
||||
end
|
||||
|
||||
# Reopen an issue
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param number [Integer] Number ID of the issue
|
||||
# @param options [Hash] A customizable set of options.
|
||||
# @option options [String] :assignee User login.
|
||||
# @option options [Array<String>] :assignees User login.
|
||||
# @option options [Integer] :milestone Milestone number.
|
||||
# @option options [Array<String>] :labels List of Label names. Example: <tt>['bug', 'ui', '@high']</tt>.
|
||||
# @return [Sawyer::Resource] The updated Issue
|
||||
# @see https://developer.github.com/v3/issues/#edit-an-issue
|
||||
# @example Reopen Issue #25 from octokit/octokit.rb
|
||||
# Octokit.reopen_issue("octokit/octokit.rb", "25")
|
||||
def reopen_issue(repo, number, options = {})
|
||||
patch "#{Repository.path repo}/issues/#{number}", options.merge({ state: 'open' })
|
||||
end
|
||||
|
||||
# Lock an issue's conversation, limiting it to collaborators
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param number [Integer] Number ID of the issue
|
||||
# @return [Boolean] Success
|
||||
# @see https://developer.github.com/v3/issues/#lock-an-issue
|
||||
# @example Lock Issue #25 from octokit/octokit.rb
|
||||
# Octokit.lock_issue("octokit/octokit.rb", "25")
|
||||
def lock_issue(repo, number, options = {})
|
||||
boolean_from_response :put, "#{Repository.path repo}/issues/#{number}/lock", options
|
||||
end
|
||||
|
||||
# Unlock an issue's conversation, opening it to all viewers
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param number [Integer] Number ID of the issue
|
||||
# @return [Boolean] Success
|
||||
# @see https://developer.github.com/v3/issues/#unlock-an-issue
|
||||
# @example Unlock Issue #25 from octokit/octokit.rb
|
||||
# Octokit.close_issue("octokit/octokit.rb", "25")
|
||||
def unlock_issue(repo, number, options = {})
|
||||
boolean_from_response :delete, "#{Repository.path repo}/issues/#{number}/lock", options
|
||||
end
|
||||
|
||||
# Update an issue
|
||||
#
|
||||
# @overload update_issue(repo, number, title, body, options)
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param number [Integer] Number ID of the issue
|
||||
# @param title [String] Updated title for the issue
|
||||
# @param body [String] Updated body of the issue
|
||||
# @param options [Hash] A customizable set of options.
|
||||
# @option options [String] :assignee User login.
|
||||
# @option options [Array<String>] :assignees User login.
|
||||
# @option options [Integer] :milestone Milestone number.
|
||||
# @option options [String] :labels List of comma separated Label names. Example: <tt>bug,ui,@high</tt>.
|
||||
# @option options [String] :state State of the issue. <tt>open</tt> or <tt>closed</tt>
|
||||
#
|
||||
# @overload update_issue(repo, number, options)
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param number [Integer] Number ID of the issue
|
||||
# @param options [Hash] A customizable set of options.
|
||||
# @option options [String] :title Updated title for the issue
|
||||
# @option options [String] :body Updated body of the issue
|
||||
# @option options [String] :assignee User login.
|
||||
# @option options [Array<String>] :assignees User login.
|
||||
# @option options [Integer] :milestone Milestone number.
|
||||
# @option options [Array<String>] :labels List of Label names. Example: <tt>['bug', 'ui', '@high']</tt>.
|
||||
# @option options [String] :state State of the issue. <tt>open</tt> or <tt>closed</tt>
|
||||
# @return [Sawyer::Resource] The updated Issue
|
||||
# @see https://developer.github.com/v3/issues/#edit-an-issue
|
||||
#
|
||||
# @example Change the title of Issue #25
|
||||
# Octokit.update_issue("octokit/octokit.rb", "25", "A new title", "the same body")
|
||||
#
|
||||
# @example Change only the assignee of Issue #25
|
||||
# Octokit.update_issue("octokit/octokit.rb", "25", :assignee => "pengwynn")
|
||||
def update_issue(repo, number, *args)
|
||||
arguments = Arguments.new(args)
|
||||
opts = arguments.options
|
||||
|
||||
unless arguments.empty?
|
||||
opts[:title] = arguments.shift
|
||||
opts[:body] = arguments.shift
|
||||
end
|
||||
|
||||
patch "#{Repository.path repo}/issues/#{number}", opts
|
||||
end
|
||||
|
||||
# Get all comments attached to issues for the repository
|
||||
#
|
||||
# By default, Issue Comments are ordered by ascending ID.
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param options [Hash] Optional parameters
|
||||
# @option options [String] :sort created or updated
|
||||
# @option options [String] :direction asc or desc. Ignored without sort
|
||||
# parameter.
|
||||
# @option options [String] :since Timestamp in ISO 8601
|
||||
# format: YYYY-MM-DDTHH:MM:SSZ
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] List of issues comments.
|
||||
#
|
||||
# @see https://developer.github.com/v3/issues/comments/#list-comments-in-a-repository
|
||||
#
|
||||
# @example Get the comments for issues in the octokit repository
|
||||
# @client.issues_comments("octokit/octokit.rb")
|
||||
#
|
||||
# @example Get issues comments, sort by updated descending since a time
|
||||
# @client.issues_comments("octokit/octokit.rb", {
|
||||
# :sort => 'desc',
|
||||
# :direction => 'asc',
|
||||
# :since => '2010-05-04T23:45:02Z'
|
||||
# })
|
||||
def issues_comments(repo, options = {})
|
||||
paginate "#{Repository.path repo}/issues/comments", options
|
||||
end
|
||||
|
||||
# Get all comments attached to an issue
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param number [Integer] Number ID of the issue
|
||||
# @return [Array<Sawyer::Resource>] Array of comments that belong to an issue
|
||||
# @see https://developer.github.com/v3/issues/comments/#list-comments-on-an-issue
|
||||
# @example Get comments for issue #25 from octokit/octokit.rb
|
||||
# Octokit.issue_comments("octokit/octokit.rb", "25")
|
||||
def issue_comments(repo, number, options = {})
|
||||
paginate "#{Repository.path repo}/issues/#{number}/comments", options
|
||||
end
|
||||
|
||||
# Get a single comment attached to an issue
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param number [Integer] Number ID of the comment
|
||||
# @return [Sawyer::Resource] The specific comment in question
|
||||
# @see https://developer.github.com/v3/issues/comments/#get-a-single-comment
|
||||
# @example Get comment #1194549 from an issue on octokit/octokit.rb
|
||||
# Octokit.issue_comment("octokit/octokit.rb", 1194549)
|
||||
def issue_comment(repo, number, options = {})
|
||||
paginate "#{Repository.path repo}/issues/comments/#{number}", options
|
||||
end
|
||||
|
||||
# Add a comment to an issue
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param number [Integer] Issue number
|
||||
# @param comment [String] Comment to be added
|
||||
# @return [Sawyer::Resource] Comment
|
||||
# @see https://developer.github.com/v3/issues/comments/#create-a-comment
|
||||
# @example Add the comment "Almost to v1" to Issue #23 on octokit/octokit.rb
|
||||
# Octokit.add_comment("octokit/octokit.rb", 23, "Almost to v1")
|
||||
def add_comment(repo, number, comment, options = {})
|
||||
post "#{Repository.path repo}/issues/#{number}/comments", options.merge({ body: comment })
|
||||
end
|
||||
|
||||
# Update a single comment on an issue
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param number [Integer] Comment number
|
||||
# @param comment [String] Body of the comment which will replace the existing body.
|
||||
# @return [Sawyer::Resource] Comment
|
||||
# @see https://developer.github.com/v3/issues/comments/#edit-a-comment
|
||||
# @example Update the comment #1194549 with body "I've started this on my 25-issue-comments-v3 fork" on an issue on octokit/octokit.rb
|
||||
# Octokit.update_comment("octokit/octokit.rb", 1194549, "Almost to v1, added this on my fork")
|
||||
def update_comment(repo, number, comment, options = {})
|
||||
patch "#{Repository.path repo}/issues/comments/#{number}", options.merge({ body: comment })
|
||||
end
|
||||
|
||||
# Delete a single comment
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param number [Integer] Comment number
|
||||
# @return [Boolean] Success
|
||||
# @see https://developer.github.com/v3/issues/comments/#delete-a-comment
|
||||
# @example Delete the comment #1194549 on an issue on octokit/octokit.rb
|
||||
# Octokit.delete_comment("octokit/octokit.rb", 1194549)
|
||||
def delete_comment(repo, number, options = {})
|
||||
boolean_from_response :delete, "#{Repository.path repo}/issues/comments/#{number}", options
|
||||
end
|
||||
|
||||
# Get the timeline for an issue
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param number [Integer] Number ID of the comment
|
||||
# @return [Sawyer::Resource] The timeline for this issue
|
||||
# @see https://developer.github.com/v3/issues/timeline/
|
||||
# @example Get timeline for issue #1435 on octokit/octokit.rb
|
||||
# Octokit.issue_timeline("octokit/octokit.rb", 1435)
|
||||
def issue_timeline(repo, number, options = {})
|
||||
paginate "#{Repository.path repo}/issues/#{number}/timeline", options
|
||||
end
|
||||
|
||||
# Lists the available assignees for issues in a repository.
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @return [Array<Sawyer::Resource>] List of GitHub users.
|
||||
# @see https://developer.github.com/v3/issues/assignees/#list-assignees
|
||||
# @example Get available assignees on repository octokit/octokit.rb
|
||||
# Octokit.list_assignees("octokit/octokit.rb")
|
||||
def list_assignees(repo, options = {})
|
||||
paginate "#{Repository.path repo}/assignees", options
|
||||
end
|
||||
|
||||
# Add assignees to an issue
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param number [Integer] Issue number
|
||||
# @param assignees [Array<String>] Assignees to be added
|
||||
# @return [Sawyer::Resource] Issue
|
||||
# @see https://developer.github.com/v3/issues/assignees/#add-assignees-to-an-issue
|
||||
# @example Add assignees "pengwynn" and "joeyw" to Issue #23 on octokit/octokit.rb
|
||||
# Octokit.add_assignees("octokit/octokit.rb", 23, ["pengwynn", "joeyw"])
|
||||
def add_assignees(repo, number, assignees, options = {})
|
||||
post "#{Repository.path repo}/issues/#{number}/assignees", options.merge({ assignees: assignees })
|
||||
end
|
||||
|
||||
# Remove assignees from an issue
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param number [Integer] Issue number
|
||||
# @param assignees [Array<String>] Assignees to be removed
|
||||
# @param options [Hash] Header params for request
|
||||
# @return [Sawyer::Resource] Issue
|
||||
# @see https://developer.github.com/v3/issues/assignees/#remove-assignees-from-an-issue
|
||||
# @example Remove assignees "pengwynn" and "joeyw" from Issue #23 on octokit/octokit.rb
|
||||
# Octokit.remove_assignees("octokit/octokit.rb", 23, ["pengwynn", "joeyw"])
|
||||
#
|
||||
# @example Remove assignees "pengwynn" from Issue #23 on octokit/octokit.rb
|
||||
# Octokit.remove_assignees("octokit/octokit.rb", 23, ["pengwynn"],
|
||||
# :accept => "application/vnd.github.v3+json")
|
||||
def remove_assignees(repo, number, assignees, options = {})
|
||||
delete "#{Repository.path repo}/issues/#{number}/assignees", options.merge({ assignees: assignees })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,156 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'erb'
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Issue Labels API
|
||||
#
|
||||
# @see https://developer.github.com/v3/issues/labels/
|
||||
module Labels
|
||||
# List available labels for a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @return [Array<Sawyer::Resource>] A list of the labels across the repository
|
||||
# @see https://developer.github.com/v3/issues/labels/#list-all-labels-for-this-repository
|
||||
# @example List labels for octokit/octokit.rb
|
||||
# Octokit.labels("octokit/octokit.rb")
|
||||
def labels(repo, options = {})
|
||||
paginate "#{Repository.path repo}/labels", options
|
||||
end
|
||||
|
||||
# Get single label for a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param name [String] Name of the label
|
||||
# @return [Sawyer::Resource] A single label from the repository
|
||||
# @see https://developer.github.com/v3/issues/labels/#get-a-single-label
|
||||
# @example Get the "V3 Addition" label from octokit/octokit.rb
|
||||
# Octokit.label("octokit/octokit.rb", "V3 Addition")
|
||||
def label(repo, name, options = {})
|
||||
get "#{Repository.path repo}/labels/#{ERB::Util.url_encode(name)}", options
|
||||
end
|
||||
|
||||
# Add a label to a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param label [String] A new label
|
||||
# @param color [String] A color, in hex, without the leading #
|
||||
# @return [Sawyer::Resource] The new label
|
||||
# @see https://developer.github.com/v3/issues/labels/#create-a-label
|
||||
# @example Add a new label "Version 1.0" with color "#cccccc"
|
||||
# Octokit.add_label("octokit/octokit.rb", "Version 1.0", "cccccc")
|
||||
def add_label(repo, label, color = 'ffffff', options = {})
|
||||
post "#{Repository.path repo}/labels", options.merge({ name: label, color: color })
|
||||
end
|
||||
|
||||
# Update a label
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param label [String] The name of the label which will be updated
|
||||
# @param options [Hash] A customizable set of options.
|
||||
# @option options [String] :name An updated label name
|
||||
# @option options [String] :color An updated color value, in hex, without leading #
|
||||
# @return [Sawyer::Resource] The updated label
|
||||
# @see https://developer.github.com/v3/issues/labels/#update-a-label
|
||||
# @example Update the label "Version 1.0" with new color "#cceeaa"
|
||||
# Octokit.update_label("octokit/octokit.rb", "Version 1.0", {:color => "cceeaa"})
|
||||
def update_label(repo, label, options = {})
|
||||
patch "#{Repository.path repo}/labels/#{ERB::Util.url_encode(label)}", options
|
||||
end
|
||||
|
||||
# Delete a label from a repository.
|
||||
#
|
||||
# This deletes the label from the repository, and removes it from all issues.
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param label [String] String name of the label
|
||||
# @return [Boolean] Success
|
||||
# @see https://developer.github.com/v3/issues/labels/#delete-a-label
|
||||
# @example Delete the label "Version 1.0" from the repository.
|
||||
# Octokit.delete_label!("octokit/octokit.rb", "Version 1.0")
|
||||
def delete_label!(repo, label, options = {})
|
||||
boolean_from_response :delete, "#{Repository.path repo}/labels/#{ERB::Util.url_encode(label)}", options
|
||||
end
|
||||
|
||||
# Remove a label from an Issue
|
||||
#
|
||||
# This removes the label from the Issue
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param number [Integer] Number ID of the issue
|
||||
# @param label [String] String name of the label
|
||||
# @return [Array<Sawyer::Resource>] A list of the labels currently on the issue
|
||||
# @see https://developer.github.com/v3/issues/labels/#remove-a-label-from-an-issue
|
||||
# @example Remove the label "Version 1.0" from the repository.
|
||||
# Octokit.remove_label("octokit/octokit.rb", 23, "Version 1.0")
|
||||
def remove_label(repo, number, label, options = {})
|
||||
delete "#{Repository.path repo}/issues/#{number}/labels/#{ERB::Util.url_encode(label)}", options
|
||||
end
|
||||
|
||||
# Remove all label from an Issue
|
||||
#
|
||||
# This removes the label from the Issue
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param number [Integer] Number ID of the issue
|
||||
# @return [Boolean] Success of operation
|
||||
# @see https://developer.github.com/v3/issues/labels/#remove-all-labels-from-an-issue
|
||||
# @example Remove all labels from Issue #23
|
||||
# Octokit.remove_all_labels("octokit/octokit.rb", 23)
|
||||
def remove_all_labels(repo, number, options = {})
|
||||
boolean_from_response :delete, "#{Repository.path repo}/issues/#{number}/labels", options
|
||||
end
|
||||
|
||||
# List labels for a given issue
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param number [Integer] Number ID of the issue
|
||||
# @return [Array<Sawyer::Resource>] A list of the labels currently on the issue
|
||||
# @see https://developer.github.com/v3/issues/labels/#list-labels-on-an-issue
|
||||
# @example List labels for octokit/octokit.rb, issue # 1
|
||||
# Octokit.labels_for_issue("octokit/octokit.rb", 1)
|
||||
def labels_for_issue(repo, number, options = {})
|
||||
paginate "#{Repository.path repo}/issues/#{number}/labels", options
|
||||
end
|
||||
|
||||
# Add label(s) to an Issue
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A Github repository
|
||||
# @param number [Integer] Number ID of the issue
|
||||
# @param labels [Array] An array of labels to apply to this Issue
|
||||
# @return [Array<Sawyer::Resource>] A list of the labels currently on the issue
|
||||
# @see https://developer.github.com/v3/issues/labels/#add-labels-to-an-issue
|
||||
# @example Add two labels for octokit/octokit.rb
|
||||
# Octokit.add_labels_to_an_issue("octokit/octokit.rb", 10, ['V3 Transition', 'Improvement'])
|
||||
def add_labels_to_an_issue(repo, number, labels)
|
||||
post "#{Repository.path repo}/issues/#{number}/labels", labels
|
||||
end
|
||||
|
||||
# Replace all labels on an Issue
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A Github repository
|
||||
# @param number [Integer] Number ID of the issue
|
||||
# @param labels [Array] An array of labels to use as replacement
|
||||
# @return [Array<Sawyer::Resource>] A list of the labels currently on the issue
|
||||
# @see https://developer.github.com/v3/issues/labels/#replace-all-labels-for-an-issue
|
||||
# @example Replace labels for octokit/octokit.rb Issue #10
|
||||
# Octokit.replace_all_labels("octokit/octokit.rb", 10, ['V3 Transition', 'Improvement'])
|
||||
def replace_all_labels(repo, number, labels, _options = {})
|
||||
put "#{Repository.path repo}/issues/#{number}/labels", labels
|
||||
end
|
||||
|
||||
# Get labels for every issue in a milestone
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param number [Integer] Number ID of the milestone
|
||||
# @return [Array<Sawyer::Resource>] A list of the labels across the milestone
|
||||
# @see http://developer.github.com/v3/issues/labels/#get-labels-for-every-issue-in-a-milestone
|
||||
# @example List all labels for milestone #2 on octokit/octokit.rb
|
||||
# Octokit.labels_for_milestone("octokit/octokit.rb", 2)
|
||||
def labels_for_milestone(repo, number, options = {})
|
||||
paginate "#{Repository.path repo}/milestones/#{number}/labels", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,42 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Legacy Search API
|
||||
#
|
||||
# @see https://developer.github.com/v3/search/
|
||||
module LegacySearch
|
||||
# Legacy repository search
|
||||
#
|
||||
# @see https://developer.github.com/v3/search/#search-repositories
|
||||
# @param q [String] Search keyword
|
||||
# @return [Array<Sawyer::Resource>] List of repositories found
|
||||
def legacy_search_repositories(q, options = {})
|
||||
get("legacy/repos/search/#{q}", options)['repositories']
|
||||
end
|
||||
|
||||
# Legacy search issues within a repository
|
||||
#
|
||||
# @param repo [String, Repository, Hash] A GitHub repository
|
||||
# @param search_term [String] The term to search for
|
||||
# @param state [String] :state (open) <tt>open</tt> or <tt>closed</tt>.
|
||||
# @return [Array<Sawyer::Resource>] A list of issues matching the search term and state
|
||||
# @example Search for 'test' in the open issues for sferik/rails_admin
|
||||
# Octokit.search_issues("sferik/rails_admin", 'test', 'open')
|
||||
def legacy_search_issues(repo, search_term, state = 'open', options = {})
|
||||
get("legacy/issues/search/#{Repository.new(repo)}/#{state}/#{search_term}", options)['issues']
|
||||
end
|
||||
|
||||
# Search for user.
|
||||
#
|
||||
# @param search [String] User to search for.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing users.
|
||||
# @see https://developer.github.com/v3/search/#search-users
|
||||
# @example
|
||||
# Octokit.search_users('pengwynn')
|
||||
def legacy_search_users(search, options = {})
|
||||
get("legacy/user/search/#{search}", options)['users']
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,42 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for licenses API
|
||||
#
|
||||
module Licenses
|
||||
# List all licenses
|
||||
#
|
||||
# @see https://developer.github.com/v3/licenses/#list-all-licenses
|
||||
# @return [Array<Sawyer::Resource>] A list of licenses
|
||||
# @example
|
||||
# Octokit.licenses
|
||||
def licenses(options = {})
|
||||
paginate 'licenses', options
|
||||
end
|
||||
|
||||
# List an individual license
|
||||
#
|
||||
# @see https://developer.github.com/v3/licenses/#get-an-individual-license
|
||||
# @param license_name [String] The license name
|
||||
# @return <Sawyer::Resource> An individual license
|
||||
# @example
|
||||
# Octokit.license 'mit'
|
||||
def license(license_name, options = {})
|
||||
get "licenses/#{license_name}", options
|
||||
end
|
||||
|
||||
# Returns the contents of the repository’s license file, if one is detected.
|
||||
#
|
||||
# @see https://developer.github.com/v3/licenses/#get-the-contents-of-a-repositorys-license
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @option options [String] :ref name of the Commit/Branch/Tag. Defaults to 'master'.
|
||||
# @return [Sawyer::Resource] The detail of the license file
|
||||
# @example
|
||||
# Octokit.repository_license_contents 'benbalter/licensee'
|
||||
def repository_license_contents(repo, options = {})
|
||||
get "#{Repository.path repo}/license", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,27 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Markdown API
|
||||
#
|
||||
# @see https://developer.github.com/v3/markdown/
|
||||
module Markdown
|
||||
# Render an arbitrary Markdown document
|
||||
#
|
||||
# @param text [String] Markdown source
|
||||
# @option options [String] (optional) :mode (`markdown` or `gfm`)
|
||||
# @option options [String] (optional) :context Repo context
|
||||
# @return [String] HTML renderization
|
||||
# @see https://developer.github.com/v3/markdown/#render-an-arbitrary-markdown-document
|
||||
# @example Render some GFM
|
||||
# Octokit.markdown('Fixed in #111', :mode => "gfm", :context => "octokit/octokit.rb")
|
||||
def markdown(text, options = {})
|
||||
options[:text] = text
|
||||
options[:repo] = Repository.new(options[:repo]) if options[:repo]
|
||||
options[:accept] = 'application/vnd.github.raw'
|
||||
|
||||
post 'markdown', options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,56 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Marketplace Listing API
|
||||
#
|
||||
# @see https://developer.github.com/v3/apps/marketplace/
|
||||
module Marketplace
|
||||
# List all plans for an app's marketplace listing
|
||||
#
|
||||
# @param options [Hash] A customizable set of options
|
||||
#
|
||||
# @see https://developer.github.com/v3/apps/marketplace/#list-all-plans-for-your-marketplace-listing
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] A list of plans
|
||||
def list_plans(options = {})
|
||||
paginate '/marketplace_listing/plans', options
|
||||
end
|
||||
|
||||
# List all GitHub accounts on a specific plan
|
||||
#
|
||||
# @param plan_id [Integer] The id of the GitHub plan
|
||||
# @param options [Hash] A customizable set of options
|
||||
#
|
||||
# @see https://developer.github.com/v3/apps/marketplace/#list-all-github-accounts-user-or-organization-on-a-specific-plan
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] A list of accounts
|
||||
def list_accounts_for_plan(plan_id, options = {})
|
||||
paginate "/marketplace_listing/plans/#{plan_id}/accounts", options
|
||||
end
|
||||
|
||||
# Get the plan associated with a given GitHub account
|
||||
#
|
||||
# @param account_id [Integer] The id of the GitHub account
|
||||
# @param options [Hash] A customizable set of options
|
||||
#
|
||||
# @see https://developer.github.com/v3/apps/marketplace/#check-if-a-github-account-is-associated-with-any-marketplace-listing
|
||||
#
|
||||
# @return <Sawyer::Resource> Account with plan details, or nil
|
||||
def plan_for_account(account_id, options = {})
|
||||
get "/marketplace_listing/accounts/#{account_id}", options
|
||||
end
|
||||
|
||||
# Get user's Marketplace purchases
|
||||
#
|
||||
# @param options [Hash] A customizable set of options
|
||||
#
|
||||
# @see https://developer.github.com/v3/apps/marketplace/#get-a-users-marketplace-purchases
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] A list of Marketplace purchases
|
||||
def marketplace_purchases(options = {})
|
||||
get '/user/marketplace_purchases', options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,20 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Meta API
|
||||
#
|
||||
# @see https://developer.github.com/v3/meta/
|
||||
module Meta
|
||||
# Get meta information about GitHub.com, the service.
|
||||
# @see https://developer.github.com/v3/meta/#meta
|
||||
# @return [Sawyer::Resource] Hash with meta information.
|
||||
# @example Get GitHub meta information
|
||||
# @client.github_meta
|
||||
def meta(options = {})
|
||||
get 'meta', options
|
||||
end
|
||||
alias github_meta meta
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,87 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Issues Milestones API
|
||||
#
|
||||
# @see https://developer.github.com/v3/issues/milestones/
|
||||
module Milestones
|
||||
# List milestones for a repository
|
||||
#
|
||||
# @param repository [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param options [Hash] A customizable set of options.
|
||||
# @option options [Integer] :milestone Milestone number.
|
||||
# @option options [String] :state (open) State: <tt>open</tt>, <tt>closed</tt>, or <tt>all</tt>.
|
||||
# @option options [String] :sort (created) Sort: <tt>created</tt>, <tt>updated</tt>, or <tt>comments</tt>.
|
||||
# @option options [String] :direction (desc) Direction: <tt>asc</tt> or <tt>desc</tt>.
|
||||
# @return [Array<Sawyer::Resource>] A list of milestones for a repository.
|
||||
# @see https://developer.github.com/v3/issues/milestones/#list-milestones-for-a-repository
|
||||
# @example List milestones for a repository
|
||||
# Octokit.list_milestones("octokit/octokit.rb")
|
||||
def list_milestones(repository, options = {})
|
||||
paginate "#{Repository.path repository}/milestones", options
|
||||
end
|
||||
alias milestones list_milestones
|
||||
|
||||
# Get a single milestone for a repository
|
||||
#
|
||||
# @param repository [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param options [Hash] A customizable set of options.
|
||||
# @option options [Integer] :milestone Milestone number.
|
||||
# @return [Sawyer::Resource] A single milestone from a repository.
|
||||
# @see https://developer.github.com/v3/issues/milestones/#get-a-single-milestone
|
||||
# @example Get a single milestone for a repository
|
||||
# Octokit.milestone("octokit/octokit.rb", 1)
|
||||
def milestone(repository, number, options = {})
|
||||
get "#{Repository.path repository}/milestones/#{number}", options
|
||||
end
|
||||
|
||||
# Create a milestone for a repository
|
||||
#
|
||||
# @param repository [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param title [String] A unique title.
|
||||
# @param options [Hash] A customizable set of options.
|
||||
# @option options [String] :state (open) State: <tt>open</tt> or <tt>closed</tt>.
|
||||
# @option options [String] :description A meaningful description
|
||||
# @option options [Time] :due_on Set if the milestone has a due date
|
||||
# @return [Sawyer::Resource] A single milestone object
|
||||
# @see https://developer.github.com/v3/issues/milestones/#create-a-milestone
|
||||
# @example Create a milestone for a repository
|
||||
# Octokit.create_milestone("octokit/octokit.rb", "0.7.0", {:description => 'Add support for v3 of Github API'})
|
||||
def create_milestone(repository, title, options = {})
|
||||
post "#{Repository.path repository}/milestones", options.merge({ title: title })
|
||||
end
|
||||
|
||||
# Update a milestone for a repository
|
||||
#
|
||||
# @param repository [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param number [String, Integer] ID of the milestone
|
||||
# @param options [Hash] A customizable set of options.
|
||||
# @option options [String] :title A unique title.
|
||||
# @option options [String] :state (open) State: <tt>open</tt> or <tt>closed</tt>.
|
||||
# @option options [String] :description A meaningful description
|
||||
# @option options [Time] :due_on Set if the milestone has a due date
|
||||
# @return [Sawyer::Resource] A single milestone object
|
||||
# @see https://developer.github.com/v3/issues/milestones/#update-a-milestone
|
||||
# @example Update a milestone for a repository
|
||||
# Octokit.update_milestone("octokit/octokit.rb", 1, {:description => 'Add support for v3 of Github API'})
|
||||
def update_milestone(repository, number, options = {})
|
||||
patch "#{Repository.path repository}/milestones/#{number}", options
|
||||
end
|
||||
alias edit_milestone update_milestone
|
||||
|
||||
# Delete a single milestone for a repository
|
||||
#
|
||||
# @param repository [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param options [Hash] A customizable set of options.
|
||||
# @option options [Integer] :milestone Milestone number.
|
||||
# @return [Boolean] Success
|
||||
# @see https://developer.github.com/v3/issues/milestones/#delete-a-milestone
|
||||
# @example Delete a single milestone from a repository
|
||||
# Octokit.delete_milestone("octokit/octokit.rb", 1)
|
||||
def delete_milestone(repository, number, options = {})
|
||||
boolean_from_response :delete, "#{Repository.path repository}/milestones/#{number}", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,167 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Notifications API
|
||||
#
|
||||
# @see https://developer.github.com/v3/activity/notifications/
|
||||
module Notifications
|
||||
# List your notifications
|
||||
#
|
||||
# @param options [Hash] Optional parameters
|
||||
# @option options [Boolean] :all 'true' to show notifications marked as
|
||||
# read.
|
||||
# @option options [Boolean] :participating 'true' to show only
|
||||
# notifications in which the user is directly participating or
|
||||
# mentioned.
|
||||
# @option options [String] :since Time filters out any notifications
|
||||
# updated before the given time. The time should be passed in as UTC in
|
||||
# the ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ. Ex. '2012-10-09T23:39:01Z'
|
||||
# @return [Array<Sawyer::Resource>] Array of notifications.
|
||||
# @see https://developer.github.com/v3/activity/notifications/#list-your-notifications
|
||||
# @example Get users notifications
|
||||
# @client.notifications
|
||||
# @example Get all notifications since a certain time.
|
||||
# @client.notifications({all: true, since: '2012-10-09T23:39:01Z'})
|
||||
def notifications(options = {})
|
||||
paginate 'notifications', options
|
||||
end
|
||||
|
||||
# List your notifications in a repository
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param options [Hash] Optional parameters
|
||||
# @option options [Boolean] :all 'true' to show notifications marked as
|
||||
# read.
|
||||
# @option options [Boolean] :participating 'true' to show only
|
||||
# notifications in which the user is directly participating or
|
||||
# mentioned.
|
||||
# @option options [String] :since Time filters out any notifications
|
||||
# updated before the given time. The time should be passed in as UTC in
|
||||
# the ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ. Ex. '2012-10-09T23:39:01Z'
|
||||
# @return [Array<Sawyer::Resource>] Array of notifications.
|
||||
# @see https://developer.github.com/v3/activity/notifications/#list-your-notifications-in-a-repository
|
||||
# @example Get your notifications for octokit/octokit.rb
|
||||
# @client.repository_notifications('octokit/octokit.rb')
|
||||
# @example Get your notifications for octokit/octokit.rb since a time.
|
||||
# @client.repository_notifications({since: '2012-10-09T23:39:01Z'})
|
||||
def repository_notifications(repo, options = {})
|
||||
paginate "#{Repository.path repo}/notifications", options
|
||||
end
|
||||
alias repo_notifications repository_notifications
|
||||
|
||||
# Mark notifications as read
|
||||
#
|
||||
# @param options [Hash] Optional parameters
|
||||
# @option options [Boolean] :unread Changes the unread status of the
|
||||
# threads.
|
||||
# @option options [Boolean] :read Inverse of 'unread'.
|
||||
# @option options [String] :last_read_at ('Now') Describes the last point
|
||||
# that notifications were checked. Anything updated since this time
|
||||
# will not be updated. The time should be passed in as UTC in the
|
||||
# ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ. Ex. '2012-10-09T23:39:01Z'
|
||||
# @return [Boolean] True if marked as read, false otherwise
|
||||
# @see https://developer.github.com/v3/activity/notifications/#mark-as-read
|
||||
#
|
||||
# @example
|
||||
# @client.mark_notifications_as_read
|
||||
def mark_notifications_as_read(options = {})
|
||||
request :put, 'notifications', options
|
||||
|
||||
last_response.status == 205
|
||||
end
|
||||
|
||||
# Mark notifications from a specific repository as read
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param options [Hash] Optional parameters
|
||||
# @option options [Boolean] :unread Changes the unread status of the
|
||||
# threads.
|
||||
# @option options [Boolean] :read Inverse of 'unread'.
|
||||
# @option options [String] :last_read_at ('Now') Describes the last point
|
||||
# that notifications were checked. Anything updated since this time
|
||||
# will not be updated. The time should be passed in as UTC in the
|
||||
# ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ. Ex. '2012-10-09T23:39:01Z'
|
||||
# @return [Boolean] True if marked as read, false otherwise
|
||||
# @see https://developer.github.com/v3/activity/notifications/#mark-notifications-as-read-in-a-repository
|
||||
# @example
|
||||
# @client.mark_notifications_as_read("octokit/octokit.rb")
|
||||
def mark_repository_notifications_as_read(repo, options = {})
|
||||
request :put, "#{Repository.path repo}/notifications", options
|
||||
|
||||
last_response.status == 205
|
||||
end
|
||||
alias mark_repo_notifications_as_read mark_repository_notifications_as_read
|
||||
|
||||
# List notifications for a specific thread
|
||||
#
|
||||
# @param thread_id [Integer] Id of the thread.
|
||||
# @return [Array<Sawyer::Resource>] Array of notifications.
|
||||
# @see https://developer.github.com/v3/activity/notifications/#view-a-single-thread
|
||||
#
|
||||
# @example
|
||||
# @client.notification_thread(1000)
|
||||
def thread_notifications(thread_id, options = {})
|
||||
get "notifications/threads/#{thread_id}", options
|
||||
end
|
||||
|
||||
# Mark thread as read
|
||||
#
|
||||
# @param thread_id [Integer] Id of the thread to update.
|
||||
# @return [Boolean] True if updated, false otherwise.
|
||||
# @see https://developer.github.com/v3/activity/notifications/#mark-a-thread-as-read
|
||||
# @example
|
||||
# @client.mark_thread_as_read(1, :read => false)
|
||||
def mark_thread_as_read(thread_id, options = {})
|
||||
request :patch, "notifications/threads/#{thread_id}", options
|
||||
|
||||
last_response.status == 205
|
||||
end
|
||||
|
||||
# Get thread subscription
|
||||
#
|
||||
# @param thread_id [Integer] Id of the thread.
|
||||
# @return [Sawyer::Resource] Subscription.
|
||||
# @see https://developer.github.com/v3/activity/notifications/#get-a-thread-subscription
|
||||
# @example
|
||||
# @client.thread_subscription(1)
|
||||
def thread_subscription(thread_id, options = {})
|
||||
get "notifications/threads/#{thread_id}/subscription", options
|
||||
end
|
||||
|
||||
# Update thread subscription
|
||||
#
|
||||
# This lets you subscribe to a thread, or ignore it. Subscribing to a
|
||||
# thread is unnecessary if the user is already subscribed to the
|
||||
# repository. Ignoring a thread will mute all future notifications (until
|
||||
# you comment or get @mentioned).
|
||||
#
|
||||
# @param thread_id [Integer] Id of the thread.
|
||||
# @param options
|
||||
# @option options [Boolean] :subscribed Determines if notifications
|
||||
# should be received from this repository.
|
||||
# @option options [Boolean] :ignored Deterimines if all notifications
|
||||
# should be blocked from this repository.
|
||||
# @return [Sawyer::Resource] Updated subscription.
|
||||
# @see https://developer.github.com/v3/activity/notifications/#set-a-thread-subscription
|
||||
# @example Subscribe to notifications
|
||||
# @client.update_thread_subscription(1, :subscribed => true)
|
||||
# @example Ignore notifications from a repo
|
||||
# @client.update_thread_subscription(1, :ignored => true)
|
||||
def update_thread_subscription(thread_id, options = {})
|
||||
put "notifications/threads/#{thread_id}/subscription", options
|
||||
end
|
||||
|
||||
# Delete a thread subscription
|
||||
#
|
||||
# @param thread_id [Integer] Id of the thread.
|
||||
# @return [Boolean] True if delete successful, false otherwise.
|
||||
# @see https://developer.github.com/v3/activity/notifications/#delete-a-thread-subscription
|
||||
# @example
|
||||
# @client.delete_thread_subscription(1)
|
||||
def delete_thread_subscription(thread_id, options = {})
|
||||
boolean_from_response :delete, "notifications/threads/#{thread_id}/subscription", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,116 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the OauthApplications API
|
||||
#
|
||||
# @see https://developer.github.com/v3/apps/oauth_applications
|
||||
module OauthApplications
|
||||
# Check if a token is valid.
|
||||
#
|
||||
# Applications can check if a token is valid without rate limits.
|
||||
#
|
||||
# @param access_token [String] 40 character GitHub OAuth access token
|
||||
#
|
||||
# @return [Sawyer::Resource] A single authorization for the authenticated user
|
||||
# @see https://developer.github.com/v3/apps/oauth_applications/#check-a-token
|
||||
#
|
||||
# @example
|
||||
# client = Octokit::Client.new(:client_id => 'abcdefg12345', :client_secret => 'secret')
|
||||
# client.check_token('deadbeef1234567890deadbeef987654321')
|
||||
def check_token(access_token, options = {})
|
||||
options[:access_token] = access_token
|
||||
|
||||
key = options.delete(:client_id) || client_id
|
||||
secret = options.delete(:client_secret) || client_secret
|
||||
|
||||
as_app(key, secret) do |app_client|
|
||||
app_client.post "applications/#{client_id}/token", options
|
||||
end
|
||||
end
|
||||
alias check_application_authorization check_token
|
||||
|
||||
# Reset a token
|
||||
#
|
||||
# Applications can reset a token without requiring a user to re-authorize.
|
||||
#
|
||||
# @param access_token [String] 40 character GitHub OAuth access token
|
||||
#
|
||||
# @return [Sawyer::Resource] A single authorization for the authenticated user
|
||||
# @see https://developer.github.com/v3/apps/oauth_applications/#reset-a-token
|
||||
#
|
||||
# @example
|
||||
# client = Octokit::Client.new(:client_id => 'abcdefg12345', :client_secret => 'secret')
|
||||
# client.reset_token('deadbeef1234567890deadbeef987654321')
|
||||
def reset_token(access_token, options = {})
|
||||
options[:access_token] = access_token
|
||||
|
||||
key = options.delete(:client_id) || client_id
|
||||
secret = options.delete(:client_secret) || client_secret
|
||||
|
||||
as_app(key, secret) do |app_client|
|
||||
app_client.patch "applications/#{client_id}/token", options
|
||||
end
|
||||
end
|
||||
alias reset_application_authorization reset_token
|
||||
|
||||
# Delete an app token
|
||||
#
|
||||
# Applications can revoke (delete) a token
|
||||
#
|
||||
# @param access_token [String] 40 character GitHub OAuth access token
|
||||
#
|
||||
# @return [Boolean] Result
|
||||
# @see https://developer.github.com/v3/apps/oauth_applications/#delete-an-app-token
|
||||
#
|
||||
# @example
|
||||
# client = Octokit::Client.new(:client_id => 'abcdefg12345', :client_secret => 'secret')
|
||||
# client.delete_token('deadbeef1234567890deadbeef987654321')
|
||||
def delete_app_token(access_token, options = {})
|
||||
options[:access_token] = access_token
|
||||
|
||||
key = options.delete(:client_id) || client_id
|
||||
secret = options.delete(:client_secret) || client_secret
|
||||
|
||||
begin
|
||||
as_app(key, secret) do |app_client|
|
||||
app_client.delete "applications/#{client_id}/token", options
|
||||
app_client.last_response.status == 204
|
||||
end
|
||||
rescue Octokit::NotFound
|
||||
false
|
||||
end
|
||||
end
|
||||
alias delete_application_authorization delete_app_token
|
||||
alias revoke_application_authorization delete_app_token
|
||||
|
||||
# Delete an app authorization
|
||||
#
|
||||
# OAuth application owners can revoke a grant for their OAuth application and a specific user.
|
||||
#
|
||||
# @param access_token [String] 40 character GitHub OAuth access token
|
||||
#
|
||||
# @return [Boolean] Result
|
||||
# @see https://developer.github.com/v3/apps/oauth_applications/#delete-an-app-token
|
||||
#
|
||||
# @example
|
||||
# client = Octokit::Client.new(:client_id => 'abcdefg12345', :client_secret => 'secret')
|
||||
# client.delete_app_authorization('deadbeef1234567890deadbeef987654321')
|
||||
def delete_app_authorization(access_token, options = {})
|
||||
options[:access_token] = access_token
|
||||
|
||||
key = options.delete(:client_id) || client_id
|
||||
secret = options.delete(:client_secret) || client_secret
|
||||
|
||||
begin
|
||||
as_app(key, secret) do |app_client|
|
||||
app_client.delete "applications/#{client_id}/grant", options
|
||||
app_client.last_response.status == 204
|
||||
end
|
||||
rescue Octokit::NotFound
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,141 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Git Data API
|
||||
#
|
||||
# @see https://developer.github.com/v3/git/
|
||||
module Objects
|
||||
# Get a single tree, fetching information about its root-level objects
|
||||
#
|
||||
# Pass <tt>:recursive => true</tt> in <tt>options</tt> to fetch information about all of the tree's objects, including those in subdirectories.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param tree_sha [String] The SHA of the tree to fetch
|
||||
# @return [Sawyer::Resource] A hash representing the fetched tree
|
||||
# @see https://developer.github.com/v3/git/trees/#get-a-tree
|
||||
# @see https://developer.github.com/v3/git/trees/#get-a-tree-recursively
|
||||
# @example Fetch a tree and inspect the path of one of its files
|
||||
# tree = Octokit.tree("octocat/Hello-World", "9fb037999f264ba9a7fc6274d15fa3ae2ab98312")
|
||||
# tree.tree.first.path # => "file.rb"
|
||||
# @example Fetch a tree recursively
|
||||
# tree = Octokit.tree("octocat/Hello-World", "fc6274d15fa3ae2ab983129fb037999f264ba9a7", :recursive => true)
|
||||
# tree.tree.first.path # => "subdir/file.txt"
|
||||
def tree(repo, tree_sha, options = {})
|
||||
get "#{Repository.path repo}/git/trees/#{tree_sha}", options
|
||||
end
|
||||
|
||||
# Create a tree
|
||||
#
|
||||
# Pass <tt>:base_tree => "827efc6..."</tt> in <tt>options</tt> to update an existing tree with new data.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param tree [Array] An array of hashes representing a tree structure
|
||||
# @return [Sawyer::Resource] A hash representing the new tree
|
||||
# @see https://developer.github.com/v3/git/trees/#create-a-tree
|
||||
# @example Create a tree containing one file
|
||||
# tree = Octokit.create_tree("octocat/Hello-World", [ { :path => "file.rb", :mode => "100644", :type => "blob", :sha => "44b4fc6d56897b048c772eb4087f854f46256132" } ])
|
||||
# tree.sha # => "cd8274d15fa3ae2ab983129fb037999f264ba9a7"
|
||||
# tree.tree.first.path # => "file.rb"
|
||||
def create_tree(repo, tree, options = {})
|
||||
parameters = { tree: tree }
|
||||
post "#{Repository.path repo}/git/trees", options.merge(parameters)
|
||||
end
|
||||
|
||||
# Get a single blob, fetching its content and encoding
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param blob_sha [String] The SHA of the blob to fetch
|
||||
# @return [Sawyer::Resource] A hash representing the fetched blob
|
||||
# @see https://developer.github.com/v3/git/blobs/#get-a-blob
|
||||
# @example Fetch a blob and inspect its contents
|
||||
# blob = Octokit.blob("octocat/Hello-World", "827efc6d56897b048c772eb4087f854f46256132")
|
||||
# blob.encoding # => "utf-8"
|
||||
# blob.content # => "Foo bar baz"
|
||||
# @example Fetch a base64-encoded blob and inspect its contents
|
||||
# require "base64"
|
||||
# blob = Octokit.blob("octocat/Hello-World", "827efc6d56897b048c772eb4087f854f46256132")
|
||||
# blob.encoding # => "base64"
|
||||
# blob.content # => "Rm9vIGJhciBiYXo="
|
||||
# Base64.decode64(blob.content) # => "Foo bar baz"
|
||||
def blob(repo, blob_sha, options = {})
|
||||
get "#{Repository.path repo}/git/blobs/#{blob_sha}", options
|
||||
end
|
||||
|
||||
# Create a blob
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param content [String] Content of the blob
|
||||
# @param encoding [String] The content's encoding. <tt>utf-8</tt> and <tt>base64</tt> are accepted. If your data cannot be losslessly sent as a UTF-8 string, you can base64 encode it
|
||||
# @return [String] The new blob's SHA, e.g. <tt>827efc6d56897b048c772eb4087f854f46256132</tt>
|
||||
# @see https://developer.github.com/v3/git/blobs/#create-a-blob
|
||||
# @example Create a blob containing <tt>foo bar baz</tt>
|
||||
# Octokit.create_blob("octocat/Hello-World", "foo bar baz")
|
||||
# @example Create a blob containing <tt>foo bar baz</tt>, encoded using base64
|
||||
# require "base64"
|
||||
# Octokit.create_blob("octocat/Hello-World", Base64.encode64("foo bar baz"), "base64")
|
||||
def create_blob(repo, content, encoding = 'utf-8', options = {})
|
||||
parameters = {
|
||||
content: content,
|
||||
encoding: encoding
|
||||
}
|
||||
blob = post "#{Repository.path repo}/git/blobs", options.merge(parameters)
|
||||
|
||||
blob.sha
|
||||
end
|
||||
|
||||
# Get a tag
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param tag_sha [String] The SHA of the tag to fetch.
|
||||
# @return [Sawyer::Resource] Hash representing the tag.
|
||||
# @see https://developer.github.com/v3/git/tags/#get-a-tag
|
||||
# @example Fetch a tag
|
||||
# Octokit.tag('octokit/octokit.rb', '23aad20633f4d2981b1c7209a800db3014774e96')
|
||||
def tag(repo, tag_sha, options = {})
|
||||
get "#{Repository.path repo}/git/tags/#{tag_sha}", options
|
||||
end
|
||||
|
||||
# Create a tag
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param tag [String] Tag string.
|
||||
# @param message [String] Tag message.
|
||||
# @param object_sha [String] SHA of the git object this is tagging.
|
||||
# @param type [String] Type of the object we're tagging. Normally this is
|
||||
# a `commit` but it can also be a `tree` or a `blob`.
|
||||
# @param tagger_name [String] Name of the author of the tag.
|
||||
# @param tagger_email [String] Email of the author of the tag.
|
||||
# @param tagger_date [string] Timestamp of when this object was tagged.
|
||||
# @return [Sawyer::Resource] Hash representing new tag.
|
||||
# @see https://developer.github.com/v3/git/tags/#create-a-tag-object
|
||||
# @example
|
||||
# @client.create_tag(
|
||||
# "octokit/octokit.rb",
|
||||
# "v9000.0.0",
|
||||
# "Version 9000\n",
|
||||
# "f4cdf6eb734f32343ce3f27670c17b35f54fd82e",
|
||||
# "commit",
|
||||
# "Wynn Netherland",
|
||||
# "wynn.netherland@gmail.com",
|
||||
# "2012-06-03T17:03:11-07:00"
|
||||
# )
|
||||
def create_tag(repo, tag, message, object_sha, type, tagger_name, tagger_email, tagger_date, options = {})
|
||||
options.merge!(
|
||||
tag: tag,
|
||||
message: message,
|
||||
object: object_sha,
|
||||
type: type,
|
||||
tagger: {
|
||||
name: tagger_name,
|
||||
email: tagger_email,
|
||||
date: tagger_date
|
||||
}
|
||||
)
|
||||
post "#{Repository.path repo}/git/tags", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,864 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Organizations API
|
||||
#
|
||||
# @see https://developer.github.com/v3/orgs/
|
||||
module Organizations
|
||||
# Get an organization
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @return [Sawyer::Resource] Hash representing GitHub organization.
|
||||
# @see https://developer.github.com/v3/orgs/#get-an-organization
|
||||
# @example
|
||||
# Octokit.organization('github')
|
||||
# @example
|
||||
# Octokit.org('github')
|
||||
def organization(org, options = {})
|
||||
get Organization.path(org), options
|
||||
end
|
||||
alias org organization
|
||||
|
||||
# Update an organization.
|
||||
#
|
||||
# Requires authenticated client with proper organization permissions.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @param values [Hash] The updated organization attributes.
|
||||
# @option values [String] :billing_email Billing email address. This address is not publicized.
|
||||
# @option values [String] :company Company name.
|
||||
# @option values [String] :email Publicly visible email address.
|
||||
# @option values [String] :location Location of organization.
|
||||
# @option values [String] :name GitHub username for organization.
|
||||
# @option values [String] :default_repository_permission The default permission members have on organization repositories.
|
||||
# @option values [Boolean] :members_can_create_repositories Set true to allow members to create repositories on the organization.
|
||||
# @return [Sawyer::Resource] Hash representing GitHub organization.
|
||||
# @see https://developer.github.com/v3/orgs/#edit-an-organization
|
||||
# @example
|
||||
# @client.update_organization('github', {
|
||||
# :billing_email => 'support@github.com',
|
||||
# :company => 'GitHub',
|
||||
# :email => 'support@github.com',
|
||||
# :location => 'San Francisco',
|
||||
# :name => 'github'
|
||||
# })
|
||||
# @example
|
||||
# @client.update_org('github', {:company => 'Unicorns, Inc.'})
|
||||
def update_organization(org, values, options = {})
|
||||
patch Organization.path(org), options.merge(values)
|
||||
end
|
||||
alias update_org update_organization
|
||||
|
||||
# Delete an organization.
|
||||
#
|
||||
# Requires authenticated organization owner.
|
||||
#
|
||||
# @param org [String, Integer] Organization login or ID.
|
||||
# @return [Boolean] True if deletion successful, otherwise false.
|
||||
# @see https://docs.github.com/rest/orgs/orgs#delete-an-organization
|
||||
# @example
|
||||
# @client.delete_organization("my-org")
|
||||
# @example
|
||||
# @client.delete_org("my-org")
|
||||
def delete_organization(org)
|
||||
boolean_from_response :delete, Organization.path(org)
|
||||
end
|
||||
alias delete_org delete_organization
|
||||
|
||||
# Get organizations for a user.
|
||||
#
|
||||
# Nonauthenticated calls to this method will return organizations that
|
||||
# the user is a public member.
|
||||
#
|
||||
# Use an authenicated client to get both public and private organizations
|
||||
# for a user.
|
||||
#
|
||||
# Calling this method on a `@client` will return that users organizations.
|
||||
# Private organizations are included only if the `@client` is authenticated.
|
||||
#
|
||||
# @param user [Integer, String] GitHub user login or id of the user to get
|
||||
# list of organizations.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing organizations.
|
||||
# @see https://developer.github.com/v3/orgs/#list-your-organizations
|
||||
# @see https://developer.github.com/v3/orgs/#list-user-organizations
|
||||
# @example
|
||||
# Octokit.organizations('pengwynn')
|
||||
# @example
|
||||
# @client.organizations('pengwynn')
|
||||
# @example
|
||||
# Octokit.orgs('pengwynn')
|
||||
# @example
|
||||
# Octokit.list_organizations('pengwynn')
|
||||
# @example
|
||||
# Octokit.list_orgs('pengwynn')
|
||||
# @example
|
||||
# @client.organizations
|
||||
def organizations(user = nil, options = {})
|
||||
paginate "#{User.path user}/orgs", options
|
||||
end
|
||||
alias list_organizations organizations
|
||||
alias list_orgs organizations
|
||||
alias orgs organizations
|
||||
|
||||
# List all GitHub organizations
|
||||
#
|
||||
# This provides a list of every organization, in the order that they
|
||||
# were created.
|
||||
#
|
||||
# @param options [Hash] Optional options.
|
||||
# @option options [Integer] :since The integer ID of the last
|
||||
# Organization that you’ve seen.
|
||||
#
|
||||
# @see https://developer.github.com/v3/orgs/#list-all-organizations
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] List of GitHub organizations.
|
||||
def all_organizations(options = {})
|
||||
paginate 'organizations', options
|
||||
end
|
||||
alias all_orgs all_organizations
|
||||
|
||||
# List organization repositories
|
||||
#
|
||||
# Public repositories are available without authentication. Private repos
|
||||
# require authenticated organization member.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id for which
|
||||
# to list repos.
|
||||
# @option options [String] :type ('all') Filter by repository type.
|
||||
# `all`, `public`, `member`, `sources`, `forks`, or `private`.
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] List of repositories
|
||||
# @see https://developer.github.com/v3/repos/#list-organization-repositories
|
||||
# @example
|
||||
# Octokit.organization_repositories('github')
|
||||
# @example
|
||||
# Octokit.org_repositories('github')
|
||||
# @example
|
||||
# Octokit.org_repos('github')
|
||||
# @example
|
||||
# @client.org_repos('github', {:type => 'private'})
|
||||
def organization_repositories(org, options = {})
|
||||
paginate "#{Organization.path org}/repos", options
|
||||
end
|
||||
alias org_repositories organization_repositories
|
||||
alias org_repos organization_repositories
|
||||
|
||||
# Get organization members
|
||||
#
|
||||
# Public members of the organization are returned by default. An
|
||||
# authenticated client that is a member of the GitHub organization
|
||||
# is required to get private members.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing users.
|
||||
# @see https://developer.github.com/v3/orgs/members/#members-list
|
||||
# @example
|
||||
# Octokit.organization_members('github')
|
||||
# @example
|
||||
# Octokit.org_members('github')
|
||||
def organization_members(org, options = {})
|
||||
options = options.dup
|
||||
path = 'public_' if options.delete(:public)
|
||||
paginate "#{Organization.path org}/#{path}members", options
|
||||
end
|
||||
alias org_members organization_members
|
||||
|
||||
# Get organization public members
|
||||
#
|
||||
# Lists the public members of an organization
|
||||
#
|
||||
# @param org [String] Organization GitHub username.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing users.
|
||||
# @see https://developer.github.com/v3/orgs/members/#public-members-list
|
||||
# @example
|
||||
# Octokit.organization_public_members('github')
|
||||
# @example
|
||||
# Octokit.org_public_members('github')
|
||||
def organization_public_members(org, options = {})
|
||||
organization_members org, options.merge(public: true)
|
||||
end
|
||||
alias org_public_members organization_public_members
|
||||
|
||||
# Check if a user is a member of an organization.
|
||||
#
|
||||
# Use this to check if another user is a member of an organization that
|
||||
# you are a member. If you are not in the organization you are checking,
|
||||
# use .organization_public_member? instead.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @param user [String] GitHub username of the user to check.
|
||||
#
|
||||
# @return [Boolean] Is a member?
|
||||
#
|
||||
# @see https://developer.github.com/v3/orgs/members/#check-membership
|
||||
#
|
||||
# @example Check if a user is in your organization
|
||||
# @client.organization_member?('your_organization', 'pengwynn')
|
||||
# => false
|
||||
def organization_member?(org, user, options = {})
|
||||
result = boolean_from_response(:get, "#{Organization.path org}/members/#{user}", options)
|
||||
if !result && last_response && last_response.status == 302
|
||||
boolean_from_response :get, last_response.headers['Location']
|
||||
else
|
||||
result
|
||||
end
|
||||
end
|
||||
alias org_member? organization_member?
|
||||
|
||||
# Check if a user is a public member of an organization.
|
||||
#
|
||||
# If you are checking for membership of a user of an organization that
|
||||
# you are in, use .organization_member? instead.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @param user [String] GitHub username of the user to check.
|
||||
#
|
||||
# @return [Boolean] Is a public member?
|
||||
#
|
||||
# @see https://developer.github.com/v3/orgs/members/#check-public-membership
|
||||
#
|
||||
# @example Check if a user is a hubbernaut
|
||||
# @client.organization_public_member?('github', 'pengwynn')
|
||||
# => true
|
||||
def organization_public_member?(org, user, options = {})
|
||||
boolean_from_response :get, "#{Organization.path org}/public_members/#{user}", options
|
||||
end
|
||||
alias org_public_member? organization_public_member?
|
||||
|
||||
# List pending organization invitations
|
||||
#
|
||||
# Requires authenticated organization member.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing invitations.
|
||||
# @see https://developer.github.com/v3/orgs/members/#list-pending-organization-invitations
|
||||
#
|
||||
# @example
|
||||
# @client.organization_invitations('github')
|
||||
def organization_invitations(org, options = {})
|
||||
get "#{Organization.path org}/invitations", options
|
||||
end
|
||||
alias org_invitations organization_invitations
|
||||
|
||||
# List outside collaborators for an organization
|
||||
#
|
||||
# Requires authenticated organization members.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing users.
|
||||
# @see https://developer.github.com/v3/orgs/outside_collaborators/#list-outside-collaborators
|
||||
#
|
||||
# @example
|
||||
# @client.outside_collaborators('github')
|
||||
def outside_collaborators(org, options = {})
|
||||
paginate "#{Organization.path org}/outside_collaborators", options
|
||||
end
|
||||
|
||||
# Remove outside collaborator from an organization
|
||||
#
|
||||
# Requires authenticated organization members.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @param user [String] GitHub username to be removed as outside collaborator
|
||||
# @return [Boolean] Return true if outside collaborator removed from organization, false otherwise.
|
||||
# @see https://developer.github.com/v3/orgs/outside-collaborators/#remove-outside-collaborator
|
||||
#
|
||||
# @example
|
||||
# @client.remove_outside_collaborator('github', 'lizzhale')
|
||||
def remove_outside_collaborator(org, user, options = {})
|
||||
boolean_from_response :delete, "#{Organization.path org}/outside_collaborators/#{user}", options
|
||||
end
|
||||
|
||||
# Converts an organization member to an outside collaborator
|
||||
#
|
||||
# Requires authenticated organization members.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @param user [String] GitHub username to be removed as outside collaborator
|
||||
# @return [Boolean] Return true if outside collaborator removed from organization, false otherwise.
|
||||
# @see https://developer.github.com/v3/orgs/outside-collaborators/#convert-member-to-outside-collaborator
|
||||
#
|
||||
# @example
|
||||
# @client.convert_to_outside_collaborator('github', 'lizzhale')
|
||||
def convert_to_outside_collaborator(org, user, options = {})
|
||||
boolean_from_response :put, "#{Organization.path org}/outside_collaborators/#{user}", options
|
||||
end
|
||||
|
||||
# List teams
|
||||
#
|
||||
# Requires authenticated organization member.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing teams.
|
||||
# @see https://developer.github.com/v3/orgs/teams/#list-teams
|
||||
# @example
|
||||
# @client.organization_teams('github')
|
||||
# @example
|
||||
# @client.org_teams('github')
|
||||
def organization_teams(org, options = {})
|
||||
paginate "#{Organization.path org}/teams", options
|
||||
end
|
||||
alias org_teams organization_teams
|
||||
|
||||
# Create team
|
||||
#
|
||||
# Requires authenticated organization owner.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @option options [String] :name Team name.
|
||||
# @option options [Array<String>] :repo_names Repositories for the team.
|
||||
# @option options [Array<String>] :maintainers Maintainers for the team.
|
||||
# @option options [Integer] :parent_team_id ID of a team to set as the parent team.
|
||||
# @return [Sawyer::Resource] Hash representing new team.
|
||||
# @see https://developer.github.com/v3/orgs/teams/#create-team
|
||||
# @example
|
||||
# @client.create_team('github', {
|
||||
# :name => 'Designers',
|
||||
# :repo_names => ['github/dotfiles']
|
||||
# })
|
||||
def create_team(org, options = {})
|
||||
if options.key?(:permission)
|
||||
octokit_warn 'Deprecated: Passing :permission option to #create_team. Assign team repository permission by passing :permission to #add_team_repository instead.'
|
||||
end
|
||||
post "#{Organization.path org}/teams", options
|
||||
end
|
||||
|
||||
# Get team
|
||||
#
|
||||
# Requires authenticated organization member.
|
||||
#
|
||||
# @param team_id [Integer] Team id.
|
||||
# @return [Sawyer::Resource] Hash representing team.
|
||||
# @see https://developer.github.com/v3/orgs/teams/#get-team
|
||||
# @example
|
||||
# @client.team(100000)
|
||||
def team(team_id, options = {})
|
||||
get "teams/#{team_id}", options
|
||||
end
|
||||
|
||||
# Get team by name and org
|
||||
#
|
||||
# Requires authenticated organization member.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @param team_slug [String] Team slug.
|
||||
# @return [Sawyer::Resource] Hash representing team.
|
||||
# @see https://developer.github.com/v3/teams/#get-team-by-name
|
||||
# @example
|
||||
# @client.team_by_name("github", "justice-league")
|
||||
def team_by_name(org, team_slug, options = {})
|
||||
get "#{Organization.path(org)}/teams/#{team_slug}", options
|
||||
end
|
||||
|
||||
# Check team permissions for a repository
|
||||
#
|
||||
# Requires authenticated organization member.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @param team_slug_or_id [String, Integer] Team slug or Team ID.
|
||||
# @param owner [String] Owner name for the repository.
|
||||
# @param repo [String] Name of the repo to check permissions against.
|
||||
# @return [String, Sawyer::Resource] Depending on options it may be an empty string or a resource.
|
||||
# @example
|
||||
# # Check whether the team has any permissions with the repository
|
||||
# @client.team_permissions_for_repo("github", "justice-league", "octocat", "hello-world")
|
||||
#
|
||||
# @example
|
||||
# # Get the full repository object including the permissions level and role for the team
|
||||
# @client.team_permissions_for_repo("github", "justice-league", "octocat", "hello-world", :accept => 'application/vnd.github.v3.repository+json')
|
||||
# @see https://docs.github.com/en/rest/teams/teams#check-team-permissions-for-a-repository
|
||||
def team_permissions_for_repo(org, team_slug_or_id, owner, repo, options = {})
|
||||
get "#{Organization.path(org)}/teams/#{team_slug_or_id}/repos/#{owner}/#{repo}", options
|
||||
end
|
||||
|
||||
# List child teams
|
||||
#
|
||||
# Requires authenticated organization member.
|
||||
#
|
||||
# @param team_id [Integer] Team id.
|
||||
# @return [Sawyer::Resource] Hash representing team.
|
||||
# @see https://developer.github.com/v3/orgs/teams/#list-child-teams
|
||||
# @example
|
||||
# @client.child_teams(100000, :accept => "application/vnd.github.hellcat-preview+json")
|
||||
def child_teams(team_id, options = {})
|
||||
paginate "teams/#{team_id}/teams", options
|
||||
end
|
||||
|
||||
# Update team
|
||||
#
|
||||
# Requires authenticated organization owner.
|
||||
#
|
||||
# @param team_id [Integer] Team id.
|
||||
# @option options [String] :name Team name.
|
||||
# @option options [String] :permission Permissions the team has for team repositories.
|
||||
#
|
||||
# `pull` - team members can pull, but not push to or administer these repositories.
|
||||
# `push` - team members can pull and push, but not administer these repositories.
|
||||
# `admin` - team members can pull, push and administer these repositories.
|
||||
# @option options [Integer] :parent_team_id ID of a team to set as the parent team.
|
||||
# @return [Sawyer::Resource] Hash representing updated team.
|
||||
# @see https://developer.github.com/v3/orgs/teams/#edit-team
|
||||
# @example
|
||||
# @client.update_team(100000, {
|
||||
# :name => 'Front-end Designers',
|
||||
# :permission => 'push'
|
||||
# })
|
||||
def update_team(team_id, options = {})
|
||||
patch "teams/#{team_id}", options
|
||||
end
|
||||
|
||||
# Delete team
|
||||
#
|
||||
# Requires authenticated organization owner.
|
||||
#
|
||||
# @param team_id [Integer] Team id.
|
||||
# @return [Boolean] True if deletion successful, false otherwise.
|
||||
# @see https://developer.github.com/v3/orgs/teams/#delete-team
|
||||
# @example
|
||||
# @client.delete_team(100000)
|
||||
def delete_team(team_id, options = {})
|
||||
boolean_from_response :delete, "teams/#{team_id}", options
|
||||
end
|
||||
|
||||
# List team members
|
||||
#
|
||||
# Requires authenticated organization member.
|
||||
#
|
||||
# @param team_id [Integer] Team id.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing users.
|
||||
# @see https://developer.github.com/v3/orgs/teams/#list-team-members
|
||||
# @example
|
||||
# @client.team_members(100000)
|
||||
def team_members(team_id, options = {})
|
||||
paginate "teams/#{team_id}/members", options
|
||||
end
|
||||
|
||||
# Add team member
|
||||
#
|
||||
# Requires authenticated organization owner or member with team
|
||||
# `admin` permission.
|
||||
#
|
||||
# @param team_id [Integer] Team id.
|
||||
# @param user [String] GitHub username of new team member.
|
||||
# @return [Boolean] True on successful addition, false otherwise.
|
||||
# @see https://developer.github.com/v3/orgs/teams/#add-team-member
|
||||
# @example
|
||||
# @client.add_team_member(100000, 'pengwynn')
|
||||
#
|
||||
# @example
|
||||
# # Opt-in to future behavior for this endpoint. Adds the member to the
|
||||
# # team if they're already an org member. If not, the method will return
|
||||
# # 422 and indicate the user should call the new Team Membership endpoint.
|
||||
# @client.add_team_member \
|
||||
# 100000,
|
||||
# 'pengwynn',
|
||||
# :accept => "application/vnd.github.the-wasp-preview+json"
|
||||
# @see https://developer.github.com/changes/2014-08-05-team-memberships-api/
|
||||
def add_team_member(team_id, user, options = {})
|
||||
# There's a bug in this API call. The docs say to leave the body blank,
|
||||
# but it fails if the body is both blank and the content-length header
|
||||
# is not 0.
|
||||
boolean_from_response :put, "teams/#{team_id}/members/#{user}", options.merge({ name: user })
|
||||
end
|
||||
|
||||
# Remove team member
|
||||
#
|
||||
# Requires authenticated organization owner or member with team
|
||||
# `admin` permission.
|
||||
#
|
||||
# @param team_id [Integer] Team id.
|
||||
# @param user [String] GitHub username of the user to boot.
|
||||
# @return [Boolean] True if user removed, false otherwise.
|
||||
# @see https://developer.github.com/v3/orgs/teams/#remove-team-member
|
||||
# @example
|
||||
# @client.remove_team_member(100000, 'pengwynn')
|
||||
def remove_team_member(team_id, user, options = {})
|
||||
boolean_from_response :delete, "teams/#{team_id}/members/#{user}", options
|
||||
end
|
||||
|
||||
# Check if a user is a member of a team.
|
||||
#
|
||||
# Use this to check if another user is a member of a team that
|
||||
# you are a member.
|
||||
#
|
||||
# @param team_id [Integer] Team id.
|
||||
# @param user [String] GitHub username of the user to check.
|
||||
#
|
||||
# @return [Boolean] Is a member?
|
||||
#
|
||||
# @see https://developer.github.com/v3/orgs/teams/#get-team-member
|
||||
#
|
||||
# @example Check if a user is in your team
|
||||
# @client.team_member?(100000, 'pengwynn')
|
||||
# => false
|
||||
def team_member?(team_id, user, options = {})
|
||||
boolean_from_response :get, "teams/#{team_id}/members/#{user}", options
|
||||
end
|
||||
|
||||
# List pending team invitations
|
||||
#
|
||||
# Requires authenticated organization member.
|
||||
#
|
||||
# @param team_id [Integer] Team id.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing invitations.
|
||||
# @see https://developer.github.com/v3/orgs/teams/#list-pending-team-invitations
|
||||
#
|
||||
# @example
|
||||
# @client.team_invitations('github')
|
||||
def team_invitations(team_id, options = {})
|
||||
get "teams/#{team_id}/invitations", options
|
||||
end
|
||||
|
||||
# List team repositories
|
||||
#
|
||||
# Requires authenticated organization member.
|
||||
#
|
||||
# @param team_id [Integer] Team id.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing repositories.
|
||||
# @see https://developer.github.com/v3/orgs/teams/#list-team-repos
|
||||
# @example
|
||||
# @client.team_repositories(100000)
|
||||
# @example
|
||||
# @client.team_repos(100000)
|
||||
def team_repositories(team_id, options = {})
|
||||
paginate "teams/#{team_id}/repos", options
|
||||
end
|
||||
alias team_repos team_repositories
|
||||
|
||||
# Check if a repo is managed by a specific team
|
||||
#
|
||||
# @param team_id [Integer] Team ID.
|
||||
# @param repo [String, Hash, Repository] A GitHub repository.
|
||||
# @return [Boolean] True if managed by a team. False if not managed by
|
||||
# the team OR the requesting user does not have authorization to access
|
||||
# the team information.
|
||||
# @see https://developer.github.com/v3/orgs/teams/#check-if-a-team-manages-a-repository
|
||||
# @example
|
||||
# @client.team_repository?(8675309, 'octokit/octokit.rb')
|
||||
# @example
|
||||
# @client.team_repo?(8675309, 'octokit/octokit.rb')
|
||||
def team_repository?(team_id, repo, _options = {})
|
||||
boolean_from_response :get, "teams/#{team_id}/repos/#{Repository.new(repo)}"
|
||||
end
|
||||
alias team_repo? team_repository?
|
||||
|
||||
# Add team repository
|
||||
#
|
||||
# This can also be used to update the permission of an existing team
|
||||
#
|
||||
# Requires authenticated user to be an owner of the organization that the
|
||||
# team is associated with. Also, the repo must be owned by the
|
||||
# organization, or a direct form of a repo owned by the organization.
|
||||
#
|
||||
# @param team_id [Integer] Team id.
|
||||
# @param repo [String, Hash, Repository] A GitHub repository.
|
||||
# @option options [String] :permission The permission to grant the team.
|
||||
# Only valid on organization-owned repositories.
|
||||
# Can be one of: <tt>pull</tt>, <tt>push</tt>, or <tt>admin</tt>.
|
||||
# If not specified, the team's <tt>permission</tt> attribute will be
|
||||
# used to determine what permission to grant the team on this repository.
|
||||
# @return [Boolean] True if successful, false otherwise.
|
||||
# @see Octokit::Repository
|
||||
# @see https://developer.github.com/v3/orgs/teams/#add-or-update-team-repository
|
||||
# @example
|
||||
# @client.add_team_repository(100000, 'github/developer.github.com')
|
||||
# @example
|
||||
# @client.add_team_repo(100000, 'github/developer.github.com')
|
||||
# @example Add a team with admin permissions
|
||||
# @client.add_team_repository(100000, 'github/developer.github.com', permission: 'admin')
|
||||
def add_team_repository(team_id, repo, options = {})
|
||||
boolean_from_response :put, "teams/#{team_id}/repos/#{Repository.new(repo)}", options
|
||||
end
|
||||
alias add_team_repo add_team_repository
|
||||
|
||||
# Remove team repository
|
||||
#
|
||||
# Removes repository from team. Does not delete the repository.
|
||||
#
|
||||
# Requires authenticated organization owner.
|
||||
#
|
||||
# @param team_id [Integer] Team id.
|
||||
# @param repo [String, Hash, Repository] A GitHub repository.
|
||||
# @return [Boolean] Return true if repo removed from team, false otherwise.
|
||||
# @see Octokit::Repository
|
||||
# @see https://developer.github.com/v3/orgs/teams/#remove-team-repository
|
||||
# @example
|
||||
# @client.remove_team_repository(100000, 'github/developer.github.com')
|
||||
# @example
|
||||
# @client.remove_team_repo(100000, 'github/developer.github.com')
|
||||
def remove_team_repository(team_id, repo, _options = {})
|
||||
boolean_from_response :delete, "teams/#{team_id}/repos/#{Repository.new(repo)}"
|
||||
end
|
||||
alias remove_team_repo remove_team_repository
|
||||
|
||||
# Remove organization member
|
||||
#
|
||||
# Requires authenticated organization owner or member with team `admin` access.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @param user [String] GitHub username of user to remove.
|
||||
# @return [Boolean] True if removal is successful, false otherwise.
|
||||
# @see https://developer.github.com/v3/orgs/members/#remove-a-member
|
||||
# @example
|
||||
# @client.remove_organization_member('github', 'pengwynn')
|
||||
# @example
|
||||
# @client.remove_org_member('github', 'pengwynn')
|
||||
def remove_organization_member(org, user, options = {})
|
||||
# this is a synonym for: for team in org.teams: remove_team_member(team.id, user)
|
||||
# provided in the GH API v3
|
||||
boolean_from_response :delete, "#{Organization.path org}/members/#{user}", options
|
||||
end
|
||||
alias remove_org_member remove_organization_member
|
||||
|
||||
# Publicize a user's membership of an organization
|
||||
#
|
||||
# Requires authenticated organization owner.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @param user [String] GitHub username of user to publicize.
|
||||
# @return [Boolean] True if publicization successful, false otherwise.
|
||||
# @see https://developer.github.com/v3/orgs/members/#publicize-a-users-membership
|
||||
# @example
|
||||
# @client.publicize_membership('github', 'pengwynn')
|
||||
def publicize_membership(org, user, options = {})
|
||||
boolean_from_response :put, "#{Organization.path org}/public_members/#{user}", options
|
||||
end
|
||||
|
||||
# Conceal a user's membership of an organization.
|
||||
#
|
||||
# Requires authenticated organization owner.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @param user [String] GitHub username of user to unpublicize.
|
||||
# @return [Boolean] True of unpublicization successful, false otherwise.
|
||||
# @see https://developer.github.com/v3/orgs/members/#conceal-a-users-membership
|
||||
# @example
|
||||
# @client.unpublicize_membership('github', 'pengwynn')
|
||||
# @example
|
||||
# @client.conceal_membership('github', 'pengwynn')
|
||||
def unpublicize_membership(org, user, options = {})
|
||||
boolean_from_response :delete, "#{Organization.path org}/public_members/#{user}", options
|
||||
end
|
||||
alias conceal_membership unpublicize_membership
|
||||
|
||||
# List all teams for the authenticated user across all their orgs
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] Array of team resources.
|
||||
# @see https://developer.github.com/v3/orgs/teams/#list-user-teams
|
||||
def user_teams(options = {})
|
||||
paginate 'user/teams', options
|
||||
end
|
||||
|
||||
# Check if a user has a team membership.
|
||||
#
|
||||
# @param team_id [Integer] Team id.
|
||||
# @param user [String] GitHub username of the user to check.
|
||||
#
|
||||
# @return [Sawyer::Resource] Hash of team membership info
|
||||
#
|
||||
# @see https://developer.github.com/v3/orgs/teams/#get-team-membership
|
||||
#
|
||||
# @example Check if a user has a membership for a team
|
||||
# @client.team_membership(1234, 'pengwynn')
|
||||
def team_membership(team_id, user, options = {})
|
||||
get "teams/#{team_id}/memberships/#{user}", options
|
||||
end
|
||||
|
||||
# Add or invite a user to a team
|
||||
#
|
||||
# @param team_id [Integer] Team id.
|
||||
# @param user [String] GitHub username of the user to invite.
|
||||
#
|
||||
# @return [Sawyer::Resource] Hash of team membership info
|
||||
#
|
||||
# @see https://developer.github.com/v3/orgs/teams/#add-or-update-team-membership
|
||||
#
|
||||
# @example Check if a user has a membership for a team
|
||||
# @client.add_team_membership(1234, 'pengwynn')
|
||||
def add_team_membership(team_id, user, options = {})
|
||||
put "teams/#{team_id}/memberships/#{user}", options
|
||||
end
|
||||
|
||||
# Remove team membership
|
||||
#
|
||||
# @param team_id [Integer] Team id.
|
||||
# @param user [String] GitHub username of the user to boot.
|
||||
# @return [Boolean] True if user removed, false otherwise.
|
||||
# @see https://developer.github.com/v3/orgs/teams/#remove-team-membership
|
||||
# @example
|
||||
# @client.remove_team_membership(100000, 'pengwynn')
|
||||
def remove_team_membership(team_id, user, options = {})
|
||||
boolean_from_response :delete, "teams/#{team_id}/memberships/#{user}", options
|
||||
end
|
||||
|
||||
# List all organizations memberships for the authenticated user
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] Array of organizations memberships.
|
||||
# @see https://developer.github.com/v3/orgs/members/#list-your-organization-memberships
|
||||
def organization_memberships(options = {})
|
||||
paginate 'user/memberships/orgs', options
|
||||
end
|
||||
alias org_memberships organization_memberships
|
||||
|
||||
# Get an organization membership
|
||||
#
|
||||
# @param org [Integer, String] The GitHub Organization.
|
||||
# @option options [String] :user The login of the user, otherwise authenticated user.
|
||||
# @return [Sawyer::Resource] Hash representing the organization membership.
|
||||
# @see https://developer.github.com/v3/orgs/members/#get-your-organization-membership
|
||||
# @see https://developer.github.com/v3/orgs/members/#get-organization-membership
|
||||
def organization_membership(org, options = {})
|
||||
options = options.dup
|
||||
if user = options.delete(:user)
|
||||
get "#{Organization.path(org)}/memberships/#{user}", options
|
||||
else
|
||||
get "user/memberships/orgs/#{org}", options
|
||||
end
|
||||
end
|
||||
alias org_membership organization_membership
|
||||
|
||||
# Edit an organization membership
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @option options [String] :role The role of the user in the organization.
|
||||
# @option options [String] :state The state that the membership should be in.
|
||||
# @option options [String] :user The login of the user, otherwise authenticated user.
|
||||
# @return [Sawyer::Resource] Hash representing the updated organization membership.
|
||||
# @see https://developer.github.com/v3/orgs/members/#edit-your-organization-membership
|
||||
# @see https://developer.github.com/v3/orgs/members/#add-or-update-organization-membership
|
||||
def update_organization_membership(org, options = {})
|
||||
options = options.dup
|
||||
if user = options.delete(:user)
|
||||
options.delete(:state)
|
||||
put "#{Organization.path(org)}/memberships/#{user}", options
|
||||
else
|
||||
options.delete(:role)
|
||||
patch "user/memberships/orgs/#{org}", options
|
||||
end
|
||||
end
|
||||
alias update_org_membership update_organization_membership
|
||||
|
||||
# Remove an organization membership
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @return [Boolean] Success
|
||||
# @see https://developer.github.com/v3/orgs/members/#remove-organization-membership
|
||||
def remove_organization_membership(org, options = {})
|
||||
options = options.dup
|
||||
user = options.delete(:user)
|
||||
user && boolean_from_response(:delete, "#{Organization.path(org)}/memberships/#{user}", options)
|
||||
end
|
||||
alias remove_org_membership remove_organization_membership
|
||||
|
||||
# Initiates the generation of a migration archive.
|
||||
#
|
||||
# Requires authenticated organization owner.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @param repositories [Array<String>] :repositories Repositories for the organization.
|
||||
# @option options [Boolean, optional] :lock_repositories Indicates whether repositories should be locked during migration
|
||||
# @return [Sawyer::Resource] Hash representing the new migration.
|
||||
# @example
|
||||
# @client.start_migration('github', ['github/dotfiles'])
|
||||
# @see https://docs.github.com/en/rest/reference/migrations#start-an-organization-migration
|
||||
def start_migration(org, repositories, options = {})
|
||||
options[:repositories] = repositories
|
||||
post "#{Organization.path(org)}/migrations", options
|
||||
end
|
||||
|
||||
# Lists the most recent migrations.
|
||||
#
|
||||
# Requires authenticated organization owner.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @return [Array<Sawyer::Resource>] Array of migration resources.
|
||||
# @see https://docs.github.com/en/rest/reference/migrations#list-organization-migrations
|
||||
def migrations(org, options = {})
|
||||
paginate "#{Organization.path(org)}/migrations", options
|
||||
end
|
||||
|
||||
# Fetches the status of a migration.
|
||||
#
|
||||
# Requires authenticated organization owner.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @param id [Integer] ID number of the migration.
|
||||
# @see https://docs.github.com/en/rest/reference/migrations#get-an-organization-migration-status
|
||||
def migration_status(org, id, options = {})
|
||||
get "#{Organization.path(org)}/migrations/#{id}", options
|
||||
end
|
||||
|
||||
# Fetches the URL to a migration archive.
|
||||
#
|
||||
# Requires authenticated organization owner.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @param id [Integer] ID number of the migration.
|
||||
# @see https://docs.github.com/en/rest/reference/migrations#download-an-organization-migration-archive
|
||||
def migration_archive_url(org, id, options = {})
|
||||
url = "#{Organization.path(org)}/migrations/#{id}/archive"
|
||||
|
||||
response = client_without_redirects(options).get(url)
|
||||
response.headers['location']
|
||||
end
|
||||
|
||||
# Deletes a previous migration archive.
|
||||
#
|
||||
# Requires authenticated organization owner.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @param id [Integer] ID number of the migration.
|
||||
# @see https://docs.github.com/en/rest/reference/migrations#delete-an-organization-migration-archive
|
||||
def delete_migration_archive(org, id, options = {})
|
||||
delete "#{Organization.path(org)}/migrations/#{id}/archive", options
|
||||
end
|
||||
|
||||
# Unlock a previous migration archive.
|
||||
#
|
||||
# Requires authenticated organization owner.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id.
|
||||
# @param id [Integer] ID number of the migration.
|
||||
# @param repo [String] Name of the repository.
|
||||
# @see https://docs.github.com/en/rest/reference/migrations#unlock-an-organization-repository
|
||||
def unlock_repository(org, id, repo, 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
|
||||
|
||||
# Get organization audit log.
|
||||
#
|
||||
# Gets the audit log for an organization.
|
||||
#
|
||||
# @param org [String, Integer] Organization GitHub login or id for which
|
||||
# to retrieve the audit log.
|
||||
# @option options [String] :include ('all') Filter by event type.
|
||||
# `all`, `git` or `web`.
|
||||
# @option options [String] :phrase A search phrase.
|
||||
# @option options [String] :order ('desc') The order of audit log events. To list newest events first, specify desc.
|
||||
# To list oldest events first, specify asc.
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] List of events
|
||||
# @see https://docs.github.com/en/enterprise-cloud@latest/rest/orgs/orgs#get-the-audit-log-for-an-organization
|
||||
# @example
|
||||
# Octokit.organization_audit_log('github', {include: 'all', phrase: 'action:org.add_member created:>2022-08-29 user:octocat'})
|
||||
def organization_audit_log(org, options = {})
|
||||
paginate "#{Organization.path org}/audit-log", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,61 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Pages API
|
||||
#
|
||||
# @see https://developer.github.com/v3/repos/pages/
|
||||
module Pages
|
||||
# List Pages information for a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @return Sawyer::Resource A GitHub Pages resource
|
||||
# @see https://developer.github.com/v3/repos/pages/#get-information-about-a-pages-site
|
||||
def pages(repo, options = {})
|
||||
get "#{Repository.path repo}/pages", options
|
||||
end
|
||||
|
||||
# Get a specific Pages build by ID
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param id [Integer, String] Build ID
|
||||
# @return [Sawyer::Resource] Pages build information
|
||||
# @see https://developer.github.com/v3/repos/pages/#list-a-specific-pages-build
|
||||
# @example
|
||||
# Octokit.pages_build("github/developer.github.com", 5472601)
|
||||
def pages_build(repo, id, options = {})
|
||||
get "#{Repository.path repo}/pages/builds/#{id}", options
|
||||
end
|
||||
|
||||
# List Pages builds for a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @return [Array<Sawyer::Resource>] A list of build history for a repository.
|
||||
# @see https://developer.github.com/v3/repos/pages/#list-pages-builds
|
||||
def pages_builds(repo, options = {})
|
||||
get "#{Repository.path repo}/pages/builds", options
|
||||
end
|
||||
alias list_pages_builds pages_builds
|
||||
|
||||
# List the latest Pages build information for a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @return Sawyer::Resource A GitHub Pages resource about a build
|
||||
# @see https://developer.github.com/v3/repos/pages/#list-latest-pages-build
|
||||
def latest_pages_build(repo, options = {})
|
||||
get "#{Repository.path repo}/pages/builds/latest", options
|
||||
end
|
||||
|
||||
# Request a page build for the latest revision of the default branch
|
||||
#
|
||||
# You can only request builds for your repositories
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @return [Sawyer::Resource] Request result
|
||||
# @see https://developer.github.com/v3/repos/pages/#request-a-page-build
|
||||
def request_page_build(repo, options = {})
|
||||
post "#{Repository.path repo}/pages/builds", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,294 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for Projects API
|
||||
#
|
||||
# @see https://docs.github.com/en/rest/projects
|
||||
module Projects
|
||||
# List projects for a repository
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @return [Array<Sawyer::Resource>] Repository projects
|
||||
# @see https://developer.github.com/v3/projects/#list-repository-projects
|
||||
# @example
|
||||
# @client.projects('octokit/octokit.rb')
|
||||
def projects(repo, options = {})
|
||||
paginate "#{Repository.path repo}/projects", options
|
||||
end
|
||||
|
||||
# Create a project
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param name [String] Project name
|
||||
# @option options [String] :body Body of the project
|
||||
# @return [Sawyer::Resource] Fresh new project
|
||||
# @see https://developer.github.com/v3/projects/#create-a-repository-project
|
||||
# @example Create project with only a name
|
||||
# @client.create_project('octokit/octokit.rb', 'implement new APIs')
|
||||
#
|
||||
# @example Create project with name and body
|
||||
# @client.create_project('octokit/octokit.rb', 'bugs be gone', body: 'Fix all the bugs @joeyw creates')
|
||||
def create_project(repo, name, options = {})
|
||||
options[:name] = name
|
||||
post "#{Repository.path repo}/projects", options
|
||||
end
|
||||
|
||||
# List organization projects
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param org [String] A GitHub organization
|
||||
# @return [Array<Sawyer::Resource>] Organization projects
|
||||
# @see https://developer.github.com/v3/projects/#list-organization-projects
|
||||
# @example
|
||||
# @client.org_projects("octokit")
|
||||
def org_projects(org, options = {})
|
||||
paginate "orgs/#{org}/projects", options
|
||||
end
|
||||
alias organization_projects org_projects
|
||||
|
||||
# Create organization project
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param org [String] A GitHub organization
|
||||
# @param name [String] Project name
|
||||
# @option options [String] :body Project body
|
||||
# @return [Sawyer::Resource] Organization project
|
||||
# @see https://developer.github.com/v3/projects/#create-an-organization-project
|
||||
# @example Create with only a name
|
||||
# @client.create_org_project("octocat", "make more octocats")
|
||||
# @example Create a project with name and body
|
||||
# @client.create_org_project("octokit", "octocan", body: 'Improve clients')
|
||||
def create_org_project(org, name, options = {})
|
||||
options[:name] = name
|
||||
post "orgs/#{org}/projects", options
|
||||
end
|
||||
alias create_organization_project create_org_project
|
||||
|
||||
# Get a project by id
|
||||
#
|
||||
# @param id [Integer] Project id
|
||||
# @return [Sawyer::Resource] Project
|
||||
# @see https://developer.github.com/v3/projects/#get-a-project
|
||||
# @example
|
||||
# Octokit.project(123942)
|
||||
def project(id, options = {})
|
||||
get "projects/#{id}", options
|
||||
end
|
||||
|
||||
# Update a project
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param id [Integer] Project id
|
||||
# @option options [String] :name Project name
|
||||
# @option options [String] :body Project body
|
||||
# @return [Sawyer::Resource] Project
|
||||
# @see https://developer.github.com/v3/projects/#update-a-project
|
||||
# @example Update project name
|
||||
# @client.update_project(123942, name: 'New name')
|
||||
def update_project(id, options = {})
|
||||
patch "projects/#{id}", options
|
||||
end
|
||||
|
||||
# Delete a project
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param id [Integer] Project id
|
||||
# @return [Boolean] Result of deletion
|
||||
# @see https://developer.github.com/v3/projects/#delete-a-project
|
||||
# @example
|
||||
# @client.delete_project(123942)
|
||||
def delete_project(id, options = {})
|
||||
boolean_from_response :delete, "projects/#{id}", options
|
||||
end
|
||||
|
||||
# List project columns
|
||||
#
|
||||
# @param id [Integer] Project id
|
||||
# @return [Array<Sawyer::Resource>] List of project columns
|
||||
# @see https://developer.github.com/v3/projects/columns/#list-project-columns
|
||||
# @example
|
||||
# @client.project_columns(123942)
|
||||
def project_columns(id, options = {})
|
||||
paginate "projects/#{id}/columns", options
|
||||
end
|
||||
|
||||
# Create a project column
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param id [Integer] Project column id
|
||||
# @param name [String] New column name
|
||||
# @return [Sawyer::Resource] Newly created column
|
||||
# @see https://developer.github.com/v3/projects/columns/#create-a-project-column
|
||||
# @example
|
||||
# @client.create_project_column(123942, "To Dones")
|
||||
def create_project_column(id, name, options = {})
|
||||
options[:name] = name
|
||||
post "projects/#{id}/columns", options
|
||||
end
|
||||
|
||||
# Get a project column by ID
|
||||
#
|
||||
# @param id [Integer] Project column id
|
||||
# @return [Sawyer::Resource] Project column
|
||||
# @see https://developer.github.com/v3/projects/columns/#get-a-project-column
|
||||
# @example
|
||||
# Octokit.project_column(30294)
|
||||
def project_column(id, options = {})
|
||||
get "projects/columns/#{id}", options
|
||||
end
|
||||
|
||||
# Update a project column
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param id [Integer] Project column id
|
||||
# @param name [String] New column name
|
||||
# @return [Sawyer::Resource] Updated column
|
||||
# @see https://developer.github.com/v3/projects/columns/#update-a-project-column
|
||||
# @example
|
||||
# @client.update_project_column(30294, "new column name")
|
||||
def update_project_column(id, name, options = {})
|
||||
options[:name] = name
|
||||
patch "projects/columns/#{id}", options
|
||||
end
|
||||
|
||||
# Delete a project column
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param id [Integer] Project column id
|
||||
# @return [Boolean] Result of deletion request, true when deleted
|
||||
# @see https://developer.github.com/v3/projects/columns/#delete-a-project-column
|
||||
# @example
|
||||
# @client.delete_project_column(30294)
|
||||
def delete_project_column(id, options = {})
|
||||
boolean_from_response :delete, "projects/columns/#{id}", options
|
||||
end
|
||||
|
||||
# Move a project column
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param id [Integer] Project column id
|
||||
# @param position [String] New position for the column. Can be one of
|
||||
# <tt>first</tt>, <tt>last</tt>, or <tt>after:<column-id></tt>, where
|
||||
# <tt><column-id></tt> is the id value of a column in the same project.
|
||||
# @return [Sawyer::Resource] Result
|
||||
# @see https://developer.github.com/v3/projects/columns/#move-a-project-column
|
||||
# @example
|
||||
# @client.move_project_column(30294, "last")
|
||||
def move_project_column(id, position, options = {})
|
||||
options[:position] = position
|
||||
post "projects/columns/#{id}/moves", options
|
||||
end
|
||||
|
||||
# List columns cards
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param id [Integer] Project column id
|
||||
# @return [Array<Sawyer::Resource>] Cards in the column
|
||||
# @see https://developer.github.com/v3/projects/cards/#list-project-cards
|
||||
# @example
|
||||
# @client.column_cards(30294)
|
||||
def column_cards(id, options = {})
|
||||
paginate "projects/columns/#{id}/cards", options
|
||||
end
|
||||
|
||||
# Create project card
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param id [Integer] Project column id
|
||||
# @option options [String] :note Card contents for a note type
|
||||
# @option options [Integer] :content_id Issue ID for the card contents
|
||||
# @option options [String] :content_type Type of content to associate
|
||||
# with the card. <tt>Issue</tt> is presently the only avaiable value
|
||||
# @note If :note is supplied, :content_id and :content_type must be
|
||||
# excluded. Similarly, if :content_id is supplied, :content_type must
|
||||
# be set and :note must not be included.
|
||||
# @return [Sawyer::Resource] Newly created card
|
||||
# @see https://developer.github.com/v3/projects/cards/#create-a-project-card
|
||||
# @example Create a project card with a note
|
||||
# @client.create_project_card(123495, note: 'New note card')
|
||||
# @example Create a project card for an repository issue
|
||||
# @client.create_project_card(123495, content_id: 1, content_type: 'Issue')
|
||||
def create_project_card(id, options = {})
|
||||
post "projects/columns/#{id}/cards", options
|
||||
end
|
||||
|
||||
# Get a project card
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param id [Integer] Project card id
|
||||
# @return [Sawyer::Resource] Project card
|
||||
# @see https://developer.github.com/v3/projects/cards/#get-a-project-card
|
||||
# @example
|
||||
# @client.project_card(123495)
|
||||
def project_card(id, options = {})
|
||||
get "projects/columns/cards/#{id}", options
|
||||
end
|
||||
|
||||
# Update a project card
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param id [Integer] Project card id
|
||||
# @option options [String] :note The card's note content. Only valid for
|
||||
# cards without another type of content, so this cannot be specified if
|
||||
# the card already has a content_id and content_type.
|
||||
# @return [Sawyer::Resource] Updated project card
|
||||
# @see https://developer.github.com/v3/projects/cards/#update-a-project-card
|
||||
# @example
|
||||
# @client.update_project_card(12345, note: 'new note')
|
||||
def update_project_card(id, options = {})
|
||||
patch "projects/columns/cards/#{id}", options
|
||||
end
|
||||
|
||||
# Move a project card
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param id [Integer] Project card id
|
||||
# @param position [String] Can be one of <tt>top</tt>, <tt>bottom</tt>,
|
||||
# or <tt>after:<card-id></tt>, where <card-id> is the id value of a
|
||||
# card in the same column, or in the new column specified by column_id.
|
||||
# @option options [Integer] :column_id The column id to move the card to,
|
||||
# must be column in same project
|
||||
# @return [Sawyer::Resource] Empty sawyer resource
|
||||
# @see https://developer.github.com/v3/projects/cards/#move-a-project-card
|
||||
# @example Move a card to the bottom of the same column
|
||||
# @client.move_project_card(123495, 'bottom')
|
||||
# @example Move a card to the top of another column
|
||||
# @client.move_project_card(123495, 'top', column_id: 59402)
|
||||
def move_project_card(id, position, options = {})
|
||||
options[:position] = position
|
||||
post "projects/columns/cards/#{id}/moves", options
|
||||
end
|
||||
|
||||
# Delete a project card
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param id [Integer] Project card id
|
||||
# @return [Boolean] True of deleted, false otherwise
|
||||
# @see https://developer.github.com/v3/projects/cards/#delete-a-project-card
|
||||
# @example
|
||||
# @client.delete_project_card(123495)
|
||||
def delete_project_card(id, options = {})
|
||||
boolean_from_response :delete, "projects/columns/cards/#{id}", options
|
||||
end
|
||||
end # Projects
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,111 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the PubSubHubbub API
|
||||
#
|
||||
# @see https://developer.github.com/v3/repos/hooks/#pubsubhubbub
|
||||
module PubSubHubbub
|
||||
# Subscribe to a pubsub topic
|
||||
#
|
||||
# @param topic [String] A recoginized and supported pubsub topic
|
||||
# @param callback [String] A callback url to be posted to when the topic event is fired
|
||||
# @param secret [String] An optional shared secret used to generate a SHA1 HMAC of the outgoing body content
|
||||
# @return [Boolean] true if the subscribe was successful, otherwise an error is raised
|
||||
# @see https://developer.github.com/v3/repos/hooks/#subscribing
|
||||
# @example Subscribe to push events from one of your repositories, having an email sent when fired
|
||||
# client = Octokit::Client.new(:oauth_token = "token")
|
||||
# client.subscribe("https://github.com/joshk/devise_imapable/events/push", "github://Email?address=josh.kalderimis@gmail.com")
|
||||
def subscribe(topic, callback, secret = nil)
|
||||
options = {
|
||||
'hub.callback': callback,
|
||||
'hub.mode': 'subscribe',
|
||||
'hub.topic': topic
|
||||
}
|
||||
options.merge!('hub.secret': secret) unless secret.nil?
|
||||
|
||||
response = pub_sub_hubbub_request(options)
|
||||
|
||||
response.status == 204
|
||||
end
|
||||
|
||||
# Unsubscribe from a pubsub topic
|
||||
#
|
||||
# @param topic [String] A recoginized pubsub topic
|
||||
# @param callback [String] A callback url to be unsubscribed from
|
||||
# @return [Boolean] true if the unsubscribe was successful, otherwise an error is raised
|
||||
# @see https://developer.github.com/v3/repos/hooks/#subscribing
|
||||
# @example Unsubscribe to push events from one of your repositories, no longer having an email sent when fired
|
||||
# client = Octokit::Client.new(:oauth_token = "token")
|
||||
# client.unsubscribe("https://github.com/joshk/devise_imapable/events/push", "github://Email?address=josh.kalderimis@gmail.com")
|
||||
def unsubscribe(topic, callback)
|
||||
options = {
|
||||
'hub.callback': callback,
|
||||
'hub.mode': 'unsubscribe',
|
||||
'hub.topic': topic
|
||||
}
|
||||
response = pub_sub_hubbub_request(options)
|
||||
|
||||
response.status == 204
|
||||
end
|
||||
|
||||
# Subscribe to a repository through pubsub
|
||||
#
|
||||
# @param repo [String, Repository, Hash] A GitHub repository
|
||||
# @param service_name [String] service name owner
|
||||
# @param service_arguments [Hash] params that will be passed by subscribed hook.
|
||||
# List of services is available @ https://github.com/github/github-services/tree/master/docs.
|
||||
# Please refer Data node for complete list of arguments.
|
||||
# @param secret [String] An optional shared secret used to generate a SHA1 HMAC of the outgoing body content
|
||||
# @return [Boolean] True if subscription successful, false otherwise
|
||||
# @see https://developer.github.com/v3/repos/hooks/#subscribing
|
||||
# @example Subscribe to push events to one of your repositories to Travis-CI
|
||||
# client = Octokit::Client.new(:oauth_token = "token")
|
||||
# client.subscribe_service_hook('joshk/device_imapable', 'Travis', { :token => "test", :domain => "domain", :user => "user" })
|
||||
def subscribe_service_hook(repo, service_name, service_arguments = {}, secret = nil)
|
||||
topic = "#{Octokit.web_endpoint}#{Repository.new(repo)}/events/push"
|
||||
callback = "github://#{service_name}?#{service_arguments.collect { |k, v| [k, v].map { |p| URI.encode_www_form_component(p) }.join('=') }.join('&')}"
|
||||
subscribe(topic, callback, secret)
|
||||
end
|
||||
|
||||
# Unsubscribe repository through pubsub
|
||||
#
|
||||
# @param repo [String, Repository, Hash] A GitHub repository
|
||||
# @param service_name [String] service name owner
|
||||
# List of services is available @ https://github.com/github/github-services/tree/master/docs.
|
||||
# @see https://developer.github.com/v3/repos/hooks/#subscribing
|
||||
# @example Subscribe to push events to one of your repositories to Travis-CI
|
||||
# client = Octokit::Client.new(:oauth_token = "token")
|
||||
# client.unsubscribe_service_hook('joshk/device_imapable', 'Travis')
|
||||
def unsubscribe_service_hook(repo, service_name)
|
||||
topic = "#{Octokit.web_endpoint}#{Repository.new(repo)}/events/push"
|
||||
callback = "github://#{service_name}"
|
||||
unsubscribe(topic, callback)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def pub_sub_hubbub_request(options = {})
|
||||
# This method is janky, bypass normal stack so we don't
|
||||
# serialize request as JSON
|
||||
conn = Faraday.new(url: @api_endpoint) do |http|
|
||||
http.headers[:user_agent] = user_agent
|
||||
if basic_authenticated?
|
||||
http.request(*FARADAY_BASIC_AUTH_KEYS, @login, @password)
|
||||
elsif token_authenticated?
|
||||
http.request :authorization, 'token', @access_token
|
||||
end
|
||||
http.request :url_encoded
|
||||
http.use Octokit::Response::RaiseError
|
||||
http.adapter Faraday.default_adapter
|
||||
end
|
||||
|
||||
conn.post do |req|
|
||||
req.url 'hub'
|
||||
req.headers['Content-Type'] = 'application/x-www-form-urlencoded'
|
||||
req.body = options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,313 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Pull Requests API
|
||||
#
|
||||
# @see https://developer.github.com/v3/pulls/
|
||||
module PullRequests
|
||||
# List pull requests for a repository
|
||||
#
|
||||
# @overload pull_requests(repo, options)
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param options [Hash] Method options
|
||||
# @option options [String] :state `open` or `closed` or `all`.
|
||||
# @return [Array<Sawyer::Resource>] Array of pulls
|
||||
# @see https://developer.github.com/v3/pulls/#list-pull-requests
|
||||
# @example
|
||||
# Octokit.pull_requests('rails/rails', :state => 'closed')
|
||||
def pull_requests(repo, options = {})
|
||||
paginate "#{Repository.path repo}/pulls", options
|
||||
end
|
||||
alias pulls pull_requests
|
||||
|
||||
# Get a pull request
|
||||
#
|
||||
# @see https://developer.github.com/v3/pulls/#get-a-single-pull-request
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param number [Integer] Number of the pull request to fetch
|
||||
# @return [Sawyer::Resource] Pull request info
|
||||
# @example
|
||||
# Octokit.pull_request('rails/rails', 42, :state => 'closed')
|
||||
def pull_request(repo, number, options = {})
|
||||
get "#{Repository.path repo}/pulls/#{number}", options
|
||||
end
|
||||
alias pull pull_request
|
||||
|
||||
# Create a pull request
|
||||
#
|
||||
# @see https://developer.github.com/v3/pulls/#create-a-pull-request
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param base [String] The branch (or git ref) you want your changes
|
||||
# pulled into. This should be an existing branch on the current
|
||||
# repository. You cannot submit a pull request to one repo that requests
|
||||
# a merge to a base of another repo.
|
||||
# @param head [String] The branch (or git ref) where your changes are implemented.
|
||||
# @param title [String] Title for the pull request
|
||||
# @param body [String] The body for the pull request (optional). Supports GFM.
|
||||
# @return [Sawyer::Resource] The newly created pull request
|
||||
# @example
|
||||
# @client.create_pull_request("octokit/octokit.rb", "master", "feature-branch",
|
||||
# "Pull Request title", "Pull Request body")
|
||||
def create_pull_request(repo, base, head, title, body = nil, options = {})
|
||||
pull = {
|
||||
base: base,
|
||||
head: head,
|
||||
title: title
|
||||
}
|
||||
pull[:body] = body unless body.nil?
|
||||
post "#{Repository.path repo}/pulls", options.merge(pull)
|
||||
end
|
||||
|
||||
# Create a pull request from existing issue
|
||||
#
|
||||
# @see https://developer.github.com/v3/pulls/#alternative-input
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param base [String] The branch (or git ref) you want your changes
|
||||
# pulled into. This should be an existing branch on the current
|
||||
# repository. You cannot submit a pull request to one repo that requests
|
||||
# a merge to a base of another repo.
|
||||
# @param head [String] The branch (or git ref) where your changes are implemented.
|
||||
# @param issue [Integer] Number of Issue on which to base this pull request
|
||||
# @return [Sawyer::Resource] The newly created pull request
|
||||
def create_pull_request_for_issue(repo, base, head, issue, options = {})
|
||||
pull = {
|
||||
base: base,
|
||||
head: head,
|
||||
issue: issue
|
||||
}
|
||||
post "#{Repository.path repo}/pulls", options.merge(pull)
|
||||
end
|
||||
|
||||
# Update a pull request
|
||||
# @overload update_pull_request(repo, number, title=nil, body=nil, state=nil, options = {})
|
||||
# @deprecated
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param number [Integer] Number of pull request to update.
|
||||
# @param title [String] Title for the pull request.
|
||||
# @param body [String] Body content for pull request. Supports GFM.
|
||||
# @param state [String] State of the pull request. `open` or `closed`.
|
||||
# @overload update_pull_request(repo, number, options = {})
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param number [Integer] Number of pull request to update.
|
||||
# @option options [String] :title Title for the pull request.
|
||||
# @option options [String] :body Body for the pull request.
|
||||
# @option options [String] :state State for the pull request.
|
||||
# @return [Sawyer::Resource] Hash representing updated pull request.
|
||||
# @see https://developer.github.com/v3/pulls/#update-a-pull-request
|
||||
# @example
|
||||
# @client.update_pull_request('octokit/octokit.rb', 67, 'new title', 'updated body', 'closed')
|
||||
# @example Passing nil for optional attributes to update specific attributes.
|
||||
# @client.update_pull_request('octokit/octokit.rb', 67, nil, nil, 'open')
|
||||
# @example Empty body by passing empty string
|
||||
# @client.update_pull_request('octokit/octokit.rb', 67, nil, '')
|
||||
def update_pull_request(*args)
|
||||
arguments = Octokit::Arguments.new(args)
|
||||
repo = arguments.shift
|
||||
number = arguments.shift
|
||||
patch "#{Repository.path repo}/pulls/#{number}", arguments.options
|
||||
end
|
||||
|
||||
# Close a pull request
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param number [Integer] Number of pull request to update.
|
||||
# @return [Sawyer::Resource] Hash representing updated pull request.
|
||||
# @see https://developer.github.com/v3/pulls/#update-a-pull-request
|
||||
# @example
|
||||
# @client.close_pull_request('octokit/octokit.rb', 67)
|
||||
def close_pull_request(repo, number, options = {})
|
||||
options.merge! state: 'closed'
|
||||
update_pull_request(repo, number, options)
|
||||
end
|
||||
|
||||
# List commits on a pull request
|
||||
#
|
||||
# @see https://developer.github.com/v3/pulls/#list-commits-on-a-pull-request
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param number [Integer] Number of pull request
|
||||
# @return [Array<Sawyer::Resource>] List of commits
|
||||
def pull_request_commits(repo, number, options = {})
|
||||
paginate "#{Repository.path repo}/pulls/#{number}/commits", options
|
||||
end
|
||||
alias pull_commits pull_request_commits
|
||||
|
||||
# List pull request comments for a repository
|
||||
#
|
||||
# By default, Review Comments are ordered by ascending ID.
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param options [Hash] Optional parameters
|
||||
# @option options [String] :sort created or updated
|
||||
# @option options [String] :direction asc or desc. Ignored without sort
|
||||
# parameter.
|
||||
# @option options [String] :since Timestamp in ISO 8601
|
||||
# format: YYYY-MM-DDTHH:MM:SSZ
|
||||
#
|
||||
# @return [Array] List of pull request review comments.
|
||||
#
|
||||
# @see https://developer.github.com/v3/pulls/comments/#list-comments-in-a-repository
|
||||
#
|
||||
# @example Get the pull request review comments in the octokit repository
|
||||
# @client.issues_comments("octokit/octokit.rb")
|
||||
#
|
||||
# @example Get review comments, sort by updated asc since a time
|
||||
# @client.pull_requests_comments("octokit/octokit.rb", {
|
||||
# :sort => 'updated',
|
||||
# :direction => 'asc',
|
||||
# :since => '2010-05-04T23:45:02Z'
|
||||
# })
|
||||
def pull_requests_comments(repo, options = {})
|
||||
paginate("#{Repository.path repo}/pulls/comments", options)
|
||||
end
|
||||
alias pulls_comments pull_requests_comments
|
||||
alias reviews_comments pull_requests_comments
|
||||
|
||||
# List comments on a pull request
|
||||
#
|
||||
# @see https://developer.github.com/v3/pulls/comments/#list-comments-on-a-pull-request
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param number [Integer] Number of pull request
|
||||
# @return [Array<Sawyer::Resource>] List of comments
|
||||
def pull_request_comments(repo, number, options = {})
|
||||
# return the comments for a pull request
|
||||
paginate("#{Repository.path repo}/pulls/#{number}/comments", options)
|
||||
end
|
||||
alias pull_comments pull_request_comments
|
||||
alias review_comments pull_request_comments
|
||||
|
||||
# Get a pull request comment
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param comment_id [Integer] Id of comment to get
|
||||
# @return [Sawyer::Resource] Hash representing the comment
|
||||
# @see https://developer.github.com/v3/pulls/comments/#get-a-single-comment
|
||||
# @example
|
||||
# @client.pull_request_comment("pengwynn/octkit", 1903950)
|
||||
def pull_request_comment(repo, comment_id, options = {})
|
||||
get "#{Repository.path repo}/pulls/comments/#{comment_id}", options
|
||||
end
|
||||
alias pull_comment pull_request_comment
|
||||
alias review_comment pull_request_comment
|
||||
|
||||
# Create a pull request comment
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param pull_id [Integer] Pull request id
|
||||
# @param body [String] Comment content
|
||||
# @param commit_id [String] Sha of the commit to comment on.
|
||||
# @param path [String] Relative path of the file to comment on.
|
||||
# @param position [Integer] Line index in the diff to comment on.
|
||||
# @return [Sawyer::Resource] Hash representing the new comment
|
||||
# @see https://developer.github.com/v3/pulls/comments/#create-a-comment
|
||||
# @example
|
||||
# @client.create_pull_request_comment("octokit/octokit.rb", 163, ":shipit:",
|
||||
# "2d3201e4440903d8b04a5487842053ca4883e5f0", "lib/octokit/request.rb", 47)
|
||||
def create_pull_request_comment(repo, pull_id, body, commit_id, path, position, options = {})
|
||||
options.merge!({
|
||||
body: body,
|
||||
commit_id: commit_id,
|
||||
path: path,
|
||||
position: position
|
||||
})
|
||||
post "#{Repository.path repo}/pulls/#{pull_id}/comments", options
|
||||
end
|
||||
alias create_pull_comment create_pull_request_comment
|
||||
alias create_view_comment create_pull_request_comment
|
||||
|
||||
# Create reply to a pull request comment
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param pull_id [Integer] Pull request id
|
||||
# @param body [String] Comment contents
|
||||
# @param comment_id [Integer] Comment id to reply to
|
||||
# @return [Sawyer::Resource] Hash representing new comment
|
||||
# @see https://developer.github.com/v3/pulls/comments/#create-a-comment
|
||||
# @example
|
||||
# @client.create_pull_request_comment_reply("octokit/octokit.rb", 163, "done.", 1903950)
|
||||
def create_pull_request_comment_reply(repo, pull_id, body, comment_id, options = {})
|
||||
options.merge!({
|
||||
body: body,
|
||||
in_reply_to: comment_id
|
||||
})
|
||||
post "#{Repository.path repo}/pulls/#{pull_id}/comments", options
|
||||
end
|
||||
alias create_pull_reply create_pull_request_comment_reply
|
||||
alias create_review_reply create_pull_request_comment_reply
|
||||
|
||||
# Update pull request comment
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param comment_id [Integer] Id of the comment to update
|
||||
# @param body [String] Updated comment content
|
||||
# @return [Sawyer::Resource] Hash representing the updated comment
|
||||
# @see https://developer.github.com/v3/pulls/comments/#edit-a-comment
|
||||
# @example
|
||||
# @client.update_pull_request_comment("octokit/octokit.rb", 1903950, ":shipit:")
|
||||
def update_pull_request_comment(repo, comment_id, body, options = {})
|
||||
options.merge! body: body
|
||||
patch("#{Repository.path repo}/pulls/comments/#{comment_id}", options)
|
||||
end
|
||||
alias update_pull_comment update_pull_request_comment
|
||||
alias update_review_comment update_pull_request_comment
|
||||
|
||||
# Delete pull request comment
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param comment_id [Integer] Id of the comment to delete
|
||||
# @return [Boolean] True if deleted, false otherwise
|
||||
# @see https://developer.github.com/v3/pulls/comments/#delete-a-comment
|
||||
# @example
|
||||
# @client.delete_pull_request_comment("octokit/octokit.rb", 1902707)
|
||||
def delete_pull_request_comment(repo, comment_id, options = {})
|
||||
boolean_from_response(:delete, "#{Repository.path repo}/pulls/comments/#{comment_id}", options)
|
||||
end
|
||||
alias delete_pull_comment delete_pull_request_comment
|
||||
alias delete_review_comment delete_pull_request_comment
|
||||
|
||||
# List files on a pull request
|
||||
#
|
||||
# @see https://developer.github.com/v3/pulls/#list-pull-requests-files
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param number [Integer] Number of pull request
|
||||
# @return [Array<Sawyer::Resource>] List of files
|
||||
def pull_request_files(repo, number, options = {})
|
||||
paginate "#{Repository.path repo}/pulls/#{number}/files", options
|
||||
end
|
||||
alias pull_files pull_request_files
|
||||
|
||||
# Update a pull request branch
|
||||
#
|
||||
# @see https://developer.github.com/v3/pulls/#update-a-pull-request-branch
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param number [Integer] Number of pull request
|
||||
# @param options [Hash] Optional parameters (e.g. expected_head_sha)
|
||||
# @return [Boolean] True if the pull request branch has been updated
|
||||
def update_pull_request_branch(repo, number, options = {})
|
||||
boolean_from_response(:put, "#{Repository.path repo}/pulls/#{number}/update-branch", options)
|
||||
end
|
||||
|
||||
# Merge a pull request
|
||||
#
|
||||
# @see https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-button
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param number [Integer] Number of pull request
|
||||
# @param commit_message [String] Optional commit message for the merge commit
|
||||
# @return [Array<Sawyer::Resource>] Merge commit info if successful
|
||||
def merge_pull_request(repo, number, commit_message = '', options = {})
|
||||
put "#{Repository.path repo}/pulls/#{number}/merge", options.merge({ commit_message: commit_message })
|
||||
end
|
||||
|
||||
# Check pull request merge status
|
||||
#
|
||||
# @see https://developer.github.com/v3/pulls/#get-if-a-pull-request-has-been-merged
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param number [Integer] Number of pull request
|
||||
# @return [Boolean] True if the pull request has been merged
|
||||
def pull_merged?(repo, number, options = {})
|
||||
boolean_from_response :get, "#{Repository.path repo}/pulls/#{number}/merge", options
|
||||
end
|
||||
alias pull_request_merged? pull_merged?
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,52 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for API rate limiting info
|
||||
#
|
||||
# @see https://developer.github.com/v3/#rate-limiting
|
||||
module RateLimit
|
||||
# Get rate limit info from last response if available
|
||||
# or make a new request to fetch rate limit
|
||||
#
|
||||
# @see https://developer.github.com/v3/rate_limit/#rate-limit
|
||||
# @return [Octokit::RateLimit] Rate limit info
|
||||
def rate_limit(_options = {})
|
||||
return rate_limit! if last_response.nil?
|
||||
|
||||
Octokit::RateLimit.from_response(last_response)
|
||||
end
|
||||
alias ratelimit rate_limit
|
||||
|
||||
# Get number of rate limted requests remaining
|
||||
#
|
||||
# @see https://developer.github.com/v3/rate_limit/#rate-limit
|
||||
# @return [Integer] Number of requests remaining in this period
|
||||
def rate_limit_remaining(_options = {})
|
||||
octokit_warn 'Deprecated: Please use .rate_limit.remaining'
|
||||
rate_limit.remaining
|
||||
end
|
||||
alias ratelimit_remaining rate_limit_remaining
|
||||
|
||||
# Refresh rate limit info by making a new request
|
||||
#
|
||||
# @see https://developer.github.com/v3/rate_limit/#rate-limit
|
||||
# @return [Octokit::RateLimit] Rate limit info
|
||||
def rate_limit!(_options = {})
|
||||
get 'rate_limit'
|
||||
Octokit::RateLimit.from_response(last_response)
|
||||
end
|
||||
alias ratelimit! rate_limit!
|
||||
|
||||
# Refresh rate limit info and get number of rate limted requests remaining
|
||||
#
|
||||
# @see https://developer.github.com/v3/rate_limit/#rate-limit
|
||||
# @return [Integer] Number of requests remaining in this period
|
||||
def rate_limit_remaining!(_options = {})
|
||||
octokit_warn 'Deprecated: Please use .rate_limit!.remaining'
|
||||
rate_limit!.remaining
|
||||
end
|
||||
alias ratelimit_remaining! rate_limit_remaining!
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,153 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Reacions API
|
||||
#
|
||||
# @see https://developer.github.com/v3/reactions/
|
||||
module Reactions
|
||||
# List reactions for a commit comment
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param id [Integer] The id of the commit comment
|
||||
# @see https://developer.github.com/v3/reactions/#list-reactions-for-a-commit-comment
|
||||
#
|
||||
# @example
|
||||
# @client.commit_comment_reactions("octokit/octokit.rb", 1)
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] Array of Hashes representing the reactions.
|
||||
def commit_comment_reactions(repo, id, options = {})
|
||||
get "#{Repository.path repo}/comments/#{id}/reactions", options
|
||||
end
|
||||
|
||||
# Create a reaction for a commit comment
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param id [Integer] The id of the commit comment
|
||||
# @param reaction [String] The Reaction
|
||||
# @see https://developer.github.com/v3/reactions/#create-reaction-for-a-commit-comment
|
||||
# @see https://developer.github.com/v3/reactions/#reaction-types
|
||||
#
|
||||
# @example
|
||||
# @client.create_commit_comment_reactions("octokit/octokit.rb", 1)
|
||||
#
|
||||
# @return [<Sawyer::Resource>] Hash representing the reaction
|
||||
def create_commit_comment_reaction(repo, id, reaction, options = {})
|
||||
options = options.merge(content: reaction)
|
||||
post "#{Repository.path repo}/comments/#{id}/reactions", options
|
||||
end
|
||||
|
||||
# List reactions for an issue
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param number [Integer] The Issue number
|
||||
# @see https://developer.github.com/v3/reactions/#list-reactions-for-an-issue
|
||||
#
|
||||
# @example
|
||||
# @client.issue_reactions("octokit/octokit.rb", 1)
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] Array of Hashes representing the reactions.
|
||||
def issue_reactions(repo, number, options = {})
|
||||
get "#{Repository.path repo}/issues/#{number}/reactions", options
|
||||
end
|
||||
|
||||
# Create reaction for an issue
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param number [Integer] The Issue number
|
||||
# @param reaction [String] The Reaction
|
||||
#
|
||||
# @see https://developer.github.com/v3/reactions/#create-reaction-for-an-issue
|
||||
# @see https://developer.github.com/v3/reactions/#reaction-types
|
||||
#
|
||||
# @example
|
||||
# @client.create_issue_reaction("octokit/octokit.rb", 1)
|
||||
#
|
||||
# @return [<Sawyer::Resource>] Hash representing the reaction.
|
||||
def create_issue_reaction(repo, number, reaction, options = {})
|
||||
options = options.merge(content: reaction)
|
||||
post "#{Repository.path repo}/issues/#{number}/reactions", options
|
||||
end
|
||||
|
||||
# List reactions for an issue comment
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param id [Integer] The Issue comment id
|
||||
#
|
||||
# @see https://developer.github.com/v3/reactions/#list-reactions-for-an-issue-comment
|
||||
#
|
||||
# @example
|
||||
# @client.issue_comment_reactions("octokit/octokit.rb", 1)
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] Array of Hashes representing the reactions.
|
||||
def issue_comment_reactions(repo, id, options = {})
|
||||
get "#{Repository.path repo}/issues/comments/#{id}/reactions", options
|
||||
end
|
||||
|
||||
# Create reaction for an issue comment
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param id [Integer] The Issue comment id
|
||||
# @param reaction [String] The Reaction
|
||||
#
|
||||
# @see https://developer.github.com/v3/reactions/#create-reaction-for-an-issue-comment
|
||||
# @see https://developer.github.com/v3/reactions/#reaction-types
|
||||
#
|
||||
# @example
|
||||
# @client.create_issue_comment_reaction("octokit/octokit.rb", 1)
|
||||
#
|
||||
# @return [<Sawyer::Resource>] Hashes representing the reaction.
|
||||
def create_issue_comment_reaction(repo, id, reaction, options = {})
|
||||
options = options.merge(content: reaction)
|
||||
post "#{Repository.path repo}/issues/comments/#{id}/reactions", options
|
||||
end
|
||||
|
||||
# List reactions for a pull request review comment
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param id [Integer] The Issue comment id
|
||||
#
|
||||
# @see https://developer.github.com/v3/reactions/#list-reactions-for-a-pull-request-review-comment
|
||||
#
|
||||
# @example
|
||||
# @client.pull_request_review_comment_reactions("octokit/octokit.rb", 1)
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] Array of Hashes representing the reactions.
|
||||
def pull_request_review_comment_reactions(repo, id, options = {})
|
||||
get "#{Repository.path repo}/pulls/comments/#{id}/reactions", options
|
||||
end
|
||||
|
||||
# Create reaction for a pull request review comment
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param id [Integer] The Issue comment id
|
||||
# @param reaction [String] The Reaction
|
||||
#
|
||||
# @see https://developer.github.com/v3/reactions/#create-reaction-for-a-pull-request-review-comment
|
||||
# @see https://developer.github.com/v3/reactions/#reaction-types
|
||||
#
|
||||
# @example
|
||||
# @client.create_pull_request_reiew_comment_reaction("octokit/octokit.rb", 1)
|
||||
#
|
||||
# @return [<Sawyer::Resource>] Hash representing the reaction.
|
||||
def create_pull_request_review_comment_reaction(repo, id, reaction, options = {})
|
||||
options = options.merge(content: reaction)
|
||||
post "#{Repository.path repo}/pulls/comments/#{id}/reactions", options
|
||||
end
|
||||
|
||||
# Delete a reaction
|
||||
#
|
||||
# @param id [Integer] Reaction id
|
||||
#
|
||||
# @see https://developer.github.com/v3/reactions/#delete-a-reaction
|
||||
#
|
||||
# @example
|
||||
# @client.delete_reaction(1)
|
||||
#
|
||||
# @return [Boolean] Return true if reaction was deleted, false otherwise.
|
||||
def delete_reaction(id, options = {})
|
||||
boolean_from_response :delete, "reactions/#{id}", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,131 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for References for Git Data API
|
||||
#
|
||||
# @see https://developer.github.com/v3/git/refs/
|
||||
module Refs
|
||||
# List all refs for a given user and repo
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param namespace [String] The ref namespace, e.g. <tt>tag</tt> or <tt>heads</tt>
|
||||
# @return [Array<Sawyer::Resource>] A list of references matching the repo and the namespace
|
||||
# @see https://developer.github.com/v3/git/refs/#get-all-references
|
||||
# @example Fetch all refs for sferik/rails_admin
|
||||
# Octokit.refs("sferik/rails_admin")
|
||||
def refs(repo, namespace = nil, options = {})
|
||||
path = "#{Repository.path repo}/git/refs"
|
||||
path += "/#{namespace}" unless namespace.nil?
|
||||
paginate path, options
|
||||
end
|
||||
alias list_refs refs
|
||||
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
|
||||
# @param ref [String] The ref, e.g. <tt>tags/v0.0.3</tt>
|
||||
# @return [Sawyer::Resource] The reference matching the given repo and the ref id
|
||||
# @see https://developer.github.com/v3/git/refs/#get-a-reference
|
||||
# @example Fetch tags/v0.0.3 for sferik/rails_admin
|
||||
# Octokit.ref("sferik/rails_admin","tags/v0.0.3")
|
||||
def ref(repo, ref, options = {})
|
||||
get "#{Repository.path repo}/git/refs/#{ref}", options
|
||||
end
|
||||
alias reference ref
|
||||
|
||||
# Create a reference
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param ref [String] The ref, e.g. <tt>tags/v0.0.3</tt>
|
||||
# @param sha [String] A SHA, e.g. <tt>827efc6d56897b048c772eb4087f854f46256132</tt>
|
||||
# @return [Array<Sawyer::Resource>] The list of references, already containing the new one
|
||||
# @see https://developer.github.com/v3/git/refs/#create-a-reference
|
||||
# @example Create refs/heads/master for octocat/Hello-World with sha 827efc6d56897b048c772eb4087f854f46256132
|
||||
# Octokit.create_ref("octocat/Hello-World", "heads/master", "827efc6d56897b048c772eb4087f854f46256132")
|
||||
def create_ref(repo, ref, sha, options = {})
|
||||
ref = "refs/#{ref}" unless ref =~ %r{\Arefs/}
|
||||
parameters = {
|
||||
ref: ref,
|
||||
sha: sha
|
||||
}
|
||||
post "#{Repository.path repo}/git/refs", options.merge(parameters)
|
||||
end
|
||||
alias create_reference create_ref
|
||||
|
||||
# Update a reference
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param ref [String] The ref, e.g. <tt>tags/v0.0.3</tt>
|
||||
# @param sha [String] A SHA, e.g. <tt>827efc6d56897b048c772eb4087f854f46256132</tt>
|
||||
# @param force [Boolean] A flag indicating whether to force the update or to make sure the update is a fast-forward update.
|
||||
# @return [Array<Sawyer::Resource>] The list of references updated
|
||||
# @see https://developer.github.com/v3/git/refs/#update-a-reference
|
||||
# @example Force update heads/sc/featureA for octocat/Hello-World with sha aa218f56b14c9653891f9e74264a383fa43fefbd
|
||||
# Octokit.update_ref("octocat/Hello-World", "heads/sc/featureA", "aa218f56b14c9653891f9e74264a383fa43fefbd")
|
||||
def update_ref(repo, ref, sha, force = false, options = {})
|
||||
parameters = {
|
||||
sha: sha,
|
||||
force: force
|
||||
}
|
||||
patch "#{Repository.path repo}/git/refs/#{ref}", options.merge(parameters)
|
||||
end
|
||||
alias update_reference update_ref
|
||||
|
||||
# Update a branch
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param branch [String] The ref, e.g. <tt>feature/new-shiny</tt>
|
||||
# @param sha [String] A SHA, e.g. <tt>827efc6d56897b048c772eb4087f854f46256132</tt>
|
||||
# @param force [Boolean] A flag indicating whether to force the update or to make sure the update is a fast-forward update.
|
||||
# @return [Array<Sawyer::Resource>] The list of references updated
|
||||
# @see https://developer.github.com/v3/git/refs/#update-a-reference
|
||||
# @example Force update heads/sc/featureA for octocat/Hello-World with sha aa218f56b14c9653891f9e74264a383fa43fefbd
|
||||
# Octokit.update_branch("octocat/Hello-World", "sc/featureA", "aa218f56b14c9653891f9e74264a383fa43fefbd")
|
||||
# @example Fast-forward update heads/sc/featureA for octocat/Hello-World with sha aa218f56b14c9653891f9e74264a383fa43fefbd
|
||||
# Octokit.update_branch("octocat/Hello-World", "sc/featureA", "aa218f56b14c9653891f9e74264a383fa43fefbd", false)
|
||||
def update_branch(repo, branch, sha, force = true, options = {})
|
||||
update_ref repo, "heads/#{branch}", sha, force, options
|
||||
end
|
||||
|
||||
# Delete a single branch
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param branch [String] The branch, e.g. <tt>fix-refs</tt>
|
||||
# @return [Boolean] Success
|
||||
# @see https://developer.github.com/v3/git/refs/#delete-a-reference
|
||||
# @example Delete uritemplate for sigmavirus24/github3.py
|
||||
# Octokit.delete_branch("sigmavirus24/github3.py", "uritemplate")
|
||||
def delete_branch(repo, branch, options = {})
|
||||
delete_ref repo, "heads/#{branch}", options
|
||||
end
|
||||
|
||||
# Delete a single reference
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param ref [String] The ref, e.g. <tt>tags/v0.0.3</tt>
|
||||
# @return [Boolean] Success
|
||||
# @see https://developer.github.com/v3/git/refs/#delete-a-reference
|
||||
# @example Delete tags/v0.0.3 for sferik/rails_admin
|
||||
# Octokit.delete_ref("sferik/rails_admin","tags/v0.0.3")
|
||||
def delete_ref(repo, ref, options = {})
|
||||
boolean_from_response :delete, "#{Repository.path repo}/git/refs/#{ref}", options
|
||||
end
|
||||
alias delete_reference delete_ref
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,164 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Releases API
|
||||
#
|
||||
# @see https://developer.github.com/v3/repos/releases/
|
||||
module Releases
|
||||
# List releases for a repository
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @return [Array<Sawyer::Resource>] A list of releases
|
||||
# @see https://developer.github.com/v3/repos/releases/#list-releases-for-a-repository
|
||||
def releases(repo, options = {})
|
||||
paginate "#{Repository.path repo}/releases", options
|
||||
end
|
||||
alias list_releases releases
|
||||
|
||||
# Create a release
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param tag_name [String] Git tag from which to create release
|
||||
# @option options [String] :target_commitish Specifies the commitish value that determines where the Git tag is created from.
|
||||
# @option options [String] :name Name for the release
|
||||
# @option options [String] :body Content for release notes
|
||||
# @option options [Boolean] :draft Mark this release as a draft
|
||||
# @option options [Boolean] :prerelease Mark this release as a pre-release
|
||||
# @return [Sawyer::Resource] The release
|
||||
# @see https://developer.github.com/v3/repos/releases/#create-a-release
|
||||
def create_release(repo, tag_name, options = {})
|
||||
opts = options.merge(tag_name: tag_name)
|
||||
post "#{Repository.path repo}/releases", opts
|
||||
end
|
||||
|
||||
# Get a release
|
||||
#
|
||||
# @param url [String] URL for the release as returned from .releases
|
||||
# @return [Sawyer::Resource] The release
|
||||
# @see https://developer.github.com/v3/repos/releases/#get-a-single-release
|
||||
def release(url, options = {})
|
||||
get url, options
|
||||
end
|
||||
|
||||
# Update a release
|
||||
#
|
||||
# @param url [String] URL for the release as returned from .releases
|
||||
# @option options [String] :tag_name Git tag from which to create release
|
||||
# @option options [String] :target_commitish Specifies the commitish value that determines where the Git tag is created from.
|
||||
# @option options [String] :name Name for the release
|
||||
# @option options [String] :body Content for release notes
|
||||
# @option options [Boolean] :draft Mark this release as a draft
|
||||
# @option options [Boolean] :prerelease Mark this release as a pre-release
|
||||
# @return [Sawyer::Resource] The release
|
||||
# @see https://developer.github.com/v3/repos/releases/#edit-a-release
|
||||
def update_release(url, options = {})
|
||||
patch url, options
|
||||
end
|
||||
alias edit_release update_release
|
||||
|
||||
# Delete a release
|
||||
#
|
||||
# @param url [String] URL for the release as returned from .releases
|
||||
# @return [Boolean] Success or failure
|
||||
# @see https://developer.github.com/v3/repos/releases/#delete-a-release
|
||||
def delete_release(url, options = {})
|
||||
boolean_from_response(:delete, url, options)
|
||||
end
|
||||
|
||||
# List release assets
|
||||
#
|
||||
# @param release_url [String] URL for the release as returned from .releases
|
||||
# @return [Array<Sawyer::Resource>] A list of release assets
|
||||
# @see https://developer.github.com/v3/repos/releases/#list-assets-for-a-release
|
||||
def release_assets(release_url, options = {})
|
||||
paginate release(release_url).rels[:assets].href, options
|
||||
end
|
||||
|
||||
# Upload a release asset
|
||||
#
|
||||
# @param release_url [String] URL for the release as returned from .releases
|
||||
# @param path_or_file [String] Path to file to upload
|
||||
# @option options [String] :content_type The MIME type for the file to upload
|
||||
# @option options [String] :name The name for the file
|
||||
# @return [Sawyer::Resource] The release asset
|
||||
# @see https://developer.github.com/v3/repos/releases/#upload-a-release-asset
|
||||
def upload_asset(release_url, path_or_file, options = {})
|
||||
file = path_or_file.respond_to?(:read) ? path_or_file : File.new(path_or_file, 'rb')
|
||||
options[:content_type] ||= content_type_from_file(file)
|
||||
raise Octokit::MissingContentType if options[:content_type].nil?
|
||||
|
||||
unless name = options[:name]
|
||||
name = File.basename(file.path)
|
||||
end
|
||||
upload_url = release(release_url).rels[:upload].href_template.expand(name: name)
|
||||
|
||||
request :post, upload_url, file.read, parse_query_and_convenience_headers(options)
|
||||
ensure
|
||||
file&.close
|
||||
end
|
||||
|
||||
# Get a single release asset
|
||||
#
|
||||
#
|
||||
# @param asset_url [String] URL for the asset as returned from .release_assets
|
||||
# @return [Sawyer::Resource] The release asset
|
||||
# @see https://developer.github.com/v3/repos/releases/#get-a-single-release-asset
|
||||
def release_asset(asset_url, options = {})
|
||||
get(asset_url, options)
|
||||
end
|
||||
|
||||
# Update a release asset
|
||||
#
|
||||
# @param asset_url [String] URL for the asset as returned from .release_assets
|
||||
# @option options [String] :name The name for the file
|
||||
# @option options [String] :label The download text for the file
|
||||
# @return [Sawyer::Resource] The release asset
|
||||
# @see https://developer.github.com/v3/repos/releases/#edit-a-release-asset
|
||||
def update_release_asset(asset_url, options = {})
|
||||
patch(asset_url, options)
|
||||
end
|
||||
alias edit_release_asset update_release_asset
|
||||
|
||||
# Delete a release asset
|
||||
#
|
||||
# @param asset_url [String] URL for the asset as returned from .release_assets
|
||||
# @return [Boolean] Success or failure
|
||||
# @see https://developer.github.com/v3/repos/releases/#delete-a-release-asset
|
||||
def delete_release_asset(asset_url, options = {})
|
||||
boolean_from_response(:delete, asset_url, options)
|
||||
end
|
||||
|
||||
# Get the release for a given tag
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param tag_name [String] the name for a tag
|
||||
# @return [Sawyer::Resource] The release
|
||||
# @see https://developer.github.com/v3/repos/releases/#get-a-release-by-tag-name
|
||||
def release_for_tag(repo, tag_name, options = {})
|
||||
get "#{Repository.path repo}/releases/tags/#{tag_name}", options
|
||||
end
|
||||
|
||||
# Get the latest release
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @return [Sawyer::Resource] The release
|
||||
# @see https://developer.github.com/v3/repos/releases/#get-the-latest-release
|
||||
def latest_release(repo, options = {})
|
||||
get "#{Repository.path repo}/releases/latest", options
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def content_type_from_file(file)
|
||||
require 'mime/types'
|
||||
if mime_type = MIME::Types.type_for(file.path).first
|
||||
mime_type.content_type
|
||||
end
|
||||
rescue LoadError
|
||||
msg = 'Please pass content_type or install mime-types gem to guess content type from file'
|
||||
raise Octokit::MissingContentType, msg
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,779 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Repositories API
|
||||
#
|
||||
# @see https://developer.github.com/v3/repos/
|
||||
module Repositories
|
||||
# Check if a repository exists
|
||||
#
|
||||
# @see https://developer.github.com/v3/repos/#get
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @return [Boolean]
|
||||
def repository?(repo, options = {})
|
||||
!!repository(repo, options)
|
||||
rescue Octokit::InvalidRepository, Octokit::NotFound
|
||||
false
|
||||
end
|
||||
|
||||
# Get a single repository
|
||||
#
|
||||
# @see https://developer.github.com/v3/repos/#get
|
||||
# @see https://developer.github.com/v3/licenses/#get-a-repositorys-license
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @return [Sawyer::Resource] Repository information
|
||||
def repository(repo, options = {})
|
||||
get Repository.path(repo), options
|
||||
end
|
||||
alias repo repository
|
||||
|
||||
# Edit a repository
|
||||
#
|
||||
# @see https://developer.github.com/v3/repos/#update-a-repository
|
||||
# @param repo [String, Hash, Repository] A GitHub repository
|
||||
# @param options [Hash] Repository information to update
|
||||
# @option options [String] :name Name of the repo
|
||||
# @option options [String] :description Description of the repo
|
||||
# @option options [String] :homepage Home page of the repo
|
||||
# @option options [String] :private `true` makes the repository private, and `false` makes it public.
|
||||
# @option options [String] :has_issues `true` enables issues for this repo, `false` disables issues.
|
||||
# @option options [String] :has_wiki `true` enables wiki for this repo, `false` disables wiki.
|
||||
# @option options [Boolean] :is_template `true` makes the repository a template, `false` makes it not a template.
|
||||
# @option options [String] :has_downloads `true` enables downloads for this repo, `false` disables downloads.
|
||||
# @option options [String] :default_branch Update the default branch for this repository.
|
||||
# @return [Sawyer::Resource] Repository information
|
||||
def edit_repository(repo, options = {})
|
||||
repo = Repository.new(repo)
|
||||
options[:name] ||= repo.name
|
||||
patch "repos/#{repo}", options
|
||||
end
|
||||
alias edit edit_repository
|
||||
alias update_repository edit_repository
|
||||
alias update edit_repository
|
||||
|
||||
# List user repositories
|
||||
#
|
||||
# If user is not supplied, repositories for the current
|
||||
# authenticated user are returned.
|
||||
#
|
||||
# @note If the user provided is a GitHub organization, only the
|
||||
# organization's public repositories will be listed. For retrieving
|
||||
# organization repositories the {Organizations#organization_repositories}
|
||||
# method should be used instead.
|
||||
# @see https://developer.github.com/v3/repos/#list-your-repositories
|
||||
# @see https://developer.github.com/v3/repos/#list-user-repositories
|
||||
# @param user [Integer, String] Optional GitHub user login or id for which
|
||||
# to list repos.
|
||||
# @return [Array<Sawyer::Resource>] List of repositories
|
||||
def repositories(user = nil, options = {})
|
||||
paginate "#{User.path user}/repos", options
|
||||
end
|
||||
alias list_repositories repositories
|
||||
alias list_repos repositories
|
||||
alias repos repositories
|
||||
|
||||
# List all repositories
|
||||
#
|
||||
# This provides a dump of every repository, in the order that they were
|
||||
# created.
|
||||
#
|
||||
# @see https://developer.github.com/v3/repos/#list-all-public-repositories
|
||||
#
|
||||
# @param options [Hash] Optional options
|
||||
# @option options [Integer] :since The integer ID of the last Repository
|
||||
# that you’ve seen.
|
||||
# @return [Array<Sawyer::Resource>] List of repositories.
|
||||
def all_repositories(options = {})
|
||||
paginate 'repositories', options
|
||||
end
|
||||
|
||||
# Star a repository
|
||||
#
|
||||
# @param repo [String, Hash, Repository] A GitHub repository
|
||||
# @return [Boolean] `true` if successfully starred
|
||||
# @see https://developer.github.com/v3/activity/starring/#star-a-repository
|
||||
def star(repo, options = {})
|
||||
boolean_from_response :put, "user/starred/#{Repository.new(repo)}", options
|
||||
end
|
||||
|
||||
# Unstar a repository
|
||||
#
|
||||
# @param repo [String, Hash, Repository] A GitHub repository
|
||||
# @return [Boolean] `true` if successfully unstarred
|
||||
# @see https://developer.github.com/v3/activity/starring/#unstar-a-repository
|
||||
def unstar(repo, options = {})
|
||||
boolean_from_response :delete, "user/starred/#{Repository.new(repo)}", options
|
||||
end
|
||||
|
||||
# Watch a repository
|
||||
#
|
||||
# @param repo [String, Hash, Repository] A GitHub repository
|
||||
# @return [Boolean] `true` if successfully watched
|
||||
# @deprecated Use #star instead
|
||||
# @see https://developer.github.com/v3/activity/watching/#watch-a-repository-legacy
|
||||
def watch(repo, options = {})
|
||||
boolean_from_response :put, "user/watched/#{Repository.new(repo)}", options
|
||||
end
|
||||
|
||||
# Unwatch a repository
|
||||
#
|
||||
# @param repo [String, Hash, Repository] A GitHub repository
|
||||
# @return [Boolean] `true` if successfully unwatched
|
||||
# @deprecated Use #unstar instead
|
||||
# @see https://developer.github.com/v3/activity/watching/#stop-watching-a-repository-legacy
|
||||
def unwatch(repo, options = {})
|
||||
boolean_from_response :delete, "user/watched/#{Repository.new(repo)}", options
|
||||
end
|
||||
|
||||
# Fork a repository
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @return [Sawyer::Resource] Repository info for the new fork
|
||||
# @see https://developer.github.com/v3/repos/forks/#create-a-fork
|
||||
def fork(repo, options = {})
|
||||
post "#{Repository.path repo}/forks", options
|
||||
end
|
||||
|
||||
# Create a repository for a user or organization
|
||||
#
|
||||
# @param name [String] Name of the new repo
|
||||
# @option options [String] :description Description of the repo
|
||||
# @option options [String] :homepage Home page of the repo
|
||||
# @option options [String] :private `true` makes the repository private, and `false` makes it public.
|
||||
# @option options [String] :has_issues `true` enables issues for this repo, `false` disables issues.
|
||||
# @option options [String] :has_wiki `true` enables wiki for this repo, `false` disables wiki.
|
||||
# @option options [Boolean] :is_template `true` makes this repo available as a template repository, `false` to prevent it.
|
||||
# @option options [String] :has_downloads `true` enables downloads for this repo, `false` disables downloads.
|
||||
# @option options [String] :organization Short name for the org under which to create the repo.
|
||||
# @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.
|
||||
# @option options [Boolean] :auto_init `true` to create an initial commit with empty README. Default is `false`.
|
||||
# @option options [String] :gitignore_template Desired language or platform .gitignore template to apply. Ignored if auto_init parameter is not provided.
|
||||
# @return [Sawyer::Resource] Repository info for the new repository
|
||||
# @see https://developer.github.com/v3/repos/#create
|
||||
def create_repository(name, options = {})
|
||||
opts = options.dup
|
||||
organization = opts.delete :organization
|
||||
opts.merge! name: name
|
||||
|
||||
if organization.nil?
|
||||
post 'user/repos', opts
|
||||
else
|
||||
post "#{Organization.path organization}/repos", opts
|
||||
end
|
||||
end
|
||||
alias create_repo create_repository
|
||||
alias create create_repository
|
||||
|
||||
# Delete repository
|
||||
#
|
||||
# Note: If OAuth is used, 'delete_repo' scope is required
|
||||
#
|
||||
# @see https://developer.github.com/v3/repos/#delete-a-repository
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @return [Boolean] `true` if repository was deleted
|
||||
def delete_repository(repo, options = {})
|
||||
boolean_from_response :delete, Repository.path(repo), options
|
||||
end
|
||||
alias delete_repo delete_repository
|
||||
|
||||
# Transfer repository
|
||||
#
|
||||
# Transfer a repository owned by your organization
|
||||
#
|
||||
# @see https://developer.github.com/v3/repos/#transfer-a-repository
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param new_owner [String] The username or organization name the repository will be transferred to.
|
||||
# @param options [Array<Integer>] :team_ids ID of the team or teams to add to the repository. Teams can only be added to organization-owned repositories.
|
||||
# @return [Sawyer::Resource] Repository info for the transferred repository
|
||||
def transfer_repository(repo, new_owner, options = {})
|
||||
post "#{Repository.path repo}/transfer", options.merge({ new_owner: new_owner })
|
||||
end
|
||||
alias transfer_repo transfer_repository
|
||||
|
||||
# Create a repository for a user or organization generated from a template repository
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub template repository
|
||||
# @param name [String] Name of the new repo
|
||||
# @option options [String] :owner Organization or user who the new repository will belong to.
|
||||
# @option options [String] :description Description of the repo
|
||||
# @option options [String] :private `true` makes the repository private, and `false` makes it public.
|
||||
# @option options [Boolean] :include_all_branches `true` copies all branches from the template repository, `false` (default) makes it only copy the master branch.
|
||||
# @return [Sawyer::Resource] Repository info for the new repository
|
||||
def create_repository_from_template(repo, name, options = {})
|
||||
options.merge! name: name
|
||||
post "#{Repository.path repo}/generate", options
|
||||
end
|
||||
alias create_repo_from_template create_repository_from_template
|
||||
|
||||
# Hide a public repository
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @return [Sawyer::Resource] Updated repository info
|
||||
def set_private(repo, options = {})
|
||||
# GitHub Api for setting private updated to use private attr, rather than public
|
||||
update_repository repo, options.merge({ private: true })
|
||||
end
|
||||
|
||||
# Unhide a private repository
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @return [Sawyer::Resource] Updated repository info
|
||||
def set_public(repo, options = {})
|
||||
# GitHub Api for setting private updated to use private attr, rather than public
|
||||
update_repository repo, options.merge({ private: false })
|
||||
end
|
||||
|
||||
# Get deploy keys on a repo
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing deploy keys.
|
||||
# @see https://developer.github.com/v3/repos/keys/#list-deploy-keys
|
||||
# @example
|
||||
# @client.deploy_keys('octokit/octokit.rb')
|
||||
# @example
|
||||
# @client.list_deploy_keys('octokit/octokit.rb')
|
||||
def deploy_keys(repo, options = {})
|
||||
paginate "#{Repository.path repo}/keys", options
|
||||
end
|
||||
alias list_deploy_keys deploy_keys
|
||||
|
||||
# Get a single deploy key for a repo
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param id [Integer] Deploy key ID.
|
||||
# @return [Sawyer::Resource] Deploy key.
|
||||
# @see https://developer.github.com/v3/repos/keys/#get-a-deploy-key
|
||||
# @example
|
||||
# @client.deploy_key('octokit/octokit.rb', 8675309)
|
||||
def deploy_key(repo, id, options = {})
|
||||
get "#{Repository.path repo}/keys/#{id}", options
|
||||
end
|
||||
|
||||
# Add deploy key to a repo
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param title [String] Title reference for the deploy key.
|
||||
# @param key [String] Public key.
|
||||
# @return [Sawyer::Resource] Hash representing newly added key.
|
||||
# @see https://developer.github.com/v3/repos/keys/#add-a-new-deploy-key
|
||||
# @example
|
||||
# @client.add_deploy_key('octokit/octokit.rb', 'Staging server', 'ssh-rsa AAA...')
|
||||
def add_deploy_key(repo, title, key, options = {})
|
||||
post "#{Repository.path repo}/keys", options.merge(title: title, key: key)
|
||||
end
|
||||
|
||||
# Edit a deploy key
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param id [Integer] Deploy key ID.
|
||||
# @param options [Hash] Attributes to edit.
|
||||
# @option title [String] Key title.
|
||||
# @option key [String] Public key.
|
||||
# @return [Sawyer::Resource] Updated deploy key.
|
||||
# @deprecated This method is no longer supported in the API
|
||||
# @see https://developer.github.com/changes/2014-02-24-finer-grained-scopes-for-ssh-keys/
|
||||
# @see https://developer.github.com/v3/repos/keys/#edit-a-deploy-key
|
||||
# @example Update the key for a deploy key.
|
||||
# @client.edit_deploy_key('octokit/octokit.rb', 8675309, :key => 'ssh-rsa BBB...')
|
||||
# @example
|
||||
# @client.update_deploy_key('octokit/octokit.rb', 8675309, :title => 'Uber', :key => 'ssh-rsa BBB...'))
|
||||
def edit_deploy_key(repo, id, options)
|
||||
patch "#{Repository.path repo}/keys/#{id}", options
|
||||
end
|
||||
alias update_deploy_key edit_deploy_key
|
||||
|
||||
# Remove deploy key from a repo
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param id [Integer] Id of the deploy key to remove.
|
||||
# @return [Boolean] True if key removed, false otherwise.
|
||||
# @see https://developer.github.com/v3/repos/keys/#remove-a-deploy-key
|
||||
# @example
|
||||
# @client.remove_deploy_key('octokit/octokit.rb', 100000)
|
||||
def remove_deploy_key(repo, id, options = {})
|
||||
boolean_from_response :delete, "#{Repository.path repo}/keys/#{id}", options
|
||||
end
|
||||
|
||||
# List collaborators
|
||||
#
|
||||
# Requires authenticated client for private repos.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @option options [String] :affiliation Filters the return array by affiliation.
|
||||
# Can be one of: <tt>outside</tt>, <tt>direct</tt>, or <tt>all</tt>.
|
||||
# If not specified, defaults to <tt>all</tt>
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing collaborating users.
|
||||
# @see https://developer.github.com/v3/repos/collaborators/#list-collaborators
|
||||
# @example
|
||||
# Octokit.collaborators('octokit/octokit.rb')
|
||||
# @example
|
||||
# Octokit.collabs('octokit/octokit.rb')
|
||||
# @example
|
||||
# @client.collabs('octokit/octokit.rb')
|
||||
def collaborators(repo, options = {})
|
||||
paginate "#{Repository.path repo}/collaborators", options
|
||||
end
|
||||
alias collabs collaborators
|
||||
|
||||
# Add collaborator to repo
|
||||
#
|
||||
# This can also be used to update the permission of an existing collaborator
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param collaborator [String] Collaborator GitHub username to add.
|
||||
# @option options [String] :permission The permission to grant the collaborator.
|
||||
# Only valid on organization-owned repositories.
|
||||
# Can be one of: <tt>pull</tt>, <tt>push</tt>, or <tt>admin</tt>.
|
||||
# If not specified, defaults to <tt>push</tt>
|
||||
# @return [Boolean] True if collaborator added, false otherwise.
|
||||
# @see https://developer.github.com/v3/repos/collaborators/#add-user-as-a-collaborator
|
||||
# @example
|
||||
# @client.add_collaborator('octokit/octokit.rb', 'holman')
|
||||
# @example
|
||||
# @client.add_collab('octokit/octokit.rb', 'holman')
|
||||
# @example Add a collaborator with admin permissions
|
||||
# @client.add_collaborator('octokit/octokit.rb', 'holman', permission: 'admin')
|
||||
def add_collaborator(repo, collaborator, options = {})
|
||||
boolean_from_response :put, "#{Repository.path repo}/collaborators/#{collaborator}", options
|
||||
end
|
||||
alias add_collab add_collaborator
|
||||
|
||||
# Remove collaborator from repo.
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param collaborator [String] Collaborator GitHub username to remove.
|
||||
# @return [Boolean] True if collaborator removed, false otherwise.
|
||||
# @see https://developer.github.com/v3/repos/collaborators/#remove-user-as-a-collaborator
|
||||
# @example
|
||||
# @client.remove_collaborator('octokit/octokit.rb', 'holman')
|
||||
# @example
|
||||
# @client.remove_collab('octokit/octokit.rb', 'holman')
|
||||
def remove_collaborator(repo, collaborator, options = {})
|
||||
boolean_from_response :delete, "#{Repository.path repo}/collaborators/#{collaborator}", options
|
||||
end
|
||||
alias remove_collab remove_collaborator
|
||||
|
||||
# Checks if a user is a collaborator for a repo.
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param collaborator [String] Collaborator GitHub username to check.
|
||||
# @return [Boolean] True if user is a collaborator, false otherwise.
|
||||
# @see https://developer.github.com/v3/repos/collaborators/#check-if-a-user-is-a-collaborator
|
||||
# @example
|
||||
# @client.collaborator?('octokit/octokit.rb', 'holman')
|
||||
def collaborator?(repo, collaborator, options = {})
|
||||
boolean_from_response :get, "#{Repository.path repo}/collaborators/#{collaborator}", options
|
||||
end
|
||||
|
||||
# Get a user's permission level for a repo.
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @return [Sawyer::Resource] Hash representing the user's permission level for the given repository
|
||||
# @see https://developer.github.com/v3/repos/collaborators/#review-a-users-permission-level
|
||||
# @example
|
||||
# @client.permission_level('octokit/octokit.rb', 'lizzhale')
|
||||
def permission_level(repo, collaborator, options = {})
|
||||
get "#{Repository.path repo}/collaborators/#{collaborator}/permission", options
|
||||
end
|
||||
|
||||
# List teams for a repo
|
||||
#
|
||||
# Requires authenticated client that is an owner or collaborator of the repo.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing teams.
|
||||
# @see https://developer.github.com/v3/repos/#list-teams
|
||||
# @example
|
||||
# @client.repository_teams('octokit/pengwynn')
|
||||
# @example
|
||||
# @client.repo_teams('octokit/pengwynn')
|
||||
# @example
|
||||
# @client.teams('octokit/pengwynn')
|
||||
def repository_teams(repo, options = {})
|
||||
paginate "#{Repository.path repo}/teams", options
|
||||
end
|
||||
alias repo_teams repository_teams
|
||||
alias teams repository_teams
|
||||
|
||||
# List all topics for a repository
|
||||
#
|
||||
# Requires authenticated client for private repos.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @return [Sawyer::Resource] representing the topics for given repo
|
||||
# @see https://developer.github.com/v3/repos/#list-all-topics-for-a-repository
|
||||
# @example List topics for octokit/octokit.rb
|
||||
# Octokit.topics('octokit/octokit.rb')
|
||||
# @example List topics for octokit/octokit.rb
|
||||
# client.topics('octokit/octokit.rb')
|
||||
def topics(repo, options = {})
|
||||
paginate "#{Repository.path repo}/topics", options
|
||||
end
|
||||
|
||||
# Replace all topics for a repository
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A Github repository
|
||||
# @param names [Array] An array of topics to add to the repository.
|
||||
# @return [Sawyer::Resource] representing the replaced topics for given repo
|
||||
# @see https://developer.github.com/v3/repos/#replace-all-topics-for-a-repository
|
||||
# @example Replace topics for octokit/octokit.rb
|
||||
# client.replace_all_topics('octokit/octokit.rb', ['octocat', 'atom', 'electron', 'API'])
|
||||
# @example Clear all topics for octokit/octokit.rb
|
||||
# client.replace_all_topics('octokit/octokit.rb', [])
|
||||
def replace_all_topics(repo, names, options = {})
|
||||
put "#{Repository.path repo}/topics", options.merge(names: names)
|
||||
end
|
||||
|
||||
# List contributors to a repo
|
||||
#
|
||||
# Requires authenticated client for private repos.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param anon [Boolean] Set true to include anonymous contributors.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing users.
|
||||
# @see https://developer.github.com/v3/repos/#list-contributors
|
||||
# @example
|
||||
# Octokit.contributors('octokit/octokit.rb', true)
|
||||
# @example
|
||||
# Octokit.contribs('octokit/octokit.rb')
|
||||
# @example
|
||||
# @client.contribs('octokit/octokit.rb')
|
||||
def contributors(repo, anon = nil, options = {})
|
||||
options[:anon] = 1 if anon.to_s[/1|true/]
|
||||
paginate "#{Repository.path repo}/contributors", options
|
||||
end
|
||||
alias contribs contributors
|
||||
|
||||
# List stargazers of a repo
|
||||
#
|
||||
# Requires authenticated client for private repos.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing users.
|
||||
# @see https://developer.github.com/v3/activity/starring/#list-stargazers
|
||||
# @example
|
||||
# Octokit.stargazers('octokit/octokit.rb')
|
||||
# @example
|
||||
# @client.stargazers('octokit/octokit.rb')
|
||||
def stargazers(repo, options = {})
|
||||
paginate "#{Repository.path repo}/stargazers", options
|
||||
end
|
||||
|
||||
# @deprecated Use {#stargazers} instead
|
||||
#
|
||||
# List watchers of repo.
|
||||
#
|
||||
# Requires authenticated client for private repos.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing users.
|
||||
# @see https://developer.github.com/v3/repos/watching/#list-watchers
|
||||
# @example
|
||||
# Octokit.watchers('octokit/octokit.rb')
|
||||
# @example
|
||||
# @client.watchers('octokit/octokit.rb')
|
||||
def watchers(repo, options = {})
|
||||
paginate "#{Repository.path repo}/watchers", options
|
||||
end
|
||||
|
||||
# List forks
|
||||
#
|
||||
# Requires authenticated client for private repos.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing repos.
|
||||
# @see https://developer.github.com/v3/repos/forks/#list-forks
|
||||
# @example
|
||||
# Octokit.forks('octokit/octokit.rb')
|
||||
# @example
|
||||
# Octokit.network('octokit/octokit.rb')
|
||||
# @example
|
||||
# @client.forks('octokit/octokit.rb')
|
||||
def forks(repo, options = {})
|
||||
paginate "#{Repository.path repo}/forks", options
|
||||
end
|
||||
alias network forks
|
||||
|
||||
# List languages of code in the repo.
|
||||
#
|
||||
# Requires authenticated client for private repos.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @return [Array<Sawyer::Resource>] Array of Hashes representing languages.
|
||||
# @see https://developer.github.com/v3/repos/#list-languages
|
||||
# @example
|
||||
# Octokit.languages('octokit/octokit.rb')
|
||||
# @example
|
||||
# @client.languages('octokit/octokit.rb')
|
||||
def languages(repo, options = {})
|
||||
paginate "#{Repository.path repo}/languages", options
|
||||
end
|
||||
|
||||
# List tags
|
||||
#
|
||||
# Requires authenticated client for private repos.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing tags.
|
||||
# @see https://developer.github.com/v3/repos/#list-tags
|
||||
# @example
|
||||
# Octokit.tags('octokit/octokit.rb')
|
||||
# @example
|
||||
# @client.tags('octokit/octokit.rb')
|
||||
def tags(repo, options = {})
|
||||
paginate "#{Repository.path repo}/tags", options
|
||||
end
|
||||
|
||||
# List branches
|
||||
#
|
||||
# Requires authenticated client for private repos.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing branches.
|
||||
# @see https://developer.github.com/v3/repos/#list-branches
|
||||
# @example
|
||||
# Octokit.branches('octokit/octokit.rb')
|
||||
# @example
|
||||
# @client.branches('octokit/octokit.rb')
|
||||
def branches(repo, options = {})
|
||||
paginate "#{Repository.path repo}/branches", options
|
||||
end
|
||||
|
||||
# Get a single branch from a repository
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param branch [String] Branch name
|
||||
# @return [Sawyer::Resource] The branch requested, if it exists
|
||||
# @see https://developer.github.com/v3/repos/#get-branch
|
||||
# @example Get branch 'master` from octokit/octokit.rb
|
||||
# Octokit.branch("octokit/octokit.rb", "master")
|
||||
def branch(repo, branch, options = {})
|
||||
get "#{Repository.path repo}/branches/#{CGI.escape(branch)}", options
|
||||
end
|
||||
alias get_branch branch
|
||||
|
||||
# Lock a single branch from a repository
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param branch [String] Branch name
|
||||
# @option options [Hash] :required_status_checks If not null, the following keys are required:
|
||||
# <tt>:enforce_admins [boolean] Enforce required status checks for repository administrators.</tt>
|
||||
# <tt>:strict [boolean] Require branches to be up to date before merging.</tt>
|
||||
# <tt>:contexts [Array] The list of status checks to require in order to merge into this branch</tt>
|
||||
#
|
||||
# @option options [Hash] :restrictions If not null, the following keys are required:
|
||||
# <tt>:users [Array] The list of user logins with push access</tt>
|
||||
# <tt>:teams [Array] The list of team slugs with push access</tt>.
|
||||
#
|
||||
# Teams and users restrictions are only available for organization-owned repositories.
|
||||
# @return [Sawyer::Resource] The protected branch
|
||||
# @see https://developer.github.com/v3/repos/#enabling-and-disabling-branch-protection
|
||||
# @example
|
||||
# @client.protect_branch('octokit/octokit.rb', 'master', foo)
|
||||
def protect_branch(repo, branch, options = {})
|
||||
options[:restrictions] ||= nil
|
||||
options[:required_status_checks] ||= nil
|
||||
put "#{Repository.path repo}/branches/#{branch}/protection", options
|
||||
end
|
||||
|
||||
# Get branch protection summary
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param branch [String] Branch name
|
||||
# @return [Sawyer::Resource, nil] Branch protection summary or nil if the branch
|
||||
# is not protected
|
||||
# @see https://developer.github.com/v3/repos/branches/#get-branch-protection
|
||||
# @example
|
||||
# @client.branch_protection('octokit/octokit.rb', 'master')
|
||||
def branch_protection(repo, branch, options = {})
|
||||
get "#{Repository.path repo}/branches/#{branch}/protection", options
|
||||
rescue Octokit::BranchNotProtected
|
||||
nil
|
||||
end
|
||||
|
||||
# Unlock a single branch from a repository
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param branch [String] Branch name
|
||||
# @return [Sawyer::Resource] The unprotected branch
|
||||
# @see https://developer.github.com/v3/repos/#enabling-and-disabling-branch-protection
|
||||
# @example
|
||||
# @client.unprotect_branch('octokit/octokit.rb', 'master')
|
||||
def unprotect_branch(repo, branch, options = {})
|
||||
boolean_from_response :delete, "#{Repository.path repo}/branches/#{branch}/protection", options
|
||||
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.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing users.
|
||||
# @see https://developer.github.com/v3/issues/assignees/#list-assignees
|
||||
# @example
|
||||
# Octokit.repository_assignees('octokit/octokit.rb')
|
||||
# @example
|
||||
# Octokit.repo_assignees('octokit/octokit.rb')
|
||||
# @example
|
||||
# @client.repository_assignees('octokit/octokit.rb')
|
||||
def repository_assignees(repo, options = {})
|
||||
paginate "#{Repository.path repo}/assignees", options
|
||||
end
|
||||
alias repo_assignees repository_assignees
|
||||
|
||||
# Check to see if a particular user is an assignee for a repository.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param assignee [String] User login to check
|
||||
# @return [Boolean] True if assignable on project, false otherwise.
|
||||
# @see https://developer.github.com/v3/issues/assignees/#check-assignee
|
||||
# @example
|
||||
# Octokit.check_assignee('octokit/octokit.rb', 'andrew')
|
||||
def check_assignee(repo, assignee, options = {})
|
||||
boolean_from_response :get, "#{Repository.path repo}/assignees/#{assignee}", options
|
||||
end
|
||||
|
||||
# List watchers subscribing to notifications for a repo
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @return [Array<Sawyer::Resource>] Array of users watching.
|
||||
# @see https://developer.github.com/v3/activity/watching/#list-watchers
|
||||
# @example
|
||||
# @client.subscribers("octokit/octokit.rb")
|
||||
def subscribers(repo, options = {})
|
||||
paginate "#{Repository.path repo}/subscribers", options
|
||||
end
|
||||
|
||||
# Get a repository subscription
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @return [Sawyer::Resource] Repository subscription.
|
||||
# @see https://developer.github.com/v3/activity/watching/#get-a-repository-subscription
|
||||
# @example
|
||||
# @client.subscription("octokit/octokit.rb")
|
||||
def subscription(repo, options = {})
|
||||
get "#{Repository.path repo}/subscription", options
|
||||
end
|
||||
|
||||
# Update repository subscription
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param options [Hash]
|
||||
#
|
||||
# @option options [Boolean] :subscribed Determines if notifications
|
||||
# should be received from this repository.
|
||||
# @option options [Boolean] :ignored Deterimines if all notifications
|
||||
# should be blocked from this repository.
|
||||
# @return [Sawyer::Resource] Updated repository subscription.
|
||||
# @see https://developer.github.com/v3/activity/watching/#set-a-repository-subscription
|
||||
# @example Subscribe to notifications for a repository
|
||||
# @client.update_subscription("octokit/octokit.rb", {subscribed: true})
|
||||
def update_subscription(repo, options = {})
|
||||
put "#{Repository.path repo}/subscription", options
|
||||
end
|
||||
|
||||
# Delete a repository subscription
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @return [Boolean] True if subscription deleted, false otherwise.
|
||||
# @see https://developer.github.com/v3/activity/watching/#delete-a-repository-subscription
|
||||
#
|
||||
# @example
|
||||
# @client.delete_subscription("octokit/octokit.rb")
|
||||
def delete_subscription(repo, options = {})
|
||||
boolean_from_response :delete, "#{Repository.path repo}/subscription", options
|
||||
end
|
||||
|
||||
# Create a repository dispatch event
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param event_type [String] A custom webhook event name.
|
||||
# @option options [Hash] :client_payload payload with extra information
|
||||
# about the webhook event that your action or worklow may use.
|
||||
#
|
||||
# @return [Boolean] True if event was dispatched, false otherwise.
|
||||
# @see https://developer.github.com/v3/repos/#create-a-repository-dispatch-event
|
||||
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 = {})
|
||||
boolean_from_response(:get, "#{Repository.path repo}/vulnerability-alerts", options)
|
||||
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 = {})
|
||||
boolean_from_response(:put, "#{Repository.path repo}/vulnerability-alerts", options)
|
||||
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 = {})
|
||||
boolean_from_response(:delete, "#{Repository.path repo}/vulnerability-alerts", options)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,96 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Repository Invitations API
|
||||
#
|
||||
# @see https://developer.github.com/v3/repos/invitations/
|
||||
module RepositoryInvitations
|
||||
# Invite a user to a repository
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param user [String] User GitHub username to add
|
||||
# @return [Sawyer::Resource] The repository invitation
|
||||
# @see https://developer.github.com/v3/repos/collaborators/#add-user-as-a-collaborator
|
||||
def invite_user_to_repository(repo, user, options = {})
|
||||
put "#{Repository.path repo}/collaborators/#{user}", options
|
||||
end
|
||||
alias invite_user_to_repo invite_user_to_repository
|
||||
|
||||
# List all invitations for a repository
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @return [Array<Sawyer::Resource>] A list of invitations
|
||||
# @see https://developer.github.com/v3/repos/invitations/#list-invitations-for-a-repository
|
||||
def repository_invitations(repo, options = {})
|
||||
paginate "#{Repository.path repo}/invitations", options
|
||||
end
|
||||
alias repo_invitations repository_invitations
|
||||
|
||||
# Delete an invitation for a repository
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param invitation_id [Integer] The id of the invitation
|
||||
# @return [Boolean] True if the invitation was successfully deleted
|
||||
# @see https://developer.github.com/v3/repos/invitations/#delete-a-repository-invitation
|
||||
def delete_repository_invitation(repo, invitation_id, options = {})
|
||||
boolean_from_response :delete, "#{Repository.path repo}/invitations/#{invitation_id}", options
|
||||
end
|
||||
alias delete_repo_invitation delete_repository_invitation
|
||||
|
||||
# Update an invitation for a repository
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param invitation_id [Integer] The id of the invitation
|
||||
# @return [Sawyer::Resource] The updated repository invitation
|
||||
# @see https://developer.github.com/v3/repos/invitations/#update-a-repository-invitation
|
||||
def update_repository_invitation(repo, invitation_id, options = {})
|
||||
patch "#{Repository.path repo}/invitations/#{invitation_id}", options
|
||||
end
|
||||
alias update_repo_invitation update_repository_invitation
|
||||
|
||||
# List all repository invitations for the user
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] The users repository invitations
|
||||
# @see https://developer.github.com/v3/repos/invitations/#list-a-users-repository-invitations
|
||||
def user_repository_invitations(options = {})
|
||||
paginate '/user/repository_invitations', options
|
||||
end
|
||||
alias user_repo_invitations user_repository_invitations
|
||||
|
||||
# Accept a repository invitation
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param invitation_id [Integer] The id of the invitation
|
||||
# @return [Boolean] True if the acceptance of the invitation was successful
|
||||
# @see https://developer.github.com/v3/repos/invitations/#accept-a-repository-invitation
|
||||
def accept_repository_invitation(invitation_id, options = {})
|
||||
patch "/user/repository_invitations/#{invitation_id}", options
|
||||
end
|
||||
alias accept_repo_invitation accept_repository_invitation
|
||||
|
||||
# Decline a repository invitation
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param invitation_id [Integer] The id of the invitation
|
||||
# @return [Boolean] True if the acceptance of the invitation was successful
|
||||
# @see https://developer.github.com/v3/repos/invitations/#decline-a-repository-invitation
|
||||
def decline_repository_invitation(invitation_id, options = {})
|
||||
boolean_from_response :delete, "/user/repository_invitations/#{invitation_id}", options
|
||||
end
|
||||
alias decline_invitation decline_repository_invitation
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,227 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Reviews API
|
||||
#
|
||||
# @see https://developer.github.com/v3/pulls/reviews/
|
||||
module Reviews
|
||||
# List reviews on a pull request
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param number [Integer] Number ID of the pull request
|
||||
# @see https://developer.github.com/v3/pulls/reviews/#list-reviews-on-a-pull-request
|
||||
#
|
||||
# @example
|
||||
# @client.pull_request_reviews('octokit/octokit.rb', 2)
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] Array of Hashes representing the reviews
|
||||
def pull_request_reviews(repo, number, options = {})
|
||||
paginate "#{Repository.path repo}/pulls/#{number}/reviews", options
|
||||
end
|
||||
|
||||
# Get a single review
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param number [Integer] Number ID of the pull request
|
||||
# @param review [Integer] The id of the review
|
||||
# @see https://developer.github.com/v3/pulls/reviews/#get-a-single-review
|
||||
#
|
||||
# @example
|
||||
# @client.pull_request_review('octokit/octokit.rb', 825, 6505518)
|
||||
#
|
||||
# @return [Sawyer::Resource] Hash representing the review
|
||||
def pull_request_review(repo, number, review, options = {})
|
||||
get "#{Repository.path repo}/pulls/#{number}/reviews/#{review}", options
|
||||
end
|
||||
|
||||
# Delete a pending review
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param number [Integer] Number ID of the pull request
|
||||
# @param review [Integer] The id of the review
|
||||
# @see https://developer.github.com/v3/pulls/reviews/#delete-a-pending-review
|
||||
#
|
||||
# @example
|
||||
# @client.delete_pull_request_review('octokit/octokit.rb', 825, 6505518)
|
||||
#
|
||||
# @return [Sawyer::Resource] Hash representing the deleted review
|
||||
def delete_pull_request_review(repo, number, review, options = {})
|
||||
delete "#{Repository.path repo}/pulls/#{number}/reviews/#{review}", options
|
||||
end
|
||||
|
||||
# Get comments for a single review
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param number [Integer] Number ID of the pull request
|
||||
# @param review [Integer] The id of the review
|
||||
# @see https://developer.github.com/v3/pulls/reviews/#get-comments-for-a-single-review
|
||||
#
|
||||
# @example
|
||||
# @client.pull_request_review_comments('octokit/octokit.rb', 825, 6505518)
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] Array of Hashes representing the review comments
|
||||
def pull_request_review_comments(repo, number, review, options = {})
|
||||
paginate "#{Repository.path repo}/pulls/#{number}/reviews/#{review}/comments", options
|
||||
end
|
||||
|
||||
# Create a pull request review
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param number [Integer] Number ID of the pull request
|
||||
# @param options [Hash] Method options
|
||||
# @option options [String] :event The review action (event) to perform;
|
||||
# can be one of APPROVE, REQUEST_CHANGES, or COMMENT.
|
||||
# If left blank, the review is left PENDING.
|
||||
# @option options [String] :body The body text of the pull request review
|
||||
# @option options [Array<Hash>] :comments Comments part of the review
|
||||
# @option comments [String] :path The path to the file being commented on
|
||||
# @option comments [Integer] :position The position in the file to be commented on
|
||||
# @option comments [String] :body Body of the comment
|
||||
# @see https://developer.github.com/v3/pulls/reviews/#create-a-pull-request-review
|
||||
#
|
||||
# @example
|
||||
# comments = [
|
||||
# { path: '.travis.yml', position: 10, body: 'ruby-head is under development that is not stable.' },
|
||||
# { path: '.travis.yml', position: 32, body: 'ruby-head is also required in thervm section.' },
|
||||
# ]
|
||||
# options = { event: 'REQUEST_CHANGES', comments: comments }
|
||||
# @client.create_pull_request_review('octokit/octokit.rb', 844, options)
|
||||
#
|
||||
# @return [Sawyer::Resource>] Hash respresenting the review
|
||||
def create_pull_request_review(repo, number, options = {})
|
||||
post "#{Repository.path repo}/pulls/#{number}/reviews", options
|
||||
end
|
||||
|
||||
# Submit a pull request review
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param number [Integer] Number ID of the pull request
|
||||
# @param review [Integer] The id of the review
|
||||
# @param event [String] The review action (event) to perform; can be one of
|
||||
# APPROVE, REQUEST_CHANGES, or COMMENT.
|
||||
# @param options [Hash] Method options
|
||||
# @option options [String] :body The body text of the pull request review
|
||||
# @see https://developer.github.com/v3/pulls/reviews/#submit-a-pull-request-review
|
||||
#
|
||||
# @example
|
||||
# @client.submit_pull_request_review('octokit/octokit.rb', 825, 6505518,
|
||||
# 'APPROVE', body: 'LGTM!')
|
||||
#
|
||||
# @return [Sawyer::Resource] Hash respresenting the review
|
||||
def submit_pull_request_review(repo, number, review, event, options = {})
|
||||
options = options.merge(event: event)
|
||||
post "#{Repository.path repo}/pulls/#{number}/reviews/#{review}/events", options
|
||||
end
|
||||
|
||||
# Dismiss a pull request review
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param number [Integer] Number ID of the pull request
|
||||
# @param review [Integer] The id of the review
|
||||
# @param message [String] The message for the pull request review dismissal
|
||||
# @see https://developer.github.com/v3/pulls/reviews/#dismiss-a-pull-request-review
|
||||
#
|
||||
# @example
|
||||
# @client.dismiss_pull_request_review('octokit/octokit.rb', 825, 6505518, 'The message.')
|
||||
#
|
||||
# @return [Sawyer::Resource] Hash representing the dismissed review
|
||||
def dismiss_pull_request_review(repo, number, review, message, options = {})
|
||||
options = options.merge(message: message)
|
||||
put "#{Repository.path repo}/pulls/#{number}/reviews/#{review}/dismissals", options
|
||||
end
|
||||
|
||||
# List review requests
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param number [Integer] Number ID of the pull request
|
||||
# @see https://developer.github.com/v3/pulls/review_requests/#list-review-requests
|
||||
#
|
||||
# @example
|
||||
# @client.pull_request_review_requests('octokit/octokit.rb', 2)
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] Array of Hashes representing the review requests
|
||||
def pull_request_review_requests(repo, number, options = {})
|
||||
paginate "#{Repository.path repo}/pulls/#{number}/requested_reviewers", options
|
||||
end
|
||||
|
||||
# Create a review request
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param number [Integer] Number ID of the pull request
|
||||
# @param reviewers [Hash] :reviewers [Array<String>] An array of user logins
|
||||
# @param options [Hash] :team_reviewers [Array<String>] An array of team slugs
|
||||
# @see https://developer.github.com/v3/pulls/review_requests/#create-a-review-request
|
||||
#
|
||||
# @example
|
||||
# @client.request_pull_request_review('octokit/octokit.rb', 2, reviewers: ['soudy'])
|
||||
#
|
||||
# @return [Sawyer::Resource>] Hash respresenting the pull request
|
||||
def request_pull_request_review(repo, number, reviewers = {}, options = {})
|
||||
# TODO(5.0): remove deprecated behavior
|
||||
if reviewers.is_a?(Array)
|
||||
octokit_warn(
|
||||
'Deprecated: Octokit::Client#request_pull_request_review ' \
|
||||
"no longer takes a separate :reviewers argument.\n" \
|
||||
'Please update your call to pass :reviewers and :team_reviewers as part of the options hash.'
|
||||
)
|
||||
options = options.merge(reviewers: reviewers)
|
||||
else
|
||||
options = options.merge(reviewers)
|
||||
end
|
||||
|
||||
post "#{Repository.path repo}/pulls/#{number}/requested_reviewers", options
|
||||
end
|
||||
|
||||
# Delete a review request
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param id [Integer] The id of the pull request
|
||||
# @param reviewers [Hash] :reviewers [Array] An array of user logins
|
||||
# @param options [Hash] :team_reviewers [Array] An array of team slugs
|
||||
#
|
||||
# @see https://developer.github.com/v3/pulls/review_requests/#delete-a-review-request
|
||||
#
|
||||
# @example
|
||||
# options = {
|
||||
# "reviewers" => [ "octocat", "hubot", "other_user" ],
|
||||
# "team_reviewers" => [ "justice-league" ]
|
||||
# }
|
||||
# @client.delete_pull_request_review_request('octokit/octokit.rb', 2, options)
|
||||
#
|
||||
# @return [Sawyer::Resource>] Hash representing the pull request
|
||||
def delete_pull_request_review_request(repo, id, reviewers = {}, options = {})
|
||||
# TODO(5.0): remove deprecated behavior
|
||||
if !reviewers.empty? && !options.empty?
|
||||
octokit_warn(
|
||||
'Deprecated: Octokit::Client#delete_pull_request_review_request ' \
|
||||
"no longer takes a separate :reviewers argument.\n" \
|
||||
'Please update your call to pass :reviewers and :team_reviewers as part of the options hash.'
|
||||
)
|
||||
end
|
||||
# For backwards compatibility, this endpoint can be called with a separate reviewers hash.
|
||||
# If not called with a separate hash, then 'reviewers' is, in fact, 'options'.
|
||||
options = options.merge(reviewers)
|
||||
delete "#{Repository.path repo}/pulls/#{id}/requested_reviewers", options
|
||||
end
|
||||
|
||||
# Update a review request comment
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param number [Integer] Number ID of the pull request
|
||||
# @param review [Integer] The id of the review
|
||||
# @param body [String] body text of the pull request review.
|
||||
# @param options [Hash] Method options
|
||||
# @see https://developer.github.com/v3/pulls/reviews/#update-a-pull-request-review
|
||||
#
|
||||
# @example
|
||||
# @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.')
|
||||
#
|
||||
# @return [Sawyer::Resource] Hash representing the review comment
|
||||
def update_pull_request_review(repo, number, review, body, options = {})
|
||||
options[:body] = body
|
||||
put "#{Repository.path repo}/pulls/#{number}/reviews/#{review}", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the unpublished Octocat API
|
||||
module Say
|
||||
# Return a nifty ASCII Octocat with GitHub wisdom
|
||||
# or your own
|
||||
#
|
||||
# @return [String]
|
||||
def say(text = nil, options = {})
|
||||
options[:s] = text if text
|
||||
get 'octocat', options
|
||||
end
|
||||
alias octocat say
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,105 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Search API
|
||||
#
|
||||
# @see https://developer.github.com/v3/search/
|
||||
module Search
|
||||
# Search code
|
||||
#
|
||||
# @param query [String] Search term and qualifiers
|
||||
# @param options [Hash] Sort and pagination options
|
||||
# @option options [String] :sort Sort field
|
||||
# @option options [String] :order Sort order (asc or desc)
|
||||
# @option options [Integer] :page Page of paginated results
|
||||
# @option options [Integer] :per_page Number of items per page
|
||||
# @return [Sawyer::Resource] Search results object
|
||||
# @see https://developer.github.com/v3/search/#search-code
|
||||
def search_code(query, options = {})
|
||||
search 'search/code', query, options
|
||||
end
|
||||
|
||||
# Search commits
|
||||
#
|
||||
# @param query [String] Search terms and qualifiers
|
||||
# @param options [Hash] Sort and pagination options
|
||||
# @option options [String] :sort Sort field
|
||||
# @option options [String] :order Sort order (asc or desc)
|
||||
# @option options [Integer] :page Page of paginated results
|
||||
# @option options [Integer] :per_page Number of items per page
|
||||
# @return [Sawyer::Resource] Search results object
|
||||
# @see https://developer.github.com/v3/search/#search-commits
|
||||
def search_commits(query, options = {})
|
||||
search 'search/commits', query, options
|
||||
end
|
||||
|
||||
# Search issues
|
||||
#
|
||||
# @param query [String] Search term and qualifiers
|
||||
# @param options [Hash] Sort and pagination options
|
||||
# @option options [String] :sort Sort field
|
||||
# @option options [String] :order Sort order (asc or desc)
|
||||
# @option options [Integer] :page Page of paginated results
|
||||
# @option options [Integer] :per_page Number of items per page
|
||||
# @return [Sawyer::Resource] Search results object
|
||||
# @see https://developer.github.com/v3/search/#search-issues-and-pull-requests
|
||||
# @see https://docs.github.com/en/rest/search#limitations-on-query-length
|
||||
def search_issues(query, options = {})
|
||||
search 'search/issues', query, options
|
||||
end
|
||||
|
||||
# Search repositories
|
||||
#
|
||||
# @param query [String] Search term and qualifiers
|
||||
# @param options [Hash] Sort and pagination options
|
||||
# @option options [String] :sort Sort field
|
||||
# @option options [String] :order Sort order (asc or desc)
|
||||
# @option options [Integer] :page Page of paginated results
|
||||
# @option options [Integer] :per_page Number of items per page
|
||||
# @return [Sawyer::Resource] Search results object
|
||||
# @see https://developer.github.com/v3/search/#search-repositories
|
||||
def search_repositories(query, options = {})
|
||||
search 'search/repositories', query, options
|
||||
end
|
||||
alias search_repos search_repositories
|
||||
|
||||
# Search topics
|
||||
#
|
||||
# @param query [String] Search term and qualifiers
|
||||
# @param options [Hash] Sort and pagination options
|
||||
# @option options [String] :sort Sort field
|
||||
# @option options [String] :order Sort order (asc or desc)
|
||||
# @option options [Integer] :page Page of paginated results
|
||||
# @option options [Integer] :per_page Number of items per page
|
||||
# @return [Sawyer::Resource] Search results object
|
||||
# @see https://developer.github.com/v3/search/#search-topics
|
||||
def search_topics(query, options = {})
|
||||
search 'search/topics', query, options
|
||||
end
|
||||
|
||||
# Search users
|
||||
#
|
||||
# @param query [String] Search term and qualifiers
|
||||
# @param options [Hash] Sort and pagination options
|
||||
# @option options [String] :sort Sort field
|
||||
# @option options [String] :order Sort order (asc or desc)
|
||||
# @option options [Integer] :page Page of paginated results
|
||||
# @option options [Integer] :per_page Number of items per page
|
||||
# @return [Sawyer::Resource] Search results object
|
||||
# @see https://developer.github.com/v3/search/#search-users
|
||||
def search_users(query, options = {})
|
||||
search 'search/users', query, options
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def search(path, query, options = {})
|
||||
opts = options.merge(q: query)
|
||||
paginate(path, opts) do |data, last_response|
|
||||
data.items.concat last_response.data.items
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,48 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the GitHub Status API
|
||||
#
|
||||
# @see https://status.github.com/api
|
||||
module ServiceStatus
|
||||
# Root for status API
|
||||
# @private
|
||||
SUMMARY_ROOT = 'https://www.githubstatus.com/api/v2/summary.json'
|
||||
STATUS_ROOT = 'https://www.githubstatus.com/api/v2/status.json'
|
||||
COMPONENTS_ROOT = 'https://www.githubstatus.com/api/v2/components.json'
|
||||
|
||||
# Returns a summary with the current status and the last status messages.
|
||||
#
|
||||
# @return [<Sawyer::Resource>] GitHub status summary
|
||||
# @see https://www.githubstatus.com/api#summory
|
||||
def github_status_summary
|
||||
get(SUMMARY_ROOT)
|
||||
end
|
||||
|
||||
# Returns the current system status
|
||||
#
|
||||
# @return [Sawyer::Resource] GitHub status
|
||||
# @see https://www.githubstatus.com/api#status
|
||||
def github_status
|
||||
get(STATUS_ROOT)
|
||||
end
|
||||
|
||||
# Returns the last human communication, status, and timestamp.
|
||||
#
|
||||
# @return [Sawyer::Resource] GitHub status last message
|
||||
# @see https://www.githubstatus.com/api/#components
|
||||
def github_status_last_message
|
||||
get(COMPONENTS_ROOT).components.first
|
||||
end
|
||||
|
||||
# Returns the most recent human communications with status and timestamp.
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] GitHub status messages
|
||||
# @see https://www.githubstatus.com/api#components
|
||||
def github_status_messages
|
||||
get(COMPONENTS_ROOT).components
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,156 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Source Import API
|
||||
#
|
||||
# @see https://developer.github.com/v3/migration/source_imports
|
||||
module SourceImport
|
||||
# Start a source import to a GitHub repository using GitHub Importer.
|
||||
#
|
||||
# @overload start_source_import(repo, vcs, vcs_url, options = {})
|
||||
# @deprecated
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param vcs [String] The originating VCS type. Can be one of "subversion", "git", "mercurial", or "tfvc".
|
||||
# @param vcs_url [String] The URL of the originating repository.
|
||||
# @param options [Hash]
|
||||
# @option options [String] :vcs_username If authentication is required, the username to provide to vcs_url.
|
||||
# @option options [String] :vcs_password If authentication is required, the password to provide to vcs_url.
|
||||
# @option options [String] :tfvc_project For a tfvc import, the name of the project that is being imported.
|
||||
# @overload start_source_import(repo, vcs_url, options = {})
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param vcs_url [String] The URL of the originating repository.
|
||||
# @param options [Hash]
|
||||
# @param options [String] :vcs The originating VCS type. Can be one of "subversion", "git", "mercurial", or "tfvc".
|
||||
# @option options [String] :vcs_username If authentication is required, the username to provide to vcs_url.
|
||||
# @option options [String] :vcs_password If authentication is required, the password to provide to vcs_url.
|
||||
# @option options [String] :tfvc_project For a tfvc import, the name of the project that is being imported.
|
||||
# @return [Sawyer::Resource] Hash representing the repository import
|
||||
# @see https://developer.github.com/v3/migration/source_imports/#start-an-import
|
||||
#
|
||||
# @example
|
||||
# @client.start_source_import("octokit/octokit.rb", "http://svn.mycompany.com/svn/myproject", {
|
||||
# :vcs => "subversion",
|
||||
# :vcs_username" => "octocat",
|
||||
# :vcs_password => "secret"
|
||||
# })
|
||||
def start_source_import(*args)
|
||||
arguments = Octokit::RepoArguments.new(args)
|
||||
vcs_url = arguments.pop
|
||||
vcs = arguments.pop
|
||||
if vcs
|
||||
octokit_warn 'Octokit#start_source_import vcs parameter is now an option, please update your call before the next major Octokit version update.'
|
||||
arguments.options.merge!(vcs: vcs)
|
||||
end
|
||||
options = arguments.options.merge(vcs_url: vcs_url)
|
||||
put "#{Repository.path arguments.repo}/import", options
|
||||
end
|
||||
|
||||
# View the progress of an import.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @return [Sawyer::Resource] Hash representing the progress of the import
|
||||
# @see https://developer.github.com/v3/migration/source_imports/#get-import-progress
|
||||
#
|
||||
# @example
|
||||
# @client.source_import_progress("octokit/octokit.rb")
|
||||
def source_import_progress(repo, options = {})
|
||||
get "#{Repository.path repo}/import", options
|
||||
end
|
||||
|
||||
# Update source import with authentication or project choice
|
||||
# Restart source import if no options are passed
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @return [Sawyer::Resource] Hash representing the repository import
|
||||
# @see https://developer.github.com/v3/migration/source_imports/#update-existing-import
|
||||
# @option options [String] :vcs_username If authentication is required, the username to provide to vcs_url.
|
||||
# @option options [String] :vcs_password If authentication is required, the password to provide to vcs_url.
|
||||
# @option options [String] To update project choice, please refer to the project_choice array from the progress return hash for the exact attributes.
|
||||
# https://developer.github.com/v3/migration/source_imports/#update-existing-import
|
||||
#
|
||||
# @example
|
||||
# @client.update_source_import("octokit/octokit.rb", {
|
||||
# :vcs_username" => "octocat",
|
||||
# :vcs_password => "secret"
|
||||
# })
|
||||
def update_source_import(repo, options = {})
|
||||
patch "#{Repository.path repo}/import", options
|
||||
end
|
||||
|
||||
# List source import commit authors
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param options [Hash]
|
||||
# @option options [String] :since Only authors found after this id are returned.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing commit_authors.
|
||||
# @see https://developer.github.com/v3/migration/source_imports/#get-commit-authors
|
||||
#
|
||||
# @example
|
||||
# @client.source_import_commit_authors("octokit/octokit.rb")
|
||||
def source_import_commit_authors(repo, options = {})
|
||||
get "#{Repository.path repo}/import/authors", options
|
||||
end
|
||||
|
||||
# Update an author's identity for the import.
|
||||
#
|
||||
# @param author_url [String] The source import API url for the commit author
|
||||
# @param values [Hash] The updated author attributes
|
||||
# @option values [String] :email The new Git author email.
|
||||
# @option values [String] :name The new Git author name.
|
||||
# @return [Sawyer::Resource] Hash representing the updated commit author
|
||||
# @see https://developer.github.com/v3/migration/source_imports/#map-a-commit-author
|
||||
#
|
||||
# @example
|
||||
# author_url = "https://api.github.com/repos/octokit/octokit.rb/import/authors/1"
|
||||
# @client.map_source_import_commit_author(author_url, {
|
||||
# :email => "hubot@github.com",
|
||||
# :name => "Hubot the Robot"
|
||||
# })
|
||||
def map_source_import_commit_author(author_url, values, options = {})
|
||||
options = options.merge(values)
|
||||
patch author_url, options
|
||||
end
|
||||
|
||||
# Stop an import for a repository.
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @return [Boolean] True if the import has been cancelled, false otherwise.
|
||||
# @see https://developer.github.com/v3/migration/source_imports/#cancel-an-import
|
||||
#
|
||||
# @example
|
||||
# @client.cancel_source_import("octokit/octokit.rb")
|
||||
def cancel_source_import(repo, options = {})
|
||||
boolean_from_response :delete, "#{Repository.path repo}/import", options
|
||||
end
|
||||
|
||||
# List source import large files
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param options [Hash]
|
||||
# @option options [Integer] :page Page of paginated results
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing files over 100MB.
|
||||
# @see https://developer.github.com/v3/migration/source_imports/#get-large-files
|
||||
#
|
||||
# @example
|
||||
# @client.source_import_large_files("octokit/octokit.rb")
|
||||
def source_import_large_files(repo, options = {})
|
||||
get "#{Repository.path repo}/import/large_files", options
|
||||
end
|
||||
|
||||
# Set preference for using Git LFS to import files over 100MB
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @param use_lfs [String] Preference for using Git LFS to import large files. Can be one of "opt_in" or "opt_out"
|
||||
# @return [Sawyer::Resource] Hash representing the repository import
|
||||
# @see https://developer.github.com/v3/migration/source_imports/#set-git-lfs-preference
|
||||
#
|
||||
# @example
|
||||
# @client.opt_in_source_import_lfs("octokit/octokit.rb", "opt_in")
|
||||
def set_source_import_lfs_preference(repo, use_lfs, options = {})
|
||||
options = options.merge(use_lfs: use_lfs)
|
||||
patch "#{Repository.path repo}/import/lfs", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,108 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Repository Statistics API
|
||||
#
|
||||
# @see https://developer.github.com/v3/repos/statistics/
|
||||
module Stats
|
||||
# Get contributors list with additions, deletions, and commit counts
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @option retry_timeout [Number] How long Octokit should keep trying to get stats (in seconds)
|
||||
# @option retry_wait [Number] How long Octokit should wait between retries.
|
||||
# @return [Array<Sawyer::Resource>] Array of contributor stats
|
||||
# @see https://developer.github.com/v3/repos/statistics/#get-contributors-list-with-additions-deletions-and-commit-counts
|
||||
# @example Get contributor stats for octokit
|
||||
# @client.contributors_stats('octokit/octokit.rb')
|
||||
def contributors_stats(repo, options = {})
|
||||
get_stats(repo, 'contributors', options)
|
||||
end
|
||||
alias contributor_stats contributors_stats
|
||||
|
||||
# Get the last year of commit activity data
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @option retry_timeout [Number] How long Octokit should keep trying to get stats (in seconds)
|
||||
# @option retry_wait [Number] How long Octokit should wait between retries.
|
||||
# @return [Array<Sawyer::Resource>] The last year of commit activity grouped by
|
||||
# week. The days array is a group of commits per day, starting on Sunday.
|
||||
# @see https://developer.github.com/v3/repos/statistics/#get-the-last-year-of-commit-activity-data
|
||||
# @example Get commit activity for octokit
|
||||
# @client.commit_activity_stats('octokit/octokit.rb')
|
||||
def commit_activity_stats(repo, options = {})
|
||||
get_stats(repo, 'commit_activity', options)
|
||||
end
|
||||
|
||||
# Get the number of additions and deletions per week
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @option retry_timeout [Number] How long Octokit should keep trying to get stats (in seconds)
|
||||
# @option retry_wait [Number] How long Octokit should wait between retries.
|
||||
# @return [Array<Sawyer::Resource>] Weekly aggregate of the number of additions
|
||||
# and deletions pushed to a repository.
|
||||
# @see https://developer.github.com/v3/repos/statistics/#get-the-number-of-additions-and-deletions-per-week
|
||||
# @example Get code frequency stats for octokit
|
||||
# @client.code_frequency_stats('octokit/octokit.rb')
|
||||
def code_frequency_stats(repo, options = {})
|
||||
get_stats(repo, 'code_frequency', options)
|
||||
end
|
||||
|
||||
# Get the weekly commit count for the repo owner and everyone else
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @option retry_timeout [Number] How long Octokit should keep trying to get stats (in seconds)
|
||||
# @option retry_wait [Number] How long Octokit should wait between retries.
|
||||
# @return [Sawyer::Resource] Total commit counts for the owner and total commit
|
||||
# counts in all. all is everyone combined, including the owner in the last
|
||||
# 52 weeks. If you’d like to get the commit counts for non-owners, you can
|
||||
# subtract all from owner.
|
||||
# @see https://developer.github.com/v3/repos/statistics/#get-the-weekly-commit-count-for-the-repository-owner-and-everyone-else
|
||||
# @example Get weekly commit counts for octokit
|
||||
# @client.participation_stats("octokit/octokit.rb")
|
||||
def participation_stats(repo, options = {})
|
||||
get_stats(repo, 'participation', options)
|
||||
end
|
||||
|
||||
# Get the number of commits per hour in each day
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @option retry_timeout [Number] How long Octokit should keep trying to get stats (in seconds)
|
||||
# @option retry_wait [Number] How long Octokit should wait between retries.
|
||||
# @return [Array<Array>] Arrays containing the day number, hour number, and
|
||||
# number of commits
|
||||
# @see https://developer.github.com/v3/repos/statistics/#get-the-number-of-commits-per-hour-in-each-day
|
||||
# @example Get octokit punch card
|
||||
# @octokit.punch_card_stats
|
||||
def punch_card_stats(repo, options = {})
|
||||
get_stats(repo, 'punch_card', options)
|
||||
end
|
||||
alias punch_card punch_card_stats
|
||||
|
||||
private
|
||||
|
||||
# @private Get stats for a repository
|
||||
#
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository
|
||||
# @param metric [String] The metrics you are looking for
|
||||
# @return [Array<Sawyer::Resource> or nil] Stats in metric-specific format, or nil if not yet calculated.
|
||||
# @see https://developer.github.com/v3/repos/statistics/
|
||||
def get_stats(repo, metric, options = {})
|
||||
options = options.dup
|
||||
if retry_timeout = options.delete(:retry_timeout)
|
||||
retry_wait = options.delete(:retry_wait) || 0.5
|
||||
timeout = Time.now + retry_timeout
|
||||
end
|
||||
loop do
|
||||
data = get("#{Repository.path repo}/stats/#{metric}", options)
|
||||
return data if last_response.status == 200
|
||||
return [] if last_response.status == 204
|
||||
return nil unless retry_timeout
|
||||
return nil if Time.now >= timeout
|
||||
|
||||
sleep retry_wait if retry_wait
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,47 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Commit Statuses API
|
||||
#
|
||||
# @see https://developer.github.com/v3/repos/statuses/
|
||||
module Statuses
|
||||
# List all statuses for a given commit
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param sha [String] The SHA1 for the commit
|
||||
# @return [Array<Sawyer::Resource>] A list of statuses
|
||||
# @see https://developer.github.com/v3/repos/statuses/#list-statuses-for-a-specific-ref
|
||||
def statuses(repo, sha, options = {})
|
||||
paginate "#{Repository.path repo}/statuses/#{sha}", options
|
||||
end
|
||||
alias list_statuses statuses
|
||||
|
||||
# Get the combined status for a ref
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] a GitHub repository
|
||||
# @param ref [String] A Sha or Ref to fetch the status of
|
||||
# @return [Sawyer::Resource] The combined status for the commit
|
||||
# @see https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref
|
||||
def combined_status(repo, ref, options = {})
|
||||
get "#{Repository.path repo}/commits/#{ref}/status", options
|
||||
end
|
||||
alias status combined_status
|
||||
|
||||
# Create status for a commit
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @param sha [String] The SHA1 for the commit
|
||||
# @param state [String] The state: pending, success, failure, error
|
||||
# @option options [String] :context A context to differentiate this status from others
|
||||
# @option options [String] :target_url A link to more details about this status
|
||||
# @option options [String] :description A short human-readable description of this status
|
||||
# @return [Sawyer::Resource] A status
|
||||
# @see https://developer.github.com/v3/repos/statuses/#create-a-status
|
||||
def create_status(repo, sha, state, options = {})
|
||||
options = options.merge(state: state)
|
||||
post "#{Repository.path repo}/statuses/#{sha}", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,31 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Method to check scopes
|
||||
#
|
||||
# @see https://developer.github.com/v3/oauth_authorizations/#oauth-authorizations-api
|
||||
module Tokens
|
||||
# Check scopes for a token
|
||||
#
|
||||
# @param token [String] GitHub OAuth token
|
||||
# @param options [Hash] Header params for request
|
||||
# @return [Array<String>] OAuth scopes
|
||||
# @see https://developer.github.com/v3/oauth/#scopes
|
||||
def scopes(token = @access_token, options = {})
|
||||
options = options.dup
|
||||
raise ArgumentError, 'Access token required' if token.nil?
|
||||
|
||||
auth = { 'Authorization' => "token #{token}" }
|
||||
headers = (options.delete(:headers) || {}).merge(auth)
|
||||
|
||||
agent.call(:get, 'user', headers: headers)
|
||||
.headers['X-OAuth-Scopes']
|
||||
.to_s
|
||||
.split(',')
|
||||
.map(&:strip)
|
||||
.sort
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,64 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Traffic API
|
||||
#
|
||||
# @see https://developer.github.com/v3/repos/traffic/
|
||||
module Traffic
|
||||
# Get the top 10 referrers over the last 14 days
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @return [Array<Sawyer::Resource>] List of referrers and stats
|
||||
# @see https://developer.github.com/v3/repos/traffic/#list-referrers
|
||||
# @example
|
||||
# @client.top_referrers('octokit/octokit.rb')
|
||||
def top_referrers(repo, options = {})
|
||||
get "#{Repository.path repo}/traffic/popular/referrers", options
|
||||
end
|
||||
|
||||
# Get the top 10 popular contents over the last 14 days
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub repository
|
||||
# @return [Array<Sawyer::Resource>] List of popular contents
|
||||
# @see https://developer.github.com/v3/repos/traffic/#list-paths
|
||||
# @example
|
||||
# @client.top_paths('octokit/octokit.rb')
|
||||
def top_paths(repo, options = {})
|
||||
get "#{Repository.path repo}/traffic/popular/paths", options
|
||||
end
|
||||
|
||||
# Get the total number of views and breakdown per day or week for the
|
||||
# last 14 days
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub Repository
|
||||
# @option options [String] :per ('day') Views per. <tt>day</tt> or
|
||||
# <tt>week</tt>
|
||||
# @return [Sawyer::Resource] Breakdown of view stats
|
||||
# @see https://developer.github.com/v3/repos/traffic/#views
|
||||
# @example Views per day
|
||||
# @client.views('octokit/octokit.rb')
|
||||
# @example Views per week
|
||||
# @client.views('octokit/octokit.rb', per: 'week')
|
||||
def views(repo, options = {})
|
||||
get "#{Repository.path repo}/traffic/views", options
|
||||
end
|
||||
|
||||
# Get the total number of clones and breakdown per day or week for the
|
||||
# last 14 days
|
||||
#
|
||||
# @param repo [Integer, String, Repository, Hash] A GitHub Repository
|
||||
# @option options [String] :per ('day') Views per. <tt>day</tt> or
|
||||
# <tt>week</tt>
|
||||
# @return [Sawyer::Resource] Breakdown of clone stats
|
||||
# @see https://developer.github.com/v3/repos/traffic/#clones
|
||||
# @example Clones per day
|
||||
# @client.clones('octokit/octokit.rb')
|
||||
# @example Clones per week
|
||||
# @client.clones('octokit/octokit.rb', per: 'week')
|
||||
def clones(repo, options = {})
|
||||
get "#{Repository.path repo}/traffic/clones", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,435 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class Client
|
||||
# Methods for the Users API
|
||||
#
|
||||
# @see https://developer.github.com/v3/users/
|
||||
module Users
|
||||
# List all GitHub users
|
||||
#
|
||||
# This provides a list of every user, in the order that they signed up
|
||||
# for GitHub.
|
||||
#
|
||||
# @param options [Hash] Optional options.
|
||||
# @option options [Integer] :since The integer ID of the last User that
|
||||
# you’ve seen.
|
||||
#
|
||||
# @see https://developer.github.com/v3/users/#get-all-users
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] List of GitHub users.
|
||||
def all_users(options = {})
|
||||
paginate 'users', options
|
||||
end
|
||||
|
||||
# Get a single user
|
||||
#
|
||||
# @param user [Integer, String] GitHub user login or id.
|
||||
# @return [Sawyer::Resource]
|
||||
# @see https://developer.github.com/v3/users/#get-a-single-user
|
||||
# @see https://developer.github.com/v3/users/#get-the-authenticated-user
|
||||
# @example
|
||||
# Octokit.user("sferik")
|
||||
def user(user = nil, options = {})
|
||||
get User.path(user), options
|
||||
end
|
||||
|
||||
# Retrieve the access_token.
|
||||
#
|
||||
# @param code [String] Authorization code generated by GitHub.
|
||||
# @param app_id [String] Client Id we received when our application was registered with GitHub. Defaults to client_id.
|
||||
# @param app_secret [String] Client Secret we received when our application was registered with GitHub. Defaults to client_secret.
|
||||
# @return [Sawyer::Resource] Hash holding the access token.
|
||||
# @see https://developer.github.com/v3/oauth/#web-application-flow
|
||||
# @example
|
||||
# Octokit.exchange_code_for_token('aaaa', 'xxxx', 'yyyy', {:accept => 'application/json'})
|
||||
def exchange_code_for_token(code, app_id = client_id, app_secret = client_secret, options = {})
|
||||
options = options.merge({
|
||||
code: code,
|
||||
client_id: app_id,
|
||||
client_secret: app_secret,
|
||||
headers: {
|
||||
content_type: 'application/json',
|
||||
accept: 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
post "#{web_endpoint}login/oauth/access_token", options
|
||||
end
|
||||
|
||||
# Validate user username and password
|
||||
#
|
||||
# @param options [Hash] User credentials
|
||||
# @option options [String] :login GitHub login
|
||||
# @option options [String] :password GitHub password
|
||||
# @return [Boolean] True if credentials are valid
|
||||
def validate_credentials(options = {})
|
||||
!self.class.new(options).user.nil?
|
||||
rescue Octokit::Unauthorized
|
||||
false
|
||||
end
|
||||
|
||||
# Update the authenticated user
|
||||
#
|
||||
# @param options [Hash] A customizable set of options.
|
||||
# @option options [String] :name
|
||||
# @option options [String] :email Publically visible email address.
|
||||
# @option options [String] :blog
|
||||
# @option options [String] :company
|
||||
# @option options [String] :location
|
||||
# @option options [Boolean] :hireable
|
||||
# @option options [String] :bio
|
||||
# @return [Sawyer::Resource]
|
||||
# @see https://developer.github.com/v3/users/#update-the-authenticated-user
|
||||
# @example
|
||||
# Octokit.update_user(:name => "Erik Michaels-Ober", :email => "sferik@gmail.com", :company => "Code for America", :location => "San Francisco", :hireable => false)
|
||||
def update_user(options)
|
||||
patch 'user', options
|
||||
end
|
||||
|
||||
# Get a user's followers.
|
||||
#
|
||||
# @param user [Integer, String] GitHub user login or id of the user whose
|
||||
# list of followers you are getting.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing users
|
||||
# followers.
|
||||
# @see https://developer.github.com/v3/users/followers/#list-followers-of-a-user
|
||||
# @example
|
||||
# Octokit.followers('pengwynn')
|
||||
def followers(user = login, options = {})
|
||||
paginate "#{User.path user}/followers", options
|
||||
end
|
||||
|
||||
# Get list of users a user is following.
|
||||
#
|
||||
# @param user [Intger, String] GitHub user login or id of the user who you
|
||||
# are getting the list of the people they follow.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing users a
|
||||
# user is following.
|
||||
# @see https://developer.github.com/v3/users/followers/#list-users-followed-by-another-user
|
||||
# @example
|
||||
# Octokit.following('pengwynn')
|
||||
def following(user = login, options = {})
|
||||
paginate "#{User.path user}/following", options
|
||||
end
|
||||
|
||||
# Check if you are following a user. Alternatively, check if a given user
|
||||
# is following a target user.
|
||||
#
|
||||
# Requries an authenticated client.
|
||||
#
|
||||
# @overload follows?(target)
|
||||
# @param target [String] GitHub login of the user that you want to
|
||||
# check if you are following.
|
||||
# @overload follows?(user, target)
|
||||
# @param user [Integer, String] GitHub user login or id of first user
|
||||
# @param target [String] GitHub login of the target user
|
||||
# @return [Boolean] True following target user, false otherwise.
|
||||
# @see https://developer.github.com/v3/users/followers/#check-if-you-are-following-a-user
|
||||
# @see https://developer.github.com/v3/users/followers/#check-if-one-user-follows-another
|
||||
# @example
|
||||
# @client.follows?('pengwynn')
|
||||
# @example
|
||||
# @client.follows?('catsby', 'pengwynn')
|
||||
def follows?(*args)
|
||||
target = args.pop
|
||||
user = args.first
|
||||
boolean_from_response :get, "#{User.path user}/following/#{target}"
|
||||
end
|
||||
|
||||
# Follow a user.
|
||||
#
|
||||
# Requires authenticatied client.
|
||||
#
|
||||
# @param user [String] Username of the user to follow.
|
||||
# @return [Boolean] True if follow was successful, false otherwise.
|
||||
# @see https://developer.github.com/v3/users/followers/#follow-a-user
|
||||
# @example
|
||||
# @client.follow('holman')
|
||||
def follow(user, options = {})
|
||||
boolean_from_response :put, "user/following/#{user}", options
|
||||
end
|
||||
|
||||
# Unfollow a user.
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param user [String] Username of the user to unfollow.
|
||||
# @return [Boolean] True if unfollow was successful, false otherwise.
|
||||
# @see https://developer.github.com/v3/users/followers/#unfollow-a-user
|
||||
# @example
|
||||
# @client.unfollow('holman')
|
||||
def unfollow(user, options = {})
|
||||
boolean_from_response :delete, "user/following/#{user}", options
|
||||
end
|
||||
|
||||
# Get list of repos starred by a user.
|
||||
#
|
||||
# @param user [Integer, String] GitHub user login of the user to get the
|
||||
# list of their starred repositories.
|
||||
# @param options [Hash] Optional options
|
||||
# @option options [String] :sort (created) Sort: <tt>created</tt> or <tt>updated</tt>.
|
||||
# @option options [String] :direction (desc) Direction: <tt>asc</tt> or <tt>desc</tt>.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing repositories starred by user.
|
||||
# @see https://developer.github.com/v3/activity/starring/#list-repositories-being-starred
|
||||
# @example
|
||||
# Octokit.starred('pengwynn')
|
||||
def starred(user = login, options = {})
|
||||
paginate user_path(user, 'starred'), options
|
||||
end
|
||||
|
||||
# Check if you are starring a repo.
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param repo [String, Hash, Repository] A GitHub repository
|
||||
# @return [Boolean] True if you are following the repo, false otherwise.
|
||||
# @see https://developer.github.com/v3/activity/starring/#check-if-you-are-starring-a-repository
|
||||
# @example
|
||||
# @client.starred?('pengwynn/octokit')
|
||||
def starred?(repo, options = {})
|
||||
boolean_from_response :get, "user/starred/#{Repository.new(repo)}", options
|
||||
end
|
||||
|
||||
# Get a public key.
|
||||
#
|
||||
# Note, when using dot notation to retrieve the values, ruby will return
|
||||
# the hash key for the public keys value instead of the actual value, use
|
||||
# symbol or key string to retrieve the value. See example.
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param key_id [Integer] Key to retreive.
|
||||
# @return [Sawyer::Resource] Hash representing the key.
|
||||
# @see https://developer.github.com/v3/users/keys/#get-a-single-public-key
|
||||
# @example
|
||||
# @client.key(1)
|
||||
# @example Retrieve public key contents
|
||||
# public_key = @client.key(1)
|
||||
# public_key.key
|
||||
# # => Error
|
||||
#
|
||||
# public_key[:key]
|
||||
# # => "ssh-rsa AAA..."
|
||||
#
|
||||
# public_key['key']
|
||||
# # => "ssh-rsa AAA..."
|
||||
def key(key_id, options = {})
|
||||
get "user/keys/#{key_id}", options
|
||||
end
|
||||
|
||||
# Get list of public keys for user.
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing public keys.
|
||||
# @see https://developer.github.com/v3/users/keys/#list-your-public-keys
|
||||
# @example
|
||||
# @client.keys
|
||||
def keys(options = {})
|
||||
paginate 'user/keys', options
|
||||
end
|
||||
|
||||
# Get list of public keys for user.
|
||||
#
|
||||
# @param user [Integer, String] GitHub user login or id.
|
||||
# @return [Array<Sawyer::Resource>] Array of hashes representing public keys.
|
||||
# @see https://developer.github.com/v3/users/keys/#list-public-keys-for-a-user
|
||||
# @example
|
||||
# @client.user_keys('pengwynn')
|
||||
def user_keys(user, options = {})
|
||||
# TODO: Roll this into .keys
|
||||
paginate "#{User.path user}/keys", options
|
||||
end
|
||||
|
||||
# Add public key to user account.
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param title [String] Title to give reference to the public key.
|
||||
# @param key [String] Public key.
|
||||
# @return [Sawyer::Resource] Hash representing the newly added public key.
|
||||
# @see https://developer.github.com/v3/users/keys/#create-a-public-key
|
||||
# @example
|
||||
# @client.add_key('Personal projects key', 'ssh-rsa AAA...')
|
||||
def add_key(title, key, options = {})
|
||||
post 'user/keys', options.merge({ title: title, key: key })
|
||||
end
|
||||
|
||||
# Update a public key
|
||||
#
|
||||
# Requires authenticated client
|
||||
#
|
||||
# @param key_id [Integer] Id of key to update.
|
||||
# @param options [Hash] Hash containing attributes to update.
|
||||
# @option options [String] :title
|
||||
# @option options [String] :key
|
||||
# @return [Sawyer::Resource] Hash representing the updated public key.
|
||||
#
|
||||
# @deprecated This method is no longer supported in the API
|
||||
# @see https://developer.github.com/v3/users/keys/#update-a-public-key
|
||||
# @see https://developer.github.com/changes/2014-02-24-finer-grained-scopes-for-ssh-keys/
|
||||
# @example
|
||||
# @client.update_key(1, :title => 'new title', :key => "ssh-rsa BBB")
|
||||
def update_key(key_id, options = {})
|
||||
patch "user/keys/#{key_id}", options
|
||||
end
|
||||
|
||||
# Remove a public key from user account.
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param id [String] Id of the public key to remove.
|
||||
# @return [Boolean] True if removal was successful, false otherwise.
|
||||
# @see https://developer.github.com/v3/users/keys/#delete-a-public-key
|
||||
# @example
|
||||
# @client.remove_key(1)
|
||||
def remove_key(id, options = {})
|
||||
boolean_from_response :delete, "user/keys/#{id}", options
|
||||
end
|
||||
|
||||
# List email addresses for a user.
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @return [Array<String>] Array of email addresses.
|
||||
# @see https://developer.github.com/v3/users/emails/#list-email-addresses-for-a-user
|
||||
# @example
|
||||
# @client.emails
|
||||
def emails(options = {})
|
||||
paginate 'user/emails', options
|
||||
end
|
||||
|
||||
# Add email address to user.
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param email [String] Email address to add to the user.
|
||||
# @return [Array<String>] Array of all email addresses of the user.
|
||||
# @see https://developer.github.com/v3/users/emails/#add-email-addresses
|
||||
# @example
|
||||
# @client.add_email('new_email@user.com')
|
||||
def add_email(email, _options = {})
|
||||
email = Array(email)
|
||||
post 'user/emails', email
|
||||
end
|
||||
|
||||
# Remove email from user.
|
||||
#
|
||||
# Requires authenticated client.
|
||||
#
|
||||
# @param email [String] Email address to remove.
|
||||
# @return [Array<String>] Array of all email addresses of the user.
|
||||
# @see https://developer.github.com/v3/users/emails/#delete-email-addresses
|
||||
# @example
|
||||
# @client.remove_email('old_email@user.com')
|
||||
def remove_email(email)
|
||||
email = Array(email)
|
||||
boolean_from_response :delete, 'user/emails', email
|
||||
end
|
||||
|
||||
# List repositories being watched by a user.
|
||||
#
|
||||
# @param user [Integer, String] GitHub user login or id.
|
||||
# @return [Array<Sawyer::Resource>] Array of repositories.
|
||||
# @see https://developer.github.com/v3/activity/watching/#list-repositories-being-watched
|
||||
# @example
|
||||
# @client.subscriptions("pengwynn")
|
||||
def subscriptions(user = login, options = {})
|
||||
paginate user_path(user, 'subscriptions'), options
|
||||
end
|
||||
alias watched subscriptions
|
||||
|
||||
# Initiates the generation of a migration archive.
|
||||
#
|
||||
# Requires authenticated user.
|
||||
#
|
||||
# @param repositories [Array<String>] :repositories Repositories for the organization.
|
||||
# @option options [Boolean, optional] :lock_repositories Indicates whether repositories should be locked during migration
|
||||
# @option options [Boolean, optional] :exclude_attachments Exclude attachments fro the migration data
|
||||
# @return [Sawyer::Resource] Hash representing the new migration.
|
||||
# @example
|
||||
# @client.start_migration(['octocat/hello-world'])
|
||||
# @see https://docs.github.com/en/rest/reference/migrations#start-a-user-migration
|
||||
def start_user_migration(repositories, options = {})
|
||||
options[:repositories] = repositories
|
||||
post 'user/migrations', options
|
||||
end
|
||||
|
||||
# Lists the most recent migrations.
|
||||
#
|
||||
# Requires authenticated user.
|
||||
#
|
||||
# @return [Array<Sawyer::Resource>] Array of migration resources.
|
||||
# @see https://docs.github.com/en/rest/reference/migrations#list-user-migrations
|
||||
def user_migrations(options = {})
|
||||
paginate 'user/migrations', options
|
||||
end
|
||||
|
||||
# Fetches the status of a migration.
|
||||
#
|
||||
# Requires authenticated user.
|
||||
#
|
||||
# @param id [Integer] ID number of the migration.
|
||||
# @see https://docs.github.com/en/rest/reference/migrations#get-a-user-migration-status
|
||||
def user_migration_status(id, options = {})
|
||||
get "user/migrations/#{id}", options
|
||||
end
|
||||
|
||||
# Fetches the URL to a migration archive.
|
||||
#
|
||||
# Requires authenticated user.
|
||||
#
|
||||
# @param id [Integer] ID number of the migration.
|
||||
# @see https://docs.github.com/en/rest/reference/migrations#download-a-user-migration-archive
|
||||
def user_migration_archive_url(id, options = {})
|
||||
url = "user/migrations/#{id}/archive"
|
||||
|
||||
response = client_without_redirects(options).get(url)
|
||||
response.headers['location']
|
||||
end
|
||||
|
||||
# Deletes a previous migration archive.
|
||||
#
|
||||
# Requires authenticated user.
|
||||
#
|
||||
# @param id [Integer] ID number of the migration.
|
||||
# @see https://docs.github.com/en/rest/reference/migrations#delete-a-user-migration-archive
|
||||
def delete_user_migration_archive(id, options = {})
|
||||
delete "user/migrations/#{id}/archive", options
|
||||
end
|
||||
|
||||
# List repositories for a user migration.
|
||||
#
|
||||
# Requires authenticated user.
|
||||
#
|
||||
# @param id [Integer] ID number of the migration.
|
||||
# @see https://docs.github.com/en/rest/reference/migrations#list-repositories-for-a-user-migration
|
||||
def user_migration_repositories(id, options = {})
|
||||
get "user/migrations/#{id}/repositories", options
|
||||
end
|
||||
|
||||
# Unlock a user repository which has been locked by a migration.
|
||||
#
|
||||
# Requires authenticated user.
|
||||
#
|
||||
# @param id [Integer] ID number of the migration.
|
||||
# @param repo [String] Name of the repository.
|
||||
# @see https://docs.github.com/en/rest/reference/migrations#unlock-a-user-repository
|
||||
def unlock_user_repository(id, repo, options = {})
|
||||
delete "user/migrations/#{id}/repos/#{repo}/lock", options
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# convenience method for constructing a user specific path, if the user is logged in
|
||||
def user_path(user, path)
|
||||
if user == login && user_authenticated?
|
||||
"user/#{path}"
|
||||
else
|
||||
"#{User.path user}/#{path}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,155 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
# Configuration options for {Client}, defaulting to values
|
||||
# in {Default}
|
||||
module Configurable
|
||||
# @!attribute [w] access_token
|
||||
# @see https://developer.github.com/v3/oauth/
|
||||
# @return [String] OAuth2 access token for authentication
|
||||
# @!attribute api_endpoint
|
||||
# @return [String] Base URL for API requests. default: https://api.github.com/
|
||||
# @!attribute auto_paginate
|
||||
# @return [Boolean] Auto fetch next page of results until rate limit reached
|
||||
# @!attribute [w] bearer_token
|
||||
# @see https://developer.github.com/early-access/integrations/authentication/#as-an-integration
|
||||
# @return [String] JWT bearer token for authentication
|
||||
# @!attribute client_id
|
||||
# @see https://developer.github.com/v3/oauth/
|
||||
# @return [String] Configure OAuth app key
|
||||
# @!attribute [w] client_secret
|
||||
# @see https://developer.github.com/v3/oauth/
|
||||
# @return [String] Configure OAuth app secret
|
||||
# @!attribute default_media_type
|
||||
# @see https://developer.github.com/v3/media/
|
||||
# @return [String] Configure preferred media type (for API versioning, for example)
|
||||
# @!attribute connection_options
|
||||
# @see https://github.com/lostisland/faraday
|
||||
# @return [Hash] Configure connection options for Faraday
|
||||
# @!attribute login
|
||||
# @return [String] GitHub username for Basic Authentication
|
||||
# @!attribute management_console_password
|
||||
# @return [String] An admin password set up for your GitHub Enterprise management console
|
||||
# @!attribute management_console_endpoint
|
||||
# @return [String] Base URL for API requests to the GitHub Enterprise management console
|
||||
# @!attribute middleware
|
||||
# @see https://github.com/lostisland/faraday
|
||||
# @return [Faraday::Builder or Faraday::RackBuilder] Configure middleware for Faraday
|
||||
# @!attribute netrc
|
||||
# @return [Boolean] Instruct Octokit to get credentials from .netrc file
|
||||
# @!attribute netrc_file
|
||||
# @return [String] Path to .netrc file. default: ~/.netrc
|
||||
# @!attribute [w] password
|
||||
# @return [String] GitHub password for Basic Authentication
|
||||
# @!attribute per_page
|
||||
# @return [String] Configure page size for paginated results. API default: 30
|
||||
# @!attribute proxy
|
||||
# @see https://github.com/lostisland/faraday
|
||||
# @return [String] URI for proxy server
|
||||
# @!attribute ssl_verify_mode
|
||||
# @see https://github.com/lostisland/faraday
|
||||
# @return [String] SSL verify mode for ssl connections
|
||||
# @!attribute user_agent
|
||||
# @return [String] Configure User-Agent header for requests.
|
||||
# @!attribute web_endpoint
|
||||
# @return [String] Base URL for web URLs. default: https://github.com/
|
||||
|
||||
attr_accessor :access_token, :auto_paginate, :bearer_token, :client_id,
|
||||
:client_secret, :default_media_type, :connection_options,
|
||||
:middleware, :netrc, :netrc_file,
|
||||
:per_page, :proxy, :ssl_verify_mode, :user_agent
|
||||
attr_writer :password, :web_endpoint, :api_endpoint, :login,
|
||||
:management_console_endpoint, :management_console_password
|
||||
|
||||
class << self
|
||||
# List of configurable keys for {Octokit::Client}
|
||||
# @return [Array] of option keys
|
||||
def keys
|
||||
@keys ||= %i[
|
||||
access_token
|
||||
api_endpoint
|
||||
auto_paginate
|
||||
bearer_token
|
||||
client_id
|
||||
client_secret
|
||||
connection_options
|
||||
default_media_type
|
||||
login
|
||||
management_console_endpoint
|
||||
management_console_password
|
||||
middleware
|
||||
netrc
|
||||
netrc_file
|
||||
per_page
|
||||
password
|
||||
proxy
|
||||
ssl_verify_mode
|
||||
user_agent
|
||||
web_endpoint
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
# Set configuration options using a block
|
||||
def configure
|
||||
yield self
|
||||
end
|
||||
|
||||
# Reset configuration options to default values
|
||||
def reset!
|
||||
# rubocop:disable Style/HashEachMethods
|
||||
#
|
||||
# This may look like a `.keys.each` which should be replaced with `#each_key`, but
|
||||
# this doesn't actually work, since `#keys` is just a method we've defined ourselves.
|
||||
# The class doesn't fulfill the whole `Enumerable` contract.
|
||||
Octokit::Configurable.keys.each do |key|
|
||||
# rubocop:enable Style/HashEachMethods
|
||||
instance_variable_set(:"@#{key}", Octokit::Default.options[key])
|
||||
end
|
||||
self
|
||||
end
|
||||
alias setup reset!
|
||||
|
||||
# Compares client options to a Hash of requested options
|
||||
#
|
||||
# @param opts [Hash] Options to compare with current client options
|
||||
# @return [Boolean]
|
||||
def same_options?(opts)
|
||||
opts.hash == options.hash
|
||||
end
|
||||
|
||||
def api_endpoint
|
||||
File.join(@api_endpoint, '')
|
||||
end
|
||||
|
||||
def management_console_endpoint
|
||||
File.join(@management_console_endpoint, '')
|
||||
end
|
||||
|
||||
# Base URL for generated web URLs
|
||||
#
|
||||
# @return [String] Default: https://github.com/
|
||||
def web_endpoint
|
||||
File.join(@web_endpoint, '')
|
||||
end
|
||||
|
||||
def login
|
||||
@login ||= (user.login if token_authenticated?)
|
||||
end
|
||||
|
||||
def netrc?
|
||||
!!@netrc
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def options
|
||||
Octokit::Configurable.keys.to_h { |key| [key, instance_variable_get(:"@#{key}")] }
|
||||
end
|
||||
|
||||
def fetch_client_id_and_secret(overrides = {})
|
||||
opts = options.merge(overrides)
|
||||
opts.values_at :client_id, :client_secret
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,218 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'sawyer'
|
||||
require 'octokit/authentication'
|
||||
module Octokit
|
||||
# Network layer for API clients.
|
||||
module Connection
|
||||
include Octokit::Authentication
|
||||
|
||||
# Header keys that can be passed in options hash to {#get},{#head}
|
||||
CONVENIENCE_HEADERS = Set.new(%i[accept content_type])
|
||||
|
||||
# Make a HTTP GET request
|
||||
#
|
||||
# @param url [String] The path, relative to {#api_endpoint}
|
||||
# @param options [Hash] Query and header params for request
|
||||
# @return [Sawyer::Resource]
|
||||
def get(url, options = {})
|
||||
request :get, url, parse_query_and_convenience_headers(options)
|
||||
end
|
||||
|
||||
# Make a HTTP POST request
|
||||
#
|
||||
# @param url [String] The path, relative to {#api_endpoint}
|
||||
# @param options [Hash] Body and header params for request
|
||||
# @return [Sawyer::Resource]
|
||||
def post(url, options = {})
|
||||
request :post, url, options
|
||||
end
|
||||
|
||||
# Make a HTTP PUT request
|
||||
#
|
||||
# @param url [String] The path, relative to {#api_endpoint}
|
||||
# @param options [Hash] Body and header params for request
|
||||
# @return [Sawyer::Resource]
|
||||
def put(url, options = {})
|
||||
request :put, url, options
|
||||
end
|
||||
|
||||
# Make a HTTP PATCH request
|
||||
#
|
||||
# @param url [String] The path, relative to {#api_endpoint}
|
||||
# @param options [Hash] Body and header params for request
|
||||
# @return [Sawyer::Resource]
|
||||
def patch(url, options = {})
|
||||
request :patch, url, options
|
||||
end
|
||||
|
||||
# Make a HTTP DELETE request
|
||||
#
|
||||
# @param url [String] The path, relative to {#api_endpoint}
|
||||
# @param options [Hash] Query and header params for request
|
||||
# @return [Sawyer::Resource]
|
||||
def delete(url, options = {})
|
||||
request :delete, url, options
|
||||
end
|
||||
|
||||
# Make a HTTP HEAD request
|
||||
#
|
||||
# @param url [String] The path, relative to {#api_endpoint}
|
||||
# @param options [Hash] Query and header params for request
|
||||
# @return [Sawyer::Resource]
|
||||
def head(url, options = {})
|
||||
request :head, url, parse_query_and_convenience_headers(options)
|
||||
end
|
||||
|
||||
# Make one or more HTTP GET requests, optionally fetching
|
||||
# the next page of results from URL in Link response header based
|
||||
# on value in {#auto_paginate}.
|
||||
#
|
||||
# @param url [String] The path, relative to {#api_endpoint}
|
||||
# @param options [Hash] Query and header params for request
|
||||
# @param block [Block] Block to perform the data concatination of the
|
||||
# multiple requests. The block is called with two parameters, the first
|
||||
# contains the contents of the requests so far and the second parameter
|
||||
# contains the latest response.
|
||||
# @return [Sawyer::Resource]
|
||||
def paginate(url, options = {})
|
||||
opts = parse_query_and_convenience_headers(options)
|
||||
if @auto_paginate || @per_page
|
||||
opts[:query][:per_page] ||= @per_page || (@auto_paginate ? 100 : nil)
|
||||
end
|
||||
|
||||
data = request(:get, url, opts.dup)
|
||||
|
||||
if @auto_paginate
|
||||
while @last_response.rels[:next] && rate_limit.remaining > 0
|
||||
@last_response = @last_response.rels[:next].get(headers: opts[:headers])
|
||||
if block_given?
|
||||
yield(data, @last_response)
|
||||
else
|
||||
data.concat(@last_response.data) if @last_response.data.is_a?(Array)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
data
|
||||
end
|
||||
|
||||
# Hypermedia agent for the GitHub API
|
||||
#
|
||||
# @return [Sawyer::Agent]
|
||||
def agent
|
||||
@agent ||= Sawyer::Agent.new(endpoint, sawyer_options) do |http|
|
||||
http.headers[:accept] = default_media_type
|
||||
http.headers[:content_type] = 'application/json'
|
||||
http.headers[:user_agent] = user_agent
|
||||
if basic_authenticated?
|
||||
http.request(*FARADAY_BASIC_AUTH_KEYS, @login, @password)
|
||||
elsif token_authenticated?
|
||||
http.request :authorization, 'token', @access_token
|
||||
elsif bearer_authenticated?
|
||||
http.request :authorization, 'Bearer', @bearer_token
|
||||
elsif application_authenticated?
|
||||
http.request(*FARADAY_BASIC_AUTH_KEYS, @client_id, @client_secret)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Fetch the root resource for the API
|
||||
#
|
||||
# @return [Sawyer::Resource]
|
||||
def root
|
||||
get '/'
|
||||
end
|
||||
|
||||
# Response for last HTTP request
|
||||
#
|
||||
# @return [Sawyer::Response]
|
||||
def last_response
|
||||
@last_response if defined? @last_response
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def endpoint
|
||||
api_endpoint
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def reset_agent
|
||||
@agent = nil
|
||||
end
|
||||
|
||||
def request(method, path, data, options = {})
|
||||
if data.is_a?(Hash)
|
||||
options[:query] = data.delete(:query) || {}
|
||||
options[:headers] = data.delete(:headers) || {}
|
||||
if accept = data.delete(:accept)
|
||||
options[:headers][:accept] = accept
|
||||
end
|
||||
end
|
||||
|
||||
@last_response = response = agent.call(method, Addressable::URI.parse(path.to_s).normalize.to_s, data, options)
|
||||
response_data_correctly_encoded(response)
|
||||
rescue Octokit::Error => e
|
||||
@last_response = nil
|
||||
raise e
|
||||
end
|
||||
|
||||
# Executes the request, checking if it was successful
|
||||
#
|
||||
# @return [Boolean] True on success, false otherwise
|
||||
def boolean_from_response(method, path, options = {})
|
||||
request(method, path, options)
|
||||
[201, 202, 204].include? @last_response.status
|
||||
rescue Octokit::NotFound
|
||||
false
|
||||
end
|
||||
|
||||
def sawyer_options
|
||||
opts = {
|
||||
links_parser: Sawyer::LinkParsers::Simple.new
|
||||
}
|
||||
conn_opts = @connection_options
|
||||
conn_opts[:builder] = @middleware.dup if @middleware
|
||||
conn_opts[:proxy] = @proxy if @proxy
|
||||
if conn_opts[:ssl].nil?
|
||||
conn_opts[:ssl] = { verify_mode: @ssl_verify_mode } if @ssl_verify_mode
|
||||
else
|
||||
verify = @connection_options[:ssl][:verify]
|
||||
conn_opts[:ssl] = {
|
||||
verify: verify,
|
||||
verify_mode: verify == false ? 0 : @ssl_verify_mode
|
||||
}
|
||||
end
|
||||
opts[:faraday] = Faraday.new(conn_opts)
|
||||
|
||||
opts
|
||||
end
|
||||
|
||||
def parse_query_and_convenience_headers(options)
|
||||
options = options.dup
|
||||
headers = options.delete(:headers) { {} }
|
||||
CONVENIENCE_HEADERS.each do |h|
|
||||
if header = options.delete(h)
|
||||
headers[h] = header
|
||||
end
|
||||
end
|
||||
query = options.delete(:query)
|
||||
opts = { query: options }
|
||||
opts[:query].merge!(query) if query.is_a?(Hash)
|
||||
opts[:headers] = headers unless headers.empty?
|
||||
|
||||
opts
|
||||
end
|
||||
|
||||
def response_data_correctly_encoded(response)
|
||||
content_type = response.headers.fetch('content-type', '')
|
||||
return response.data unless content_type.include?('charset') && response.data.is_a?(String)
|
||||
|
||||
reported_encoding = content_type.match(/charset=([^ ]+)/)[1]
|
||||
response.data.force_encoding(reported_encoding)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,189 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'octokit/middleware/follow_redirects'
|
||||
require 'octokit/response/raise_error'
|
||||
require 'octokit/response/feed_parser'
|
||||
require 'octokit/version'
|
||||
require 'octokit/warnable'
|
||||
|
||||
if Gem::Version.new(Faraday::VERSION) >= Gem::Version.new('2.0')
|
||||
begin
|
||||
require 'faraday/retry'
|
||||
rescue LoadError
|
||||
Octokit::Warnable.octokit_warn 'To use retry middleware with Faraday v2.0+, install `faraday-retry` gem'
|
||||
end
|
||||
end
|
||||
|
||||
module Octokit
|
||||
# Default configuration options for {Client}
|
||||
module Default
|
||||
# Default API endpoint
|
||||
API_ENDPOINT = 'https://api.github.com'
|
||||
|
||||
# Default User Agent header string
|
||||
USER_AGENT = "Octokit Ruby Gem #{Octokit::VERSION}"
|
||||
|
||||
# Default media type
|
||||
MEDIA_TYPE = 'application/vnd.github.v3+json'
|
||||
|
||||
# Default WEB endpoint
|
||||
WEB_ENDPOINT = 'https://github.com'
|
||||
|
||||
# Default Faraday middleware stack
|
||||
MIDDLEWARE = Faraday::RackBuilder.new do |builder|
|
||||
# In Faraday 2.x, Faraday::Request::Retry was moved to a separate gem
|
||||
# so we use it only when it's available.
|
||||
if defined?(Faraday::Request::Retry)
|
||||
retry_exceptions = Faraday::Request::Retry::DEFAULT_EXCEPTIONS + [Octokit::ServerError]
|
||||
builder.use Faraday::Request::Retry, exceptions: retry_exceptions
|
||||
elsif defined?(Faraday::Retry::Middleware)
|
||||
retry_exceptions = Faraday::Retry::Middleware::DEFAULT_EXCEPTIONS + [Octokit::ServerError]
|
||||
builder.use Faraday::Retry::Middleware, exceptions: retry_exceptions
|
||||
end
|
||||
|
||||
builder.use Octokit::Middleware::FollowRedirects
|
||||
builder.use Octokit::Response::RaiseError
|
||||
builder.use Octokit::Response::FeedParser
|
||||
builder.adapter Faraday.default_adapter
|
||||
end
|
||||
|
||||
class << self
|
||||
# Configuration options
|
||||
# @return [Hash]
|
||||
def options
|
||||
Octokit::Configurable.keys.to_h { |key| [key, send(key)] }
|
||||
end
|
||||
|
||||
# Default access token from ENV
|
||||
# @return [String]
|
||||
def access_token
|
||||
ENV.fetch('OCTOKIT_ACCESS_TOKEN', nil)
|
||||
end
|
||||
|
||||
# Default API endpoint from ENV or {API_ENDPOINT}
|
||||
# @return [String]
|
||||
def api_endpoint
|
||||
ENV.fetch('OCTOKIT_API_ENDPOINT') { API_ENDPOINT }
|
||||
end
|
||||
|
||||
# Default pagination preference from ENV
|
||||
# @return [String]
|
||||
def auto_paginate
|
||||
ENV.fetch('OCTOKIT_AUTO_PAGINATE', nil)
|
||||
end
|
||||
|
||||
# Default bearer token from ENV
|
||||
# @return [String]
|
||||
def bearer_token
|
||||
ENV.fetch('OCTOKIT_BEARER_TOKEN', nil)
|
||||
end
|
||||
|
||||
# Default OAuth app key from ENV
|
||||
# @return [String]
|
||||
def client_id
|
||||
ENV.fetch('OCTOKIT_CLIENT_ID', nil)
|
||||
end
|
||||
|
||||
# Default OAuth app secret from ENV
|
||||
# @return [String]
|
||||
def client_secret
|
||||
ENV.fetch('OCTOKIT_SECRET', nil)
|
||||
end
|
||||
|
||||
# Default management console password from ENV
|
||||
# @return [String]
|
||||
def management_console_password
|
||||
ENV.fetch('OCTOKIT_ENTERPRISE_MANAGEMENT_CONSOLE_PASSWORD', nil)
|
||||
end
|
||||
|
||||
# Default management console endpoint from ENV
|
||||
# @return [String]
|
||||
def management_console_endpoint
|
||||
ENV.fetch('OCTOKIT_ENTERPRISE_MANAGEMENT_CONSOLE_ENDPOINT', nil)
|
||||
end
|
||||
|
||||
# Default options for Faraday::Connection
|
||||
# @return [Hash]
|
||||
def connection_options
|
||||
{
|
||||
headers: {
|
||||
accept: default_media_type,
|
||||
user_agent: user_agent
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
# Default media type from ENV or {MEDIA_TYPE}
|
||||
# @return [String]
|
||||
def default_media_type
|
||||
ENV.fetch('OCTOKIT_DEFAULT_MEDIA_TYPE') { MEDIA_TYPE }
|
||||
end
|
||||
|
||||
# Default GitHub username for Basic Auth from ENV
|
||||
# @return [String]
|
||||
def login
|
||||
ENV.fetch('OCTOKIT_LOGIN', nil)
|
||||
end
|
||||
|
||||
# Default middleware stack for Faraday::Connection
|
||||
# from {MIDDLEWARE}
|
||||
# @return [Faraday::RackBuilder or Faraday::Builder]
|
||||
def middleware
|
||||
MIDDLEWARE
|
||||
end
|
||||
|
||||
# Default GitHub password for Basic Auth from ENV
|
||||
# @return [String]
|
||||
def password
|
||||
ENV.fetch('OCTOKIT_PASSWORD', nil)
|
||||
end
|
||||
|
||||
# Default pagination page size from ENV
|
||||
# @return [Integer] Page size
|
||||
def per_page
|
||||
page_size = ENV.fetch('OCTOKIT_PER_PAGE', nil)
|
||||
|
||||
page_size&.to_i
|
||||
end
|
||||
|
||||
# Default proxy server URI for Faraday connection from ENV
|
||||
# @return [String]
|
||||
def proxy
|
||||
ENV.fetch('OCTOKIT_PROXY', nil)
|
||||
end
|
||||
|
||||
# Default SSL verify mode from ENV
|
||||
# @return [Integer]
|
||||
def ssl_verify_mode
|
||||
# 0 is OpenSSL::SSL::VERIFY_NONE
|
||||
# 1 is OpenSSL::SSL::SSL_VERIFY_PEER
|
||||
# the standard default for SSL is SSL_VERIFY_PEER which requires a server certificate check on the client
|
||||
ENV.fetch('OCTOKIT_SSL_VERIFY_MODE', 1).to_i
|
||||
end
|
||||
|
||||
# Default User-Agent header string from ENV or {USER_AGENT}
|
||||
# @return [String]
|
||||
def user_agent
|
||||
ENV.fetch('OCTOKIT_USER_AGENT') { USER_AGENT }
|
||||
end
|
||||
|
||||
# Default web endpoint from ENV or {WEB_ENDPOINT}
|
||||
# @return [String]
|
||||
def web_endpoint
|
||||
ENV.fetch('OCTOKIT_WEB_ENDPOINT') { WEB_ENDPOINT }
|
||||
end
|
||||
|
||||
# Default behavior for reading .netrc file
|
||||
# @return [Boolean]
|
||||
def netrc
|
||||
ENV.fetch('OCTOKIT_NETRC', false)
|
||||
end
|
||||
|
||||
# Default path for .netrc file
|
||||
# @return [String]
|
||||
def netrc_file
|
||||
ENV.fetch('OCTOKIT_NETRC_FILE') { File.join(Dir.home.to_s, '.netrc') }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,46 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'octokit/connection'
|
||||
require 'octokit/configurable'
|
||||
require 'octokit/warnable'
|
||||
require 'octokit/enterprise_admin_client/admin_stats'
|
||||
require 'octokit/enterprise_admin_client/license'
|
||||
require 'octokit/enterprise_admin_client/orgs'
|
||||
require 'octokit/enterprise_admin_client/search_indexing'
|
||||
require 'octokit/enterprise_admin_client/users'
|
||||
|
||||
module Octokit
|
||||
# EnterpriseAdminClient is only meant to be used by GitHub Enterprise Admins
|
||||
# and provides access the Admin only API endpoints including Admin Stats,
|
||||
# Management Console, and the Search Indexing API.
|
||||
#
|
||||
# @see Octokit::Client Use Octokit::Client for regular API use for GitHub
|
||||
# and GitHub Enterprise.
|
||||
# @see https://developer.github.com/v3/enterprise/
|
||||
class EnterpriseAdminClient
|
||||
include Octokit::Configurable
|
||||
include Octokit::Connection
|
||||
include Octokit::Warnable
|
||||
include Octokit::EnterpriseAdminClient::AdminStats
|
||||
include Octokit::EnterpriseAdminClient::License
|
||||
include Octokit::EnterpriseAdminClient::Orgs
|
||||
include Octokit::EnterpriseAdminClient::SearchIndexing
|
||||
include Octokit::EnterpriseAdminClient::Users
|
||||
|
||||
def initialize(options = {})
|
||||
# Use options passed in, but fall back to module defaults
|
||||
#
|
||||
# rubocop:disable Style/HashEachMethods
|
||||
#
|
||||
# This may look like a `.keys.each` which should be replaced with `#each_key`, but
|
||||
# this doesn't actually work, since `#keys` is just a method we've defined ourselves.
|
||||
# The class doesn't fulfill the whole `Enumerable` contract.
|
||||
Octokit::Configurable.keys.each do |key|
|
||||
# rubocop:enable Style/HashEachMethods
|
||||
instance_variable_set(:"@#{key}", options[key] || Octokit.instance_variable_get(:"@#{key}"))
|
||||
end
|
||||
|
||||
login_from_netrc unless user_authenticated? || application_authenticated?
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,119 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class EnterpriseAdminClient
|
||||
# Methods for the Enterprise Admin Stats API
|
||||
#
|
||||
# @see https://developer.github.com/v3/enterprise-admin/admin_stats/
|
||||
module AdminStats
|
||||
# Get all available stats
|
||||
#
|
||||
# @return [Sawyer::Resource] All available stats
|
||||
# @example Get all available stats
|
||||
# @client.admin_stats
|
||||
def admin_stats
|
||||
get_admin_stats 'all'
|
||||
end
|
||||
|
||||
# Get only repository-related stats
|
||||
#
|
||||
# @return [Sawyer::Resource] Only repository-related stats
|
||||
# @example Get only repository-related stats
|
||||
# @client.admin_repository_stats
|
||||
def admin_repository_stats
|
||||
get_admin_stats 'repos'
|
||||
end
|
||||
|
||||
# Get only hooks-related stats
|
||||
#
|
||||
# @return [Sawyer::Resource] Only hooks-related stats
|
||||
# @example Get only hooks-related stats
|
||||
# @client.admin_hooks_stats
|
||||
def admin_hooks_stats
|
||||
get_admin_stats 'hooks'
|
||||
end
|
||||
|
||||
# Get only pages-related stats
|
||||
#
|
||||
# @return [Sawyer::Resource] Only pages-related stats
|
||||
# @example Get only pages-related stats
|
||||
# @client.admin_pages_stats
|
||||
def admin_pages_stats
|
||||
get_admin_stats 'pages'
|
||||
end
|
||||
|
||||
# Get only organization-related stats
|
||||
#
|
||||
# @return [Sawyer::Resource] Only organization-related stats
|
||||
# @example Get only organization-related stats
|
||||
# @client.admin_organization_stats
|
||||
def admin_organization_stats
|
||||
get_admin_stats 'orgs'
|
||||
end
|
||||
|
||||
# Get only user-related stats
|
||||
#
|
||||
# @return [Sawyer::Resource] Only user-related stats
|
||||
# @example Get only user-related stats
|
||||
# @client.admin_users_stats
|
||||
def admin_users_stats
|
||||
get_admin_stats 'users'
|
||||
end
|
||||
|
||||
# Get only pull request-related stats
|
||||
#
|
||||
# @return [Sawyer::Resource] Only pull request-related stats
|
||||
# @example Get only pull request-related stats
|
||||
# @client.admin_pull_requests_stats
|
||||
def admin_pull_requests_stats
|
||||
get_admin_stats 'pulls'
|
||||
end
|
||||
|
||||
# Get only issue-related stats
|
||||
#
|
||||
# @return [Sawyer::Resource] Only issue-related stats
|
||||
# @example Get only issue-related stats
|
||||
# @client.admin_issues_stats
|
||||
def admin_issues_stats
|
||||
get_admin_stats 'issues'
|
||||
end
|
||||
|
||||
# Get only milestone-related stats
|
||||
#
|
||||
# @return [Sawyer::Resource] Only milestone-related stats
|
||||
# @example Get only milestone-related stats
|
||||
# @client.admin_milestones_stats
|
||||
def admin_milestones_stats
|
||||
get_admin_stats 'milestones'
|
||||
end
|
||||
|
||||
# Get only gist-related stats
|
||||
#
|
||||
# @return [Sawyer::Resource] Only only gist-related stats
|
||||
# @example Get only gist-related stats
|
||||
# @client.admin_gits_stats
|
||||
def admin_gists_stats
|
||||
get_admin_stats 'gists'
|
||||
end
|
||||
|
||||
# Get only comment-related stats
|
||||
#
|
||||
# @return [Sawyer::Resource] Only comment-related stats
|
||||
# @example Get only comment-related stats
|
||||
# @client.admin_comments_stats
|
||||
def admin_comments_stats
|
||||
get_admin_stats 'comments'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# @private Get enterprise stats
|
||||
#
|
||||
# @param metric [String] The metrics you are looking for
|
||||
# @return [Sawyer::Resource] Magical unicorn stats
|
||||
def get_admin_stats(metric)
|
||||
get "enterprise/stats/#{metric}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,17 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class EnterpriseAdminClient
|
||||
# Methods for the Enterprise License API
|
||||
#
|
||||
# @see https://developer.github.com/v3/enterprise-admin/license/
|
||||
module License
|
||||
# Get information about the Enterprise license
|
||||
#
|
||||
# @return [Sawyer::Resource] The license information
|
||||
def license_info
|
||||
get 'enterprise/settings/license'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,26 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class EnterpriseAdminClient
|
||||
# Methods for the Enterprise Orgs API
|
||||
#
|
||||
# @see https://developer.github.com/v3/enterprise-admin/orgs/
|
||||
module Orgs
|
||||
# Create a new organization on the instance.
|
||||
#
|
||||
# @param login [String] The organization's username.
|
||||
# @param admin [String] The login of the user who will manage this organization.
|
||||
# @param options [Hash] A set of options.
|
||||
# @option options [String] :profile_name The organization's display name.
|
||||
# @return [nil]
|
||||
# @see https://developer.github.com/v3/enterprise-admin/orgs/#create-an-organization
|
||||
# @example
|
||||
# @admin_client.create_organization('SuchAGreatOrg', 'gjtorikian')
|
||||
def create_organization(login, admin, options = {})
|
||||
options[:login] = login
|
||||
options[:admin] = admin
|
||||
post 'admin/organizations', options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,82 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class EnterpriseAdminClient
|
||||
# Methods for the Enterprise Search Indexing API
|
||||
#
|
||||
# @see https://developer.github.com/v3/enterprise-admin/search_indexing/
|
||||
module SearchIndexing
|
||||
# Queue a User or Organization to be indexed
|
||||
#
|
||||
# @param user [String] A GitHub Enterprise user or organization
|
||||
# @return [Sawyer:Resource] Result of the queuing containing `:message`
|
||||
def index_user(user)
|
||||
queue_index user
|
||||
end
|
||||
alias index_organization index_user
|
||||
|
||||
# Queue a Repository to be indexed
|
||||
#
|
||||
# @param repo [String, Hash, Repository] A GitHub repository
|
||||
# @return [Sawyer:Resource] Result of the queuing containing `:message`
|
||||
def index_repository(repo)
|
||||
queue_index Repository.new repo
|
||||
end
|
||||
|
||||
# Queue a repository's Issues to be indexed
|
||||
#
|
||||
# @param repo [String, Hash, Repository] A GitHub repository
|
||||
# @return [Sawyer:Resource] Result of the queuing containing `:message`
|
||||
def index_repository_issues(repo)
|
||||
queue_index "#{Repository.new repo}/issues"
|
||||
end
|
||||
|
||||
# Queue a repository's code to be indexed
|
||||
#
|
||||
# @param repo [String, Hash, Repository] A GitHub repository
|
||||
# @return [Sawyer:Resource] Result of the queuing containing `:message`
|
||||
def index_repository_code(repo)
|
||||
queue_index "#{Repository.new repo}/code"
|
||||
end
|
||||
|
||||
# Queue a user's or organization's repositories to be indexed
|
||||
#
|
||||
# @param user [String] A GitHub Enterprise user or organization
|
||||
# @return [Sawyer:Resource] Result of the queuing containing `:message`
|
||||
def index_users_repositories(user)
|
||||
queue_index "#{user}/*"
|
||||
end
|
||||
alias index_organizations_repositories index_users_repositories
|
||||
|
||||
# Queue an index of all the issues across all of a user's or
|
||||
# organization's repositories
|
||||
#
|
||||
# @param user [String] A GitHub Enterprise user or organization
|
||||
# @return [Sawyer:Resource] Result of the queuing containing `:message`
|
||||
def index_users_repositories_issues(user)
|
||||
queue_index "#{user}/*/issues"
|
||||
end
|
||||
alias index_organizations_repositories_issues index_users_repositories_issues
|
||||
|
||||
# Queue an index of all the code contained in all of a user's or
|
||||
# organization's repositories
|
||||
#
|
||||
# @param user [String] A GitHub Enterprise user or organization
|
||||
# @return [Sawyer:Resource] Result of the queuing containing `:message`
|
||||
def index_users_repositories_code(user)
|
||||
queue_index "#{user}/*/code"
|
||||
end
|
||||
alias index_organizations_repositories_code index_users_repositories_code
|
||||
|
||||
private
|
||||
|
||||
# @private Queue a target for indexing
|
||||
#
|
||||
# @param target [String] Target to index
|
||||
# @return [Sawyer:Resource] Result of the queuing containing `:message`
|
||||
def queue_index(target)
|
||||
post 'staff/indexing_jobs', target: target
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,129 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class EnterpriseAdminClient
|
||||
# Methods for the Enterprise User Administration API
|
||||
#
|
||||
# @see https://developer.github.com/enterprise/v3/enterprise-admin/users/
|
||||
module Users
|
||||
# Create a new user.
|
||||
#
|
||||
# @param login [String] The user's username.
|
||||
# @param email [String] The user's email address.
|
||||
# @see https://developer.github.com/enterprise/v3/enterprise-admin/users#create-a-new-user
|
||||
# @example
|
||||
# @admin_client.create_user('foobar', 'notreal@foo.bar')
|
||||
def create_user(login, email, options = {})
|
||||
options[:login] = login
|
||||
options[:email] = email
|
||||
post 'admin/users', options
|
||||
end
|
||||
|
||||
# Promote an ordinary user to a site administrator
|
||||
#
|
||||
# @param user [String] Username of the user to promote.
|
||||
# @return [Boolean] True if promote was successful, false otherwise.
|
||||
# @see https://developer.github.com/enterprise/v3/enterprise-admin/users/#promote-an-ordinary-user-to-a-site-administrator
|
||||
# @example
|
||||
# @admin_client.promote('holman')
|
||||
def promote(user, options = {})
|
||||
boolean_from_response :put, "users/#{user}/site_admin", options
|
||||
end
|
||||
|
||||
# Demote a site administrator to an ordinary user
|
||||
#
|
||||
# @param user [String] Username of the user to demote.
|
||||
# @return [Boolean] True if demote was successful, false otherwise.
|
||||
# @see https://developer.github.com/enterprise/v3/enterprise-admin/users/#demote-a-site-administrator-to-an-ordinary-user
|
||||
# @example
|
||||
# @admin_client.demote('holman')
|
||||
def demote(user, options = {})
|
||||
boolean_from_response :delete, "users/#{user}/site_admin", options
|
||||
end
|
||||
|
||||
# Rename a user.
|
||||
#
|
||||
# @param old_login [String] The user's old username.
|
||||
# @param new_login [String] The user's new username.
|
||||
# @see https://developer.github.com/enterprise/v3/enterprise-admin/users/#rename-an-existing-user
|
||||
# @example
|
||||
# @admin_client.rename_user('foobar', 'foofoobar')
|
||||
def rename_user(old_login, new_login, options = {})
|
||||
options[:login] = new_login
|
||||
patch "admin/users/#{old_login}", options
|
||||
end
|
||||
|
||||
# Deletes a user.
|
||||
#
|
||||
# @param username [String] The username to delete.
|
||||
# @see https://developer.github.com/enterprise/v3/enterprise-admin/users/#delete-a-user
|
||||
# @example
|
||||
# @admin_client.delete_key(1)
|
||||
def delete_user(username, options = {})
|
||||
boolean_from_response :delete, "admin/users/#{username}", options
|
||||
end
|
||||
|
||||
# Suspend a user.
|
||||
#
|
||||
# @param user [String] Username of the user to suspend.
|
||||
# @return [Boolean] True if suspend was successful, false otherwise.
|
||||
# @see https://developer.github.com/enterprise/v3/enterprise-admin/users/#suspend-a-user
|
||||
# @example
|
||||
# @admin_client.suspend('holman')
|
||||
def suspend(user, options = {})
|
||||
boolean_from_response :put, "users/#{user}/suspended", options
|
||||
end
|
||||
|
||||
# Unsuspend a user.
|
||||
#
|
||||
# @param user [String] Username of the user to unsuspend.
|
||||
# @return [Boolean] True if unsuspend was successful, false otherwise.
|
||||
# @see https://developer.github.com/enterprise/v3/enterprise-admin/users/#unsuspend-a-user
|
||||
# @example
|
||||
# @admin_client.unsuspend('holman')
|
||||
def unsuspend(user, options = {})
|
||||
boolean_from_response :delete, "users/#{user}/suspended", options
|
||||
end
|
||||
|
||||
# Creates an impersonation OAuth token.
|
||||
#
|
||||
# @param login [String] The user to create a token for.
|
||||
# @param options [Array<String>] :scopes The scopes to apply.
|
||||
# @see https://developer.github.com/enterprise/v3/enterprise-admin/users/#create-an-impersonation-oauth-token
|
||||
# @example
|
||||
# @admin_client.create_impersonation_token('foobar', {:scopes => ['repo:write']})
|
||||
def create_impersonation_token(login, options = {})
|
||||
post "admin/users/#{login}/authorizations", options
|
||||
end
|
||||
|
||||
# Deletes an impersonation OAuth token.
|
||||
#
|
||||
# @param login [String] The user whose token should be deleted.
|
||||
# @see https://developer.github.com/enterprise/v3/enterprise-admin/users/#delete-an-impersonation-oauth-token
|
||||
# @example
|
||||
# @admin_client.delete_impersonation_token('foobar')
|
||||
def delete_impersonation_token(login, options = {})
|
||||
boolean_from_response :delete, "admin/users/#{login}/authorizations", options
|
||||
end
|
||||
|
||||
# Lists all the public SSH keys.
|
||||
#
|
||||
# @see https://developer.github.com/enterprise/v3/enterprise-admin/users/#list-all-public-keys
|
||||
# @example
|
||||
# @admin_client.list_all_keys
|
||||
def list_all_keys(options = {})
|
||||
get 'admin/keys', options
|
||||
end
|
||||
|
||||
# Deletes a public SSH keys.
|
||||
#
|
||||
# @param id [Number] The ID of the key to delete.
|
||||
# @see https://developer.github.com/enterprise/v3/enterprise-admin/users/#delete-a-public-key
|
||||
# @example
|
||||
# @admin_client.delete_key(1)
|
||||
def delete_key(id, options = {})
|
||||
boolean_from_response :delete, "admin/keys/#{id}", options
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,56 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'octokit/configurable'
|
||||
require 'octokit/connection'
|
||||
require 'octokit/warnable'
|
||||
require 'octokit/enterprise_management_console_client/management_console'
|
||||
|
||||
module Octokit
|
||||
# EnterpriseManagementConsoleClient is only meant to be used by GitHub Enterprise Admins
|
||||
# and provides access to the management console API endpoints.
|
||||
#
|
||||
# @see Octokit::Client Use Octokit::Client for regular API use for GitHub
|
||||
# and GitHub Enterprise.
|
||||
# @see https://developer.github.com/v3/enterprise-admin/management_console/
|
||||
class EnterpriseManagementConsoleClient
|
||||
include Octokit::Configurable
|
||||
include Octokit::Connection
|
||||
include Octokit::Warnable
|
||||
include Octokit::EnterpriseManagementConsoleClient::ManagementConsole
|
||||
|
||||
def initialize(options = {})
|
||||
# Use options passed in, but fall back to module defaults
|
||||
# rubocop:disable Style/HashEachMethods
|
||||
#
|
||||
# This may look like a `.keys.each` which should be replaced with `#each_key`, but
|
||||
# this doesn't actually work, since `#keys` is just a method we've defined ourselves.
|
||||
# The class doesn't fulfill the whole `Enumerable` contract.
|
||||
Octokit::Configurable.keys.each do |key|
|
||||
# rubocop:enable Style/HashEachMethods
|
||||
instance_variable_set(:"@#{key}", options[key] || Octokit.instance_variable_get(:"@#{key}"))
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def endpoint
|
||||
management_console_endpoint
|
||||
end
|
||||
|
||||
# Set Enterprise Management Console password
|
||||
#
|
||||
# @param value [String] Management console admin password
|
||||
def management_console_password=(value)
|
||||
reset_agent
|
||||
@management_console_password = value
|
||||
end
|
||||
|
||||
# Set Enterprise Management Console endpoint
|
||||
#
|
||||
# @param value [String] Management console endpoint
|
||||
def management_console_endpoint=(value)
|
||||
reset_agent
|
||||
@management_console_endpoint = value
|
||||
end
|
||||
end
|
||||
end
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
class EnterpriseManagementConsoleClient
|
||||
# Methods for the Enterprise Management Console API
|
||||
#
|
||||
# @see https://developer.github.com/v3/enterprise-admin/management_console/
|
||||
module ManagementConsole
|
||||
# Uploads a license for the first time
|
||||
#
|
||||
# @param license [String] The path to your .ghl license file.
|
||||
# @param settings [Hash] A hash configuration of the initial settings.
|
||||
#
|
||||
# @see https://docs.github.com/en/enterprise-server@3.4/rest/enterprise-admin/management-console#create-a-github-license
|
||||
# @return nil
|
||||
def upload_license(license, settings = nil)
|
||||
conn = faraday_configuration
|
||||
|
||||
params = {}
|
||||
params[:license] = Faraday::UploadIO.new(license, 'binary')
|
||||
params[:password] = @management_console_password
|
||||
params[:settings] = settings.to_json.to_s unless settings.nil?
|
||||
|
||||
@last_response = conn.post('/setup/api/start', params)
|
||||
end
|
||||
|
||||
# Start a configuration process.
|
||||
#
|
||||
# @return nil
|
||||
def start_configuration
|
||||
post '/setup/api/configure', password_hash
|
||||
end
|
||||
|
||||
# Upgrade an Enterprise installation
|
||||
#
|
||||
# @param license [String] The path to your .ghl license file.
|
||||
#
|
||||
# @return nil
|
||||
def upgrade(license)
|
||||
conn = faraday_configuration
|
||||
|
||||
params = {}
|
||||
params[:license] = Faraday::UploadIO.new(license, 'binary')
|
||||
params[:api_key] = @management_console_password
|
||||
@last_response = conn.post('/setup/api/upgrade', params)
|
||||
end
|
||||
|
||||
# Get information about the Enterprise installation
|
||||
#
|
||||
# @return [Sawyer::Resource] The installation information
|
||||
def config_status
|
||||
get '/setup/api/configcheck', password_hash
|
||||
end
|
||||
alias config_check config_status
|
||||
|
||||
# Get information about the Enterprise installation
|
||||
#
|
||||
# @return [Sawyer::Resource] The settings
|
||||
def settings
|
||||
get '/setup/api/settings', password_hash
|
||||
end
|
||||
alias get_settings settings
|
||||
|
||||
# Modify the Enterprise settings
|
||||
#
|
||||
# @param settings [Hash] A hash configuration of the new settings
|
||||
#
|
||||
# @return [nil]
|
||||
def edit_settings(settings)
|
||||
queries = password_hash
|
||||
queries[:query][:settings] = settings.to_json.to_s
|
||||
put '/setup/api/settings', queries
|
||||
end
|
||||
|
||||
# Get information about the Enterprise maintenance status
|
||||
#
|
||||
# @return [Sawyer::Resource] The maintenance status
|
||||
def maintenance_status
|
||||
get '/setup/api/maintenance', password_hash
|
||||
end
|
||||
alias get_maintenance_status maintenance_status
|
||||
|
||||
# Start (or turn off) the Enterprise maintenance mode
|
||||
#
|
||||
# @param maintenance [Hash] A hash configuration of the maintenance settings
|
||||
# @return [nil]
|
||||
def set_maintenance_status(maintenance)
|
||||
queries = password_hash
|
||||
queries[:query][:maintenance] = maintenance.to_json.to_s
|
||||
post '/setup/api/maintenance', queries
|
||||
end
|
||||
alias edit_maintenance_status set_maintenance_status
|
||||
|
||||
# Fetch the authorized SSH keys on the Enterprise install
|
||||
#
|
||||
# @return [Sawyer::Resource] An array of authorized SSH keys
|
||||
def authorized_keys
|
||||
get '/setup/api/settings/authorized-keys', password_hash
|
||||
end
|
||||
alias get_authorized_keys authorized_keys
|
||||
|
||||
# Add an authorized SSH keys on the Enterprise install
|
||||
#
|
||||
# @param key Either the file path to a key, a File handler to the key, or the contents of the key itself
|
||||
# @return [Sawyer::Resource] An array of authorized SSH keys
|
||||
def add_authorized_key(key)
|
||||
queries = password_hash
|
||||
case key
|
||||
when String
|
||||
if File.exist?(key)
|
||||
key = File.open(key, 'r')
|
||||
content = key.read.strip
|
||||
key.close
|
||||
else
|
||||
content = key
|
||||
end
|
||||
when File
|
||||
content = key.read.strip
|
||||
key.close
|
||||
end
|
||||
|
||||
queries[:query][:authorized_key] = content
|
||||
post '/setup/api/settings/authorized-keys', queries
|
||||
end
|
||||
|
||||
# Removes an authorized SSH keys from the Enterprise install
|
||||
#
|
||||
# @param key Either the file path to a key, a File handler to the key, or the contents of the key itself
|
||||
# @return [Sawyer::Resource] An array of authorized SSH keys
|
||||
def remove_authorized_key(key)
|
||||
queries = password_hash
|
||||
case key
|
||||
when String
|
||||
if File.exist?(key)
|
||||
key = File.open(key, 'r')
|
||||
content = key.read.strip
|
||||
key.close
|
||||
else
|
||||
content = key
|
||||
end
|
||||
when File
|
||||
content = key.read.strip
|
||||
key.close
|
||||
end
|
||||
|
||||
queries[:query][:authorized_key] = content
|
||||
delete '/setup/api/settings/authorized-keys', queries
|
||||
end
|
||||
alias delete_authorized_key remove_authorized_key
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def password_hash
|
||||
{ query: { api_key: @management_console_password } }
|
||||
end
|
||||
|
||||
# We fall back to raw Faraday for handling the licenses because I'm suspicious
|
||||
# that Sawyer isn't handling binary POSTs correctly: https://github.com/lostisland/sawyer/blob/03fca4c020f465ec42856d0486ec3991859b0aed/lib/sawyer/agent.rb#L85
|
||||
def faraday_configuration
|
||||
@faraday_configuration ||= Faraday.new(url: @management_console_endpoint) do |http|
|
||||
http.headers[:user_agent] = user_agent
|
||||
http.request :multipart
|
||||
http.request :url_encoded
|
||||
|
||||
# Disabling SSL is essential for certain self-hosted Enterprise instances
|
||||
if connection_options[:ssl] && !connection_options[:ssl][:verify]
|
||||
http.ssl[:verify] = false
|
||||
end
|
||||
|
||||
http.use Octokit::Response::RaiseError
|
||||
http.adapter Faraday.default_adapter
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,363 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
# Custom error class for rescuing from all GitHub errors
|
||||
class Error < StandardError
|
||||
attr_reader :context
|
||||
|
||||
# Returns the appropriate Octokit::Error subclass based
|
||||
# on status and response message
|
||||
#
|
||||
# @param [Hash] response HTTP response
|
||||
# @return [Octokit::Error]
|
||||
def self.from_response(response)
|
||||
status = response[:status].to_i
|
||||
body = response[:body].to_s
|
||||
headers = response[:response_headers]
|
||||
|
||||
if klass = case status
|
||||
when 400 then Octokit::BadRequest
|
||||
when 401 then error_for_401(headers)
|
||||
when 403 then error_for_403(body)
|
||||
when 404 then error_for_404(body)
|
||||
when 405 then Octokit::MethodNotAllowed
|
||||
when 406 then Octokit::NotAcceptable
|
||||
when 409 then Octokit::Conflict
|
||||
when 415 then Octokit::UnsupportedMediaType
|
||||
when 422 then error_for_422(body)
|
||||
when 451 then Octokit::UnavailableForLegalReasons
|
||||
when 400..499 then Octokit::ClientError
|
||||
when 500 then Octokit::InternalServerError
|
||||
when 501 then Octokit::NotImplemented
|
||||
when 502 then Octokit::BadGateway
|
||||
when 503 then Octokit::ServiceUnavailable
|
||||
when 500..599 then Octokit::ServerError
|
||||
end
|
||||
klass.new(response)
|
||||
end
|
||||
end
|
||||
|
||||
def build_error_context
|
||||
if RATE_LIMITED_ERRORS.include?(self.class)
|
||||
@context = Octokit::RateLimit.from_response(@response)
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(response = nil)
|
||||
@response = response
|
||||
super(build_error_message)
|
||||
build_error_context
|
||||
end
|
||||
|
||||
# Documentation URL returned by the API for some errors
|
||||
#
|
||||
# @return [String]
|
||||
def documentation_url
|
||||
data[:documentation_url] if data.is_a? Hash
|
||||
end
|
||||
|
||||
# Returns most appropriate error for 401 HTTP status code
|
||||
# @private
|
||||
# rubocop:disable Naming/VariableNumber
|
||||
def self.error_for_401(headers)
|
||||
# rubocop:enbale Naming/VariableNumber
|
||||
if Octokit::OneTimePasswordRequired.required_header(headers)
|
||||
Octokit::OneTimePasswordRequired
|
||||
else
|
||||
Octokit::Unauthorized
|
||||
end
|
||||
end
|
||||
|
||||
# Returns most appropriate error for 403 HTTP status code
|
||||
# @private
|
||||
def self.error_for_403(body)
|
||||
# rubocop:enable Naming/VariableNumber
|
||||
case body
|
||||
when /rate limit exceeded/i, /exceeded a secondary rate limit/i
|
||||
Octokit::TooManyRequests
|
||||
when /login attempts exceeded/i
|
||||
Octokit::TooManyLoginAttempts
|
||||
when /(returns|for) blobs (up to|between) [0-9-]+ MB/i
|
||||
Octokit::TooLargeContent
|
||||
when /abuse/i
|
||||
Octokit::AbuseDetected
|
||||
when /repository access blocked/i
|
||||
Octokit::RepositoryUnavailable
|
||||
when /email address must be verified/i
|
||||
Octokit::UnverifiedEmail
|
||||
when /account was suspended/i
|
||||
Octokit::AccountSuspended
|
||||
when /billing issue/i
|
||||
Octokit::BillingIssue
|
||||
when /Resource protected by organization SAML enforcement/i
|
||||
Octokit::SAMLProtected
|
||||
when /suspended your access|This installation has been suspended/i
|
||||
Octokit::InstallationSuspended
|
||||
else
|
||||
Octokit::Forbidden
|
||||
end
|
||||
end
|
||||
|
||||
# Return most appropriate error for 404 HTTP status code
|
||||
# @private
|
||||
# rubocop:disable Naming/VariableNumber
|
||||
def self.error_for_404(body)
|
||||
# rubocop:enable Naming/VariableNumber
|
||||
if body =~ /Branch not protected/i
|
||||
Octokit::BranchNotProtected
|
||||
else
|
||||
Octokit::NotFound
|
||||
end
|
||||
end
|
||||
|
||||
# Return most appropriate error for 422 HTTP status code
|
||||
# @private
|
||||
# rubocop:disable Naming/VariableNumber
|
||||
def self.error_for_422(body)
|
||||
# rubocop:enable Naming/VariableNumber
|
||||
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
|
||||
if data.is_a?(Hash)
|
||||
data[:errors] || []
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
# Status code returned by the GitHub server.
|
||||
#
|
||||
# @return [Integer]
|
||||
def response_status
|
||||
@response[:status]
|
||||
end
|
||||
|
||||
# Headers returned by the GitHub server.
|
||||
#
|
||||
# @return [Hash]
|
||||
def response_headers
|
||||
@response[:response_headers]
|
||||
end
|
||||
|
||||
# Body returned by the GitHub server.
|
||||
#
|
||||
# @return [String]
|
||||
def response_body
|
||||
@response[:body]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def data
|
||||
@data ||=
|
||||
if (body = @response[:body]) && !body.empty?
|
||||
if body.is_a?(String) &&
|
||||
@response[:response_headers] &&
|
||||
@response[:response_headers][:content_type] =~ /json/
|
||||
|
||||
Sawyer::Agent.serializer.decode(body)
|
||||
else
|
||||
body
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def response_message
|
||||
case data
|
||||
when Hash
|
||||
data[:message]
|
||||
when String
|
||||
data
|
||||
end
|
||||
end
|
||||
|
||||
def response_error
|
||||
"Error: #{data[:error]}" if data.is_a?(Hash) && data[:error]
|
||||
end
|
||||
|
||||
def response_error_summary
|
||||
return nil unless data.is_a?(Hash) && !Array(data[:errors]).empty?
|
||||
|
||||
summary = +"\nError summary:\n"
|
||||
summary << data[:errors].map do |error|
|
||||
if error.is_a? Hash
|
||||
error.map { |k, v| " #{k}: #{v}" }
|
||||
else
|
||||
" #{error}"
|
||||
end
|
||||
end.join("\n")
|
||||
|
||||
summary
|
||||
end
|
||||
|
||||
def build_error_message
|
||||
return nil if @response.nil?
|
||||
|
||||
message = +"#{@response[:method].to_s.upcase} "
|
||||
message << "#{redact_url(@response[:url].to_s.dup)}: "
|
||||
message << "#{@response[:status]} - "
|
||||
message << response_message.to_s unless response_message.nil?
|
||||
message << response_error.to_s unless response_error.nil?
|
||||
message << response_error_summary.to_s unless response_error_summary.nil?
|
||||
message << " // See: #{documentation_url}" unless documentation_url.nil?
|
||||
message
|
||||
end
|
||||
|
||||
def redact_url(url_string)
|
||||
%w[client_secret access_token api_key].each do |token|
|
||||
if url_string.include? token
|
||||
url_string.gsub!(/#{token}=\S+/, "#{token}=(redacted)")
|
||||
end
|
||||
end
|
||||
url_string
|
||||
end
|
||||
end
|
||||
|
||||
# Raised on errors in the 400-499 range
|
||||
class ClientError < Error; end
|
||||
|
||||
# Raised when GitHub returns a 400 HTTP status code
|
||||
class BadRequest < ClientError; end
|
||||
|
||||
# Raised when GitHub returns a 401 HTTP status code
|
||||
class Unauthorized < ClientError; end
|
||||
|
||||
# Raised when GitHub returns a 401 HTTP status code
|
||||
# and headers include "X-GitHub-OTP"
|
||||
class OneTimePasswordRequired < ClientError
|
||||
# @private
|
||||
OTP_DELIVERY_PATTERN = /required; (\w+)/i.freeze
|
||||
|
||||
# @private
|
||||
def self.required_header(headers)
|
||||
OTP_DELIVERY_PATTERN.match headers['X-GitHub-OTP'].to_s
|
||||
end
|
||||
|
||||
# Delivery method for the user's OTP
|
||||
#
|
||||
# @return [String]
|
||||
def password_delivery
|
||||
@password_delivery ||= delivery_method_from_header
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def delivery_method_from_header
|
||||
if match = self.class.required_header(@response[:response_headers])
|
||||
match[1]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Raised when GitHub returns a 403 HTTP status code
|
||||
class Forbidden < ClientError; end
|
||||
|
||||
# Raised when GitHub returns a 403 HTTP status code
|
||||
# and body matches 'rate limit exceeded'
|
||||
class TooManyRequests < Forbidden; end
|
||||
|
||||
# Raised when GitHub returns a 403 HTTP status code
|
||||
# and body matches 'login attempts exceeded'
|
||||
class TooManyLoginAttempts < Forbidden; end
|
||||
|
||||
# Raised when GitHub returns a 403 HTTP status code
|
||||
# and body matches 'returns blobs up to [0-9]+ MB'
|
||||
class TooLargeContent < Forbidden; end
|
||||
|
||||
# Raised when GitHub returns a 403 HTTP status code
|
||||
# and body matches 'abuse'
|
||||
class AbuseDetected < Forbidden; end
|
||||
|
||||
# Raised when GitHub returns a 403 HTTP status code
|
||||
# and body matches 'repository access blocked'
|
||||
class RepositoryUnavailable < Forbidden; end
|
||||
|
||||
# Raised when GitHub returns a 403 HTTP status code
|
||||
# and body matches 'email address must be verified'
|
||||
class UnverifiedEmail < Forbidden; end
|
||||
|
||||
# Raised when GitHub returns a 403 HTTP status code
|
||||
# and body matches 'account was suspended'
|
||||
class AccountSuspended < Forbidden; end
|
||||
|
||||
# Raised when GitHub returns a 403 HTTP status code
|
||||
# and body matches 'billing issue'
|
||||
class BillingIssue < Forbidden; end
|
||||
|
||||
# Raised when GitHub returns a 403 HTTP status code
|
||||
# and body matches 'Resource protected by organization SAML enforcement'
|
||||
class SAMLProtected < Forbidden; end
|
||||
|
||||
# Raised when GitHub returns a 403 HTTP status code
|
||||
# and body matches 'suspended your access'
|
||||
class InstallationSuspended < Forbidden; end
|
||||
|
||||
# Raised when GitHub returns a 404 HTTP status code
|
||||
class NotFound < ClientError; end
|
||||
|
||||
# Raised when GitHub returns a 404 HTTP status code
|
||||
# and body matches 'Branch not protected'
|
||||
class BranchNotProtected < ClientError; end
|
||||
|
||||
# Raised when GitHub returns a 405 HTTP status code
|
||||
class MethodNotAllowed < ClientError; end
|
||||
|
||||
# Raised when GitHub returns a 406 HTTP status code
|
||||
class NotAcceptable < ClientError; end
|
||||
|
||||
# Raised when GitHub returns a 409 HTTP status code
|
||||
class Conflict < ClientError; end
|
||||
|
||||
# Raised when GitHub returns a 414 HTTP status code
|
||||
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
|
||||
|
||||
# Raised on errors in the 500-599 range
|
||||
class ServerError < Error; end
|
||||
|
||||
# Raised when GitHub returns a 500 HTTP status code
|
||||
class InternalServerError < ServerError; end
|
||||
|
||||
# Raised when GitHub returns a 501 HTTP status code
|
||||
class NotImplemented < ServerError; end
|
||||
|
||||
# Raised when GitHub returns a 502 HTTP status code
|
||||
class BadGateway < ServerError; end
|
||||
|
||||
# Raised when GitHub returns a 503 HTTP status code
|
||||
class ServiceUnavailable < ServerError; end
|
||||
|
||||
# Raised when client fails to provide valid Content-Type
|
||||
class MissingContentType < ArgumentError; end
|
||||
|
||||
# Raised when a method requires an application client_id
|
||||
# and secret but none is provided
|
||||
class ApplicationCredentialsRequired < StandardError; end
|
||||
|
||||
# Raised when a repository is created with an invalid format
|
||||
class InvalidRepository < ArgumentError; end
|
||||
|
||||
RATE_LIMITED_ERRORS = [Octokit::TooManyRequests, Octokit::AbuseDetected].freeze
|
||||
end
|
||||
@@ -0,0 +1,35 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
# Class to parse and create Gist URLs
|
||||
class Gist
|
||||
# !@attribute id
|
||||
# @return [String] Gist ID
|
||||
attr_accessor :id
|
||||
|
||||
# Instantiate {Gist} object from Gist URL
|
||||
# @ return [Gist]
|
||||
def self.from_url(url)
|
||||
Gist.new(URI.parse(url).path[1..])
|
||||
end
|
||||
|
||||
def initialize(gist)
|
||||
case gist
|
||||
when Integer, String
|
||||
@id = gist.to_s
|
||||
end
|
||||
end
|
||||
|
||||
# Gist ID
|
||||
# @return [String]
|
||||
def to_s
|
||||
@id
|
||||
end
|
||||
|
||||
# Gist URL
|
||||
# @return [String]
|
||||
def url
|
||||
"https://gist.github.com/#{@id}"
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,135 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'faraday'
|
||||
require 'set'
|
||||
|
||||
# Adapted from lostisland/faraday_middleware. Trimmed down to just the logic
|
||||
# that we need for octokit.rb.
|
||||
#
|
||||
# https://github.com/lostisland/faraday_middleware/blob/138766e/lib/faraday_middleware/response/follow_redirects.rb
|
||||
|
||||
module Octokit
|
||||
module Middleware
|
||||
# Public: Exception thrown when the maximum amount of requests is exceeded.
|
||||
class RedirectLimitReached < Faraday::ClientError
|
||||
attr_reader :response
|
||||
|
||||
def initialize(response)
|
||||
super "too many redirects; last one to: #{response['location']}"
|
||||
@response = response
|
||||
end
|
||||
end
|
||||
|
||||
# Public: Follow HTTP 301, 302, 303, and 307 redirects.
|
||||
#
|
||||
# For HTTP 303, the original GET, POST, PUT, DELETE, or PATCH request gets
|
||||
# converted into a GET. For HTTP 301, 302, and 307, the HTTP method remains
|
||||
# unchanged.
|
||||
#
|
||||
# This middleware currently only works with synchronous requests; i.e. it
|
||||
# doesn't support parallelism.
|
||||
class FollowRedirects < Faraday::Middleware
|
||||
# HTTP methods for which 30x redirects can be followed
|
||||
ALLOWED_METHODS = Set.new %i[head options get post put patch delete]
|
||||
|
||||
# HTTP redirect status codes that this middleware implements
|
||||
REDIRECT_CODES = Set.new [301, 302, 303, 307]
|
||||
|
||||
# Keys in env hash which will get cleared between requests
|
||||
ENV_TO_CLEAR = Set.new %i[status response response_headers]
|
||||
|
||||
# Default value for max redirects followed
|
||||
FOLLOW_LIMIT = 3
|
||||
|
||||
# Regex that matches characters that need to be escaped in URLs, sans
|
||||
# the "%" character which we assume already represents an escaped
|
||||
# sequence.
|
||||
URI_UNSAFE = %r{[^\-_.!~*'()a-zA-Z\d;/?:@&=+$,\[\]%]}.freeze
|
||||
|
||||
# Public: Initialize the middleware.
|
||||
#
|
||||
# options - An options Hash (default: {}):
|
||||
# :limit - A Integer redirect limit (default: 3).
|
||||
def initialize(app, options = {})
|
||||
super(app)
|
||||
@options = options
|
||||
|
||||
@convert_to_get = Set.new [303]
|
||||
end
|
||||
|
||||
def call(env)
|
||||
perform_with_redirection(env, follow_limit)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def convert_to_get?(response)
|
||||
!%i[head options].include?(response.env[:method]) &&
|
||||
@convert_to_get.include?(response.status)
|
||||
end
|
||||
|
||||
def perform_with_redirection(env, follows)
|
||||
request_body = env[:body]
|
||||
response = @app.call(env)
|
||||
|
||||
response.on_complete do |response_env|
|
||||
if follow_redirect?(response_env, response)
|
||||
raise(RedirectLimitReached, response) if follows.zero?
|
||||
|
||||
new_request_env = update_env(response_env, request_body, response)
|
||||
response = perform_with_redirection(new_request_env, follows - 1)
|
||||
end
|
||||
end
|
||||
response
|
||||
end
|
||||
|
||||
def update_env(env, request_body, response)
|
||||
original_url = env[:url]
|
||||
env[:url] += safe_escape(response['location'])
|
||||
unless same_host?(original_url, env[:url])
|
||||
# HACK: Faraday’s Authorization middlewares don’t touch the request if the `Authorization` header is set.
|
||||
# This is a workaround to drop authentication info.
|
||||
# See https://github.com/octokit/octokit.rb/pull/1359#issuecomment-925609697
|
||||
env[:request_headers]['Authorization'] = 'dummy'
|
||||
end
|
||||
|
||||
if convert_to_get?(response)
|
||||
env[:method] = :get
|
||||
env[:body] = nil
|
||||
else
|
||||
env[:body] = request_body
|
||||
end
|
||||
|
||||
ENV_TO_CLEAR.each { |key| env.delete(key) }
|
||||
|
||||
env
|
||||
end
|
||||
|
||||
def follow_redirect?(env, response)
|
||||
ALLOWED_METHODS.include?(env[:method]) &&
|
||||
REDIRECT_CODES.include?(response.status)
|
||||
end
|
||||
|
||||
def follow_limit
|
||||
@options.fetch(:limit, FOLLOW_LIMIT)
|
||||
end
|
||||
|
||||
def same_host?(original_url, redirect_url)
|
||||
original_uri = Addressable::URI.parse(original_url)
|
||||
redirect_uri = Addressable::URI.parse(redirect_url)
|
||||
|
||||
redirect_uri.host.nil? || original_uri.host == redirect_uri.host
|
||||
end
|
||||
|
||||
# Internal: Escapes unsafe characters from a URL which might be a path
|
||||
# component only or a fully-qualified URI so that it can be joined onto a
|
||||
# URI:HTTP using the `+` operator. Doesn't escape "%" characters so to not
|
||||
# risk double-escaping.
|
||||
def safe_escape(uri)
|
||||
uri.to_s.gsub(URI_UNSAFE) do |match|
|
||||
"%#{match.unpack('H2' * match.bytesize).join('%').upcase}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,19 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
# GitHub organization class to generate API path urls
|
||||
class Organization
|
||||
# Get the api path for an organization
|
||||
#
|
||||
# @param org [String, Integer] GitHub organization login or id
|
||||
# @return [String] Organization Api path
|
||||
def self.path(org)
|
||||
case org
|
||||
when String
|
||||
"orgs/#{org}"
|
||||
when Integer
|
||||
"organizations/#{org}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,35 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
# Class for API Rate Limit info
|
||||
#
|
||||
# @!attribute [w] limit
|
||||
# @return [Integer] Max tries per rate limit period
|
||||
# @!attribute [w] remaining
|
||||
# @return [Integer] Remaining tries per rate limit period
|
||||
# @!attribute [w] resets_at
|
||||
# @return [Time] Indicates when rate limit resets
|
||||
# @!attribute [w] resets_in
|
||||
# @return [Integer] Number of seconds when rate limit resets
|
||||
#
|
||||
# @see https://developer.github.com/v3/#rate-limiting
|
||||
class RateLimit < Struct.new(:limit, :remaining, :resets_at, :resets_in)
|
||||
# Get rate limit info from HTTP response
|
||||
#
|
||||
# @param response [#headers] HTTP response
|
||||
# @return [RateLimit]
|
||||
def self.from_response(response)
|
||||
info = new
|
||||
headers = response.headers if response.respond_to?(:headers) && !response.headers.nil?
|
||||
headers ||= response.response_headers if response.respond_to?(:response_headers) && !response.response_headers.nil?
|
||||
if headers
|
||||
info.limit = (headers['X-RateLimit-Limit'] || 1).to_i
|
||||
info.remaining = (headers['X-RateLimit-Remaining'] || 1).to_i
|
||||
info.resets_at = Time.at((headers['X-RateLimit-Reset'] || Time.now).to_i)
|
||||
info.resets_in = [(info.resets_at - Time.now).to_i, 0].max
|
||||
end
|
||||
|
||||
info
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
# Class to extract options from Ruby arguments for
|
||||
# Repository-related methods
|
||||
class RepoArguments < Arguments
|
||||
# !@attribute [r] repo
|
||||
# @return [Repository]
|
||||
attr_reader :repo
|
||||
|
||||
def initialize(args)
|
||||
arguments = super(args)
|
||||
@repo = arguments.shift
|
||||
|
||||
arguments
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,95 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
# Class to parse GitHub repository owner and name from
|
||||
# URLs and to generate URLs
|
||||
class Repository
|
||||
attr_accessor :owner, :name, :id
|
||||
|
||||
NAME_WITH_OWNER_PATTERN = %r{\A[\w.-]+/[\w.-]+\z}i.freeze
|
||||
|
||||
# Instantiate from a GitHub repository URL
|
||||
#
|
||||
# @return [Repository]
|
||||
def self.from_url(url)
|
||||
new URI.parse(url).path[1..]
|
||||
.gsub(%r{^repos/}, '')
|
||||
.split('/', 3)[0..1]
|
||||
.join('/')
|
||||
end
|
||||
|
||||
# @raise [Octokit::InvalidRepository] if the repository
|
||||
# has an invalid format
|
||||
def initialize(repo)
|
||||
case repo
|
||||
when Integer
|
||||
@id = repo
|
||||
when NAME_WITH_OWNER_PATTERN
|
||||
@owner, @name = repo.split('/')
|
||||
when Repository
|
||||
@owner = repo.owner
|
||||
@name = repo.name
|
||||
when Hash
|
||||
@name = repo[:repo] || repo[:name]
|
||||
@owner = repo[:owner] || repo[:user] || repo[:username]
|
||||
else
|
||||
raise_invalid_repository!(repo)
|
||||
end
|
||||
validate_owner_and_name!(repo) if @owner && @name
|
||||
end
|
||||
|
||||
# Repository owner/name
|
||||
# @return [String]
|
||||
def slug
|
||||
"#{@owner}/#{@name}"
|
||||
end
|
||||
alias to_s slug
|
||||
|
||||
# @return [String] Repository API path
|
||||
def path
|
||||
return named_api_path if @owner && @name
|
||||
return id_api_path if @id
|
||||
end
|
||||
|
||||
# Get the api path for a repo
|
||||
# @param repo [Integer, String, Hash, Repository] A GitHub repository.
|
||||
# @return [String] Api path.
|
||||
def self.path(repo)
|
||||
new(repo).path
|
||||
end
|
||||
|
||||
# @return [String] Api path for owner/name identified repos
|
||||
def named_api_path
|
||||
"repos/#{slug}"
|
||||
end
|
||||
|
||||
# @return [String] Api path for id identified repos
|
||||
def id_api_path
|
||||
"repositories/#{@id}"
|
||||
end
|
||||
|
||||
# Repository URL based on {Octokit::Client#web_endpoint}
|
||||
# @return [String]
|
||||
def url
|
||||
"#{Octokit.web_endpoint}#{slug}"
|
||||
end
|
||||
|
||||
alias user owner
|
||||
alias username owner
|
||||
alias repo name
|
||||
|
||||
private
|
||||
|
||||
def validate_owner_and_name!(repo)
|
||||
if @owner.include?('/') || @name.include?('/') || !url.match(URI::ABS_URI)
|
||||
raise_invalid_repository!(repo)
|
||||
end
|
||||
end
|
||||
|
||||
def raise_invalid_repository!(repo)
|
||||
msg = "#{repo.inspect} is invalid as a repository identifier. " \
|
||||
'Use the user/repo (String) format, or the repository ID (Integer), or a hash containing :repo and :user keys.'
|
||||
raise Octokit::InvalidRepository, msg
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'faraday'
|
||||
|
||||
module Octokit
|
||||
module Response
|
||||
# In Faraday 2.x, Faraday::Response::Middleware was removed
|
||||
BaseMiddleware = defined?(Faraday::Response::Middleware) ? Faraday::Response::Middleware : Faraday::Middleware
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,17 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'octokit/response/base_middleware'
|
||||
|
||||
module Octokit
|
||||
module Response
|
||||
# Parses RSS and Atom feed responses.
|
||||
class FeedParser < BaseMiddleware
|
||||
def on_complete(env)
|
||||
if env[:response_headers]['content-type'] =~ /(\batom|\brss)/
|
||||
require 'rss'
|
||||
env[:body] = RSS::Parser.parse env[:body]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,19 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'octokit/response/base_middleware'
|
||||
require 'octokit/error'
|
||||
|
||||
module Octokit
|
||||
# Faraday response middleware
|
||||
module Response
|
||||
# This class raises an Octokit-flavored exception based
|
||||
# HTTP status codes returned by the API
|
||||
class RaiseError < BaseMiddleware
|
||||
def on_complete(response)
|
||||
if error = Octokit::Error.from_response(response)
|
||||
raise error
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
# GitHub user class to generate API path urls
|
||||
class User
|
||||
# Get the api path for a user
|
||||
#
|
||||
# @param user [String, Integer] GitHub user login or id
|
||||
# @return [String] User Api path
|
||||
def self.path(user)
|
||||
case user
|
||||
when String
|
||||
"users/#{user}"
|
||||
when Integer
|
||||
"user/#{user}"
|
||||
else
|
||||
'user'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,19 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
# Current major release.
|
||||
# @return [Integer]
|
||||
MAJOR = 6
|
||||
|
||||
# Current minor release.
|
||||
# @return [Integer]
|
||||
MINOR = 1
|
||||
|
||||
# Current patch level.
|
||||
# @return [Integer]
|
||||
PATCH = 1
|
||||
|
||||
# Full release version.
|
||||
# @return [String]
|
||||
VERSION = [MAJOR, MINOR, PATCH].join('.').freeze
|
||||
end
|
||||
@@ -0,0 +1,16 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Octokit
|
||||
# Allows warnings to be suppressed via environment variable.
|
||||
module Warnable
|
||||
module_function
|
||||
|
||||
# Wrapper around Kernel#warn to print warnings unless
|
||||
# OCTOKIT_SILENT is set to true.
|
||||
#
|
||||
# @return [nil]
|
||||
def octokit_warn(*message)
|
||||
warn message unless ENV['OCTOKIT_SILENT']
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,25 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
lib = File.expand_path('lib', __dir__)
|
||||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||
require 'octokit/version'
|
||||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.add_development_dependency 'bundler', '>= 1', '< 3'
|
||||
spec.add_dependency 'faraday', '>= 1', '< 3'
|
||||
spec.add_dependency 'sawyer', '~> 0.9'
|
||||
spec.authors = ['Wynn Netherland', 'Erik Michaels-Ober', 'Clint Shryock']
|
||||
spec.description = 'Simple wrapper for the GitHub API'
|
||||
spec.email = ['wynn.netherland@gmail.com', 'sferik@gmail.com', 'clint@ctshryock.com']
|
||||
spec.files = %w[.document CONTRIBUTING.md LICENSE.md README.md Rakefile octokit.gemspec]
|
||||
spec.files += Dir.glob('lib/**/*.rb')
|
||||
spec.homepage = 'https://github.com/octokit/octokit.rb'
|
||||
spec.licenses = ['MIT']
|
||||
spec.name = 'octokit'
|
||||
spec.require_paths = ['lib']
|
||||
spec.required_ruby_version = '>= 2.7.0'
|
||||
spec.required_rubygems_version = '>= 1.3.5'
|
||||
spec.summary = 'Ruby toolkit for working with the GitHub API'
|
||||
spec.version = Octokit::VERSION.dup
|
||||
spec.metadata = { 'rubygems_mfa_required' => 'true' }
|
||||
end
|
||||
Reference in New Issue
Block a user