diff --git a/docs/v3-to-v4-update.md b/docs/v3-to-v4-update.md index 1098ef1e..c02e73e5 100644 --- a/docs/v3-to-v4-update.md +++ b/docs/v3-to-v4-update.md @@ -5,3 +5,42 @@ The following changes were made to the Github API package between v3 and v4. ### Minimum supported PHP version raised All Framework packages now require PHP 8.3 or newer. + +### Modern API headers and authentication (since 4.1) + +Starting with version 4.1, `fetchUrl()` automatically sends `Accept: application/vnd.github+json` and pins +`X-GitHub-Api-Version` to `2022-11-28` on every request, matching GitHub's currently recommended REST API +conventions. Both headers are only added if you haven't already set them yourself on the HTTP client, so +existing code that manages its own headers is unaffected. + +If you need a different API version, set the `api.version` option: + +```php +$options->set('api.version', '2022-11-28'); +``` + +A new `gh.token.scheme` option (default `token`, unchanged) lets you send the `Authorization` header using the +`Bearer` scheme instead, which some fine-grained personal access tokens and GitHub App installation tokens +require: + +```php +$options->set('gh.token', $token); +$options->set('gh.token.scheme', 'Bearer'); +``` + +HTTP Basic Authentication (`api.username` / `api.password`) against `https://api.github.com` no longer works — +GitHub removed it in November 2020. Use `gh.token` instead. The `api.username` / `api.password` options remain +available for GitHub Enterprise Server instances that still accept them. + +### `Authorization` and `Repositories\Downloads` are deprecated (since 4.1) + +`Package\Authorization` wrapped GitHub's OAuth Authorizations API, and `Package\Repositories\Downloads` wrapped +the Repository Downloads API. GitHub has removed both endpoints from github.com (OAuth Authorizations in +November 2020; Downloads years earlier), so every method on these two classes now fails against live GitHub. +The classes are kept so existing `$github->authorization` and `$github->repositories->downloads` call sites +don't fatal, but they are marked `@deprecated`; `Authorization` is scheduled for removal in 5.0. + +* Replace `$github->authorization` usage with a personal access token passed via the `gh.token` option, or the + GitHub Apps / OAuth device flow once supported. +* Replace `$github->repositories->downloads` usage with `$github->repositories->releases`, which manages + release assets. diff --git a/src/AbstractGithubObject.php b/src/AbstractGithubObject.php index 80fa942a..ddcc43d6 100644 --- a/src/AbstractGithubObject.php +++ b/src/AbstractGithubObject.php @@ -109,22 +109,42 @@ public function __construct(Registry $options = null, BaseHttp $client = null) * @return Uri * * @since 1.0 + * @since __DEPLOY_VERSION__ Sets a default `Accept: application/vnd.github+json` header and pins + * `X-GitHub-Api-Version` (overridable via the `api.version` option, or by + * setting either header on the HTTP client before the request). The + * `gh.token.scheme` option (default `token`, unchanged) may be set to + * `Bearer` for fine-grained PATs / GitHub App installation tokens. */ protected function fetchUrl($path, $page = 0, $limit = 0) { // Get a new Uri object focusing the api url and given path. $uri = new Uri($this->options->get('api.url') . $path); + $headers = $this->client->getOption('headers', []); + + // Pin the REST API media type and version unless the consumer already set their own. + if (!isset($headers['Accept'])) { + $headers['Accept'] = 'application/vnd.github+json'; + } + + if (!isset($headers['X-GitHub-Api-Version'])) { + $headers['X-GitHub-Api-Version'] = $this->options->get('api.version', '2022-11-28'); + } + if ($this->options->get('gh.token', false)) { // Use oAuth authentication - $headers = $this->client->getOption('headers', []); - if (!isset($headers['Authorization'])) { - $headers['Authorization'] = 'token ' . $this->options->get('gh.token'); - $this->client->setOption('headers', $headers); + // 'token' is the classic scheme; set gh.token.scheme to 'Bearer' for fine-grained + // PATs or GitHub App installation tokens, both of which GitHub also accepts as 'token'. + $scheme = $this->options->get('gh.token.scheme', 'token'); + + $headers['Authorization'] = $scheme . ' ' . $this->options->get('gh.token'); } } else { // Use basic authentication + // Note: GitHub removed username/password Basic authentication for the API in + // November 2020; this path is kept only for compatibility with Enterprise Server + // instances that may still accept it. Use gh.token for github.com. if ($this->options->get('api.username', false)) { $uri->setUser($this->options->get('api.username')); } @@ -134,6 +154,8 @@ protected function fetchUrl($path, $page = 0, $limit = 0) } } + $this->client->setOption('headers', $headers); + // If we have a defined page number add it to the JUri object. if ($page > 0) { $uri->setVar('page', (int) $page); diff --git a/src/Package/Authorization.php b/src/Package/Authorization.php index 10b881f2..a0300e3c 100644 --- a/src/Package/Authorization.php +++ b/src/Package/Authorization.php @@ -19,8 +19,13 @@ * @documentation http://developer.github.com/v3/oauth/ * @documentation http://developer.github.com/v3/oauth_authorizations/ * - * @note The methods in this class are only accessible with Basic Authentication - * @since 1.0 + * @note The methods in this class are only accessible with Basic Authentication + * @since 1.0 + * @deprecated __DEPLOY_VERSION__ will be removed in 5.0. GitHub removed the OAuth + * Authorizations API (and Basic Authentication for the API) in November 2020; + * every method in this class now fails against github.com. Kept only so + * existing `$github->authorization` call sites don't fatal. Use GitHub Apps / OAuth + * device flow (Package\Apps) or a personal access token via the `gh.token` option instead. */ class Authorization extends AbstractPackage { diff --git a/src/Package/Repositories/Downloads.php b/src/Package/Repositories/Downloads.php index 4e23ea1a..b8168deb 100644 --- a/src/Package/Repositories/Downloads.php +++ b/src/Package/Repositories/Downloads.php @@ -21,7 +21,10 @@ * @documentation https://developer.github.com/v3/repos/downloads * * @since 1.0 - * @deprecated The Releases API should be used instead + * @deprecated __DEPLOY_VERSION__ will be removed in 5.0. GitHub removed the Repository Downloads API entirely in + * 2020; every method in this class now 404s against github.com. Kept only so + * existing `$github->repositories->downloads` call sites don't fatal. Use + * Package\Repositories\Releases (release assets) instead. */ class Downloads extends AbstractPackage {