From 02d6c81480b99284cfe7cce7fd314e0f3c95a617 Mon Sep 17 00:00:00 2001 From: Martin Bean Date: Fri, 18 Jun 2021 20:39:38 +0100 Subject: [PATCH 01/98] feature #994 Add create a repository using a template endpoint (martinbean) This PR was squashed before being merged into the 3.3.x-dev branch. Discussion ---------- Adds methods to [create a repository using a template][1], and also contributes a few test cases for the various options. Resolves #976 [1]: https://docs.github.com/en/rest/reference/repos#create-a-repository-using-a-template Commits ------- 58b294f856eb74488a9fdd8e8549cc66bc023ae1 Add create a repository using a template endpoint 9fabcf701f26561b74f7a9e4d6d9c185d27508fd Make parameters array instead c70f39f6ab0e546b9eabfdf52c78aeb311f83d60 Document create repository from template 79ebd98dbb64142acebf95114d7cf46afc56f84b Type-hint parameters --- doc/repos.md | 11 +++++++++++ lib/Github/Api/Repo.php | 12 ++++++++++++ test/Github/Tests/Api/RepoTest.php | 26 ++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/doc/repos.md b/doc/repos.md index 0a4d234a695..ab412dc77c2 100644 --- a/doc/repos.md +++ b/doc/repos.md @@ -370,3 +370,14 @@ Example when you want to configure custom github action workflows. ```php $client->api('repo')->dispatch('KnpLabs', 'php-github-api', 'acme-event', ['foo'=>'bar']); ``` + +### Create a repository using a template + +Create a new repository using a repository template. + +```php +$client->api('repo')->createFromTemplate('template-owner', 'template-repo', [ + 'name' => 'name-of-new-repo', + 'owner' => 'name-of-new-repo-owner', // can be user or org +]); +``` diff --git a/lib/Github/Api/Repo.php b/lib/Github/Api/Repo.php index fcaa196d264..15e51b38bd2 100644 --- a/lib/Github/Api/Repo.php +++ b/lib/Github/Api/Repo.php @@ -793,4 +793,16 @@ public function transfer($username, $repository, $newOwner, $teamId = []) { return $this->post('/repos/'.rawurldecode($username).'/'.rawurldecode($repository).'/transfer', ['new_owner' => $newOwner, 'team_id' => $teamId]); } + + /** + * Create a repository using a template. + * + * @link https://developer.github.com/v3/repos/#create-a-repository-using-a-template + * + * @return array + */ + public function createFromTemplate(string $templateOwner, string $templateRepo, array $parameters = []) + { + return $this->post('/repos/'.rawurldecode($templateOwner).'/'.rawurldecode($templateRepo).'/generate', $parameters); + } } diff --git a/test/Github/Tests/Api/RepoTest.php b/test/Github/Tests/Api/RepoTest.php index 083d7201aa8..3761b2efb7e 100644 --- a/test/Github/Tests/Api/RepoTest.php +++ b/test/Github/Tests/Api/RepoTest.php @@ -626,6 +626,32 @@ public function shouldTransferRepository() $this->assertEquals($expectedArray, $api->transfer('KnpLabs', 'php-github-api', 'github', [1234, 1235])); } + /** + * @test + */ + public function shouldCreateRepositoryUsingTemplate() + { + $expectedArray = [ + 'id' => 1, + 'name' => 'newrepo', + 'full_name' => 'johndoe/newrepo', + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('/repos/acme/template/generate', [ + 'name' => 'newrepo', + 'owner' => 'johndoe', + ]) + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->createFromTemplate('acme', 'template', [ + 'name' => 'newrepo', + 'owner' => 'johndoe', + ])); + } + /** * @return string */ From fd8954b274708d2b5bfc246a399682cad736096f Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Fri, 18 Jun 2021 21:40:43 +0200 Subject: [PATCH 02/98] Bump branch alias --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 328128743ff..d65a6e02d0c 100644 --- a/composer.json +++ b/composer.json @@ -52,7 +52,7 @@ "extra": { "branch-alias": { "dev-2.x": "2.20.x-dev", - "dev-master": "3.3.x-dev" + "dev-master": "3.4.x-dev" } } } From d73a1e0f24d697d1b4b528acd6fc445bea1a751e Mon Sep 17 00:00:00 2001 From: bery Date: Fri, 9 Jul 2021 17:24:32 +0200 Subject: [PATCH 03/98] Allow fetching repo readme for a specific ref As per Github's API it is possible to fetch a readme file for specific branch or tag https://docs.github.com/en/rest/reference/repos#get-a-repository-readme --- lib/Github/Api/Repo.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/Github/Api/Repo.php b/lib/Github/Api/Repo.php index 15e51b38bd2..30ee37ff6e4 100644 --- a/lib/Github/Api/Repo.php +++ b/lib/Github/Api/Repo.php @@ -257,12 +257,13 @@ public function remove($username, $repository) * @param string $username the user who owns the repository * @param string $repository the name of the repository * @param string $format one of formats: "raw", "html", or "v3+json" + * @param array $params additional query params like "ref" to fetch readme for branch/tag * * @return string|array the readme content */ - public function readme($username, $repository, $format = 'raw') + public function readme($username, $repository, $format = 'raw', $params = []) { - return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/readme', [], [ + return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/readme', $params, [ 'Accept' => "application/vnd.github.$format", ]); } From de9637945acd615f1290f3a8f7db7fa998ae3a83 Mon Sep 17 00:00:00 2001 From: Stephan Date: Sun, 11 Jul 2021 20:56:43 +0100 Subject: [PATCH 04/98] minor #1017 Update integration authentication documentation for usage with lcobucci/jwt ^4 (glaubinix) This PR was squashed before being merged into the 3.4.x-dev branch. Discussion ---------- The security docs were mentioning `lcobucci/jwt:^3.4` which doesn't support php 8. Updated the security docs to reflect all necessary changes to work with `lcobucci/jwt:^4.1` Passing `ChainedFormatter::withUnixTimestampDates()` to the builder method is necessary because otherwise all dates will be format via `$date->format('U.u')` as microseconds. GitHub expects unix timestamps and will return a 401 response with `'Expiration time' claim ('exp') must be a numeric value representing the future time at which the assertion expires`. Commits ------- 917192c14a61237e2352fb7a906a0a1ef04815ec Update integration authentication documentation for usage with lcobucci/jwt ^4 73dea747e8fd469cecfdef16ac57ecacfa0cd5e7 Docs: add builder to JWT authentication --- doc/security.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/doc/security.md b/doc/security.md index b7e94783890..b62ca4c05fc 100644 --- a/doc/security.md +++ b/doc/security.md @@ -37,14 +37,18 @@ and installation access token which is then usable with `Github\Client::AUTH_ACC authentication docs](https://developer.github.com/apps/building-github-apps/authentication-options-for-github-apps/#authenticating-as-a-github-app) describe the flow in detail. It´s important for integration requests to use the custom Accept header `application/vnd.github.machine-man-preview`. -The following sample code authenticates as an installation using [lcobucci/jwt 3.4](https://github.com/lcobucci/jwt/tree/3.4) +The following sample code authenticates as an installation using [lcobucci/jwt 4.1](https://github.com/lcobucci/jwt/tree/4.1.x) to generate a JSON Web Token (JWT). ```php +use Github\HttpClient\Builder; use Lcobucci\JWT\Configuration; +use Lcobucci\JWT\Encoding\ChainedFormatter; use Lcobucci\JWT\Signer\Key\LocalFileReference; use Lcobucci\JWT\Signer\Rsa\Sha256; +$builder = new Builder(); + $github = new Github\Client($builder, 'machine-man-preview'); $config = Configuration::forSymmetricSigner( @@ -53,14 +57,14 @@ $config = Configuration::forSymmetricSigner( ); $now = new \DateTimeImmutable(); -$jwt = $config->builder() +$jwt = $config->builder(ChainedFormatter::withUnixTimestampDates()) ->issuedBy($integrationId) ->issuedAt($now) ->expiresAt($now->modify('+1 minute')) ->getToken($config->signer(), $config->signingKey()) ; -$github->authenticate($jwt, null, Github\Client::AUTH_JWT) +$github->authenticate($jwt->toString(), null, Github\Client::AUTH_JWT) ``` The `$integrationId` you can find in the about section of your github app. From c593113de147c0db86ec4903e365d45327564fb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20Klabbers?= Date: Tue, 13 Jul 2021 19:06:09 +0200 Subject: [PATCH 05/98] feature #1018 allow assigning role to organisation members (luceos) This PR was squashed before being merged into the 3.4.x-dev branch. Discussion ---------- This PR allows you to assign the `admin` role to new members of the organisation. Ref: https://docs.github.com/en/rest/reference/orgs#set-organization-membership-for-a-user Commits ------- eb4e3c2ef738386cac0c7d96e486f267a8f13eda allow assigning roles to organisation members 480b9193151b1d93bed1266ba0183b96f27710cc remove default value and role check --- lib/Github/Api/Organization/Members.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Github/Api/Organization/Members.php b/lib/Github/Api/Organization/Members.php index 3639e3ba57d..023e3f8d545 100644 --- a/lib/Github/Api/Organization/Members.php +++ b/lib/Github/Api/Organization/Members.php @@ -58,9 +58,9 @@ public function conceal($organization, $username) /* * Add user to organization */ - public function add($organization, $username) + public function add($organization, $username, array $params = []) { - return $this->put('/orgs/'.rawurlencode($organization).'/memberships/'.rawurlencode($username)); + return $this->put('/orgs/'.rawurlencode($organization).'/memberships/'.rawurlencode($username), $params); } public function addMember($organization, $username) From 2e58baace31b6463431fb54dccd5b8fd96cd873d Mon Sep 17 00:00:00 2001 From: pitonic Date: Tue, 13 Jul 2021 13:18:51 -0400 Subject: [PATCH 06/98] feature #1020 Branch lists . ( ? query per_page) (pitonic) This PR was squashed before being merged into the 3.4.x-dev branch. Discussion ---------- For function "branches" added: parameters for the query string. example to use: ``` return $this->client->api('repo')->branches($this->id, $repo, null , [ 'page' =>2, 'per_page' => 100 ]); ``` Commits ------- ab3d87b10cfd830720e1e3ea983d8109188639a7 added: parameters for the query string 44c39238b084aa07c236b2aacc4a67df25f6c448 fixed formating --- lib/Github/Api/Repo.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/Github/Api/Repo.php b/lib/Github/Api/Repo.php index 30ee37ff6e4..b5d11debf68 100644 --- a/lib/Github/Api/Repo.php +++ b/lib/Github/Api/Repo.php @@ -503,17 +503,18 @@ public function statuses() * @param string $username the username * @param string $repository the name of the repository * @param string $branch the name of the branch + * @param array $parameters parameters for the query string * * @return array list of the repository branches */ - public function branches($username, $repository, $branch = null) + public function branches($username, $repository, $branch = null, array $parameters = []) { $url = '/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/branches'; if (null !== $branch) { $url .= '/'.rawurlencode($branch); } - return $this->get($url); + return $this->get($url, $parameters); } /** From 2e36702b083df81047e626479d69125751c9fb9a Mon Sep 17 00:00:00 2001 From: Tom Sowerby Date: Thu, 19 Aug 2021 16:21:17 +0100 Subject: [PATCH 07/98] Update result_pager.md Quick update to the docs as I notice this method has been removed in v3. --- doc/result_pager.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/doc/result_pager.md b/doc/result_pager.md index 3eb0a115f5f..b13432cb569 100644 --- a/doc/result_pager.md +++ b/doc/result_pager.md @@ -63,7 +63,3 @@ $paginator->hasPrevious(); $paginator->fetchPrevious(); ``` -If you want to retrieve the pagination links (available after the call to fetch): -```php -$paginator->getPagination(); -``` From cad499e4f2b1f25f94dfb2113b689c9e07b4f217 Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Wed, 15 Sep 2021 22:30:53 +0200 Subject: [PATCH 08/98] feature #1025 Php8.1 support (acrobat) This PR was squashed before being merged into the 3.4.x-dev branch. Discussion ---------- Commits ------- 1b8b3bab407e87183a123f810d15cb914c2ed764 Test against php 8.1 bd57aec7c83b784cea30d919bccc41dd3594228f Fixed php 8.1 warnings and phpunit 10 depercation --- .github/workflows/ci.yml | 2 +- test/Github/Tests/Api/PullRequestTest.php | 14 +++++++------- .../Plugin/GithubExceptionThrowerTest.php | 8 +++----- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 83e62d87e29..175c5f09a0e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - php-versions: ['7.2', '7.3', '7.4', '8.0'] + php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1'] steps: - uses: actions/checkout@v2 diff --git a/test/Github/Tests/Api/PullRequestTest.php b/test/Github/Tests/Api/PullRequestTest.php index 90505535ff9..fe5b87c9d6d 100644 --- a/test/Github/Tests/Api/PullRequestTest.php +++ b/test/Github/Tests/Api/PullRequestTest.php @@ -144,15 +144,15 @@ public function shouldShowStatusesFromPullRequest() $expectedArray['_links']['statuses']['href'] = '/repos/ezsystems/ezpublish/pulls/15/statuses'; $api = $this->getApiMock(); - $api->expects($this->at(0)) - ->method('get') - ->with('/repos/ezsystems/ezpublish/pulls/15') - ->will($this->returnValue($expectedArray)); - $api->expects($this->at(1)) + $api->expects($this->exactly(2)) ->method('get') - ->with('/repos/ezsystems/ezpublish/pulls/15/statuses') - ->will($this->returnValue($expectedArray)); + ->withConsecutive( + [$this->equalTo('/repos/ezsystems/ezpublish/pulls/15')], + [$this->equalTo('/repos/ezsystems/ezpublish/pulls/15/statuses')] + ) + ->willReturn($expectedArray) + ; $this->assertEquals($expectedArray, $api->status('ezsystems', 'ezpublish', '15')); } diff --git a/test/Github/Tests/HttpClient/Plugin/GithubExceptionThrowerTest.php b/test/Github/Tests/HttpClient/Plugin/GithubExceptionThrowerTest.php index 4f6f9a5615b..99973521980 100644 --- a/test/Github/Tests/HttpClient/Plugin/GithubExceptionThrowerTest.php +++ b/test/Github/Tests/HttpClient/Plugin/GithubExceptionThrowerTest.php @@ -4,6 +4,7 @@ use Github\Exception\ExceptionInterface; use Github\HttpClient\Plugin\GithubExceptionThrower; +use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; use Http\Client\Promise\HttpFulfilledPromise; use Http\Client\Promise\HttpRejectedPromise; @@ -17,14 +18,11 @@ class GithubExceptionThrowerTest extends TestCase { /** - * @param ResponseInterface $response - * @param ExceptionInterface|\Exception|null $exception * @dataProvider responseProvider */ - public function testHandleRequest(ResponseInterface $response, ExceptionInterface $exception = null) + public function testHandleRequest(ResponseInterface $response, ExceptionInterface $exception = null): void { - /** @var RequestInterface $request */ - $request = $this->getMockForAbstractClass(RequestInterface::class); + $request = new Request('GET', 'https://api.github.com/issues'); $promise = new HttpFulfilledPromise($response); From bfa97f673dd3ea0fa57134204565ef7c404deec4 Mon Sep 17 00:00:00 2001 From: Maxime Veber Date: Thu, 23 Sep 2021 00:06:20 +0200 Subject: [PATCH 09/98] fix(doc): links to doc in CurrentUser class --- lib/Github/Api/CurrentUser.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/Github/Api/CurrentUser.php b/lib/Github/Api/CurrentUser.php index 70600a855a8..b5cbc89a376 100644 --- a/lib/Github/Api/CurrentUser.php +++ b/lib/Github/Api/CurrentUser.php @@ -54,7 +54,7 @@ public function followers($page = 1) } /** - * @link http://developer.github.com/v3/issues/#list-issues + * @link https://docs.github.com/en/rest/reference/issues#list-user-account-issues-assigned-to-the-authenticated-user * * @param array $params * @param bool $includeOrgIssues @@ -91,7 +91,7 @@ public function memberships() } /** - * @link http://developer.github.com/v3/orgs/#list-user-organizations + * @link https://docs.github.com/en/rest/reference/orgs#list-organizations-for-the-authenticated-user * * @return array */ @@ -111,7 +111,7 @@ public function teams() } /** - * @link http://developer.github.com/v3/repos/#list-your-repositories + * @link https://docs.github.com/en/rest/reference/repos#list-repositories-for-the-authenticated-user * * @param string $type role in the repository * @param string $sort sort by @@ -159,7 +159,7 @@ public function starring() } /** - * @link https://developer.github.com/v3/activity/watching/#list-repositories-being-watched + * @link https://docs.github.com/en/rest/reference/activity#list-repositories-watched-by-the-authenticated-user */ public function subscriptions() { @@ -167,7 +167,7 @@ public function subscriptions() } /** - * @link https://developer.github.com/v3/apps/installations/#list-app-installations-accessible-to-the-user-access-token + * @link https://docs.github.com/en/rest/reference/apps#list-app-installations-accessible-to-the-user-access-token * * @param array $params */ From 5d77c8195dcb51f52a0b50e6181bc4a7c81c15d8 Mon Sep 17 00:00:00 2001 From: John Noel Date: Sun, 26 Sep 2021 16:30:33 +0100 Subject: [PATCH 10/98] Allow psr/cache 2.0 as well as 1.0 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index d65a6e02d0c..71924b18e59 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "php-http/discovery": "^1.12", "php-http/httplug": "^2.2", "php-http/multipart-stream-builder": "^1.1.2", - "psr/cache": "^1.0", + "psr/cache": "^1.0|^2.0", "psr/http-client-implementation": "^1.0", "psr/http-factory-implementation": "^1.0", "psr/http-message": "^1.0", From de92500d4ca47743d81f39296f74104891ca88de Mon Sep 17 00:00:00 2001 From: David Peach Date: Fri, 1 Oct 2021 08:48:43 +0100 Subject: [PATCH 11/98] bug #1030 Add accept header for creating repo from template (davidpeach) This PR was squashed before being merged into the 3.4.x-dev branch. Discussion ---------- This still requires an accept header as per the docs: https://docs.github.com/en/rest/reference/repos#create-a-repository-using-a-template-preview-notices Commits ------- 34e33707af1ca963b636855f7dde4138aad89c7f Add accept header for creating repo from template 91b39118798ad4fc1a90ee4dd9804b3c00c4a2d7 Update Repo.php --- lib/Github/Api/Repo.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/Github/Api/Repo.php b/lib/Github/Api/Repo.php index b5d11debf68..dfbd39b991a 100644 --- a/lib/Github/Api/Repo.php +++ b/lib/Github/Api/Repo.php @@ -805,6 +805,9 @@ public function transfer($username, $repository, $newOwner, $teamId = []) */ public function createFromTemplate(string $templateOwner, string $templateRepo, array $parameters = []) { + //This api is in preview mode, so set the correct accept-header + $this->acceptHeaderValue = 'application/vnd.github.baptiste-preview+json'; + return $this->post('/repos/'.rawurldecode($templateOwner).'/'.rawurldecode($templateRepo).'/generate', $parameters); } } From fe559892cf6f19980d058900c14b8a623c89ffe9 Mon Sep 17 00:00:00 2001 From: Quentin Ra <54904135+QuentinRa@users.noreply.github.com> Date: Sun, 3 Oct 2021 18:52:25 +0200 Subject: [PATCH 12/98] feature #1031 adding code_with_match (#1024) (QuentinRa) This PR was squashed before being merged into the 3.4.x-dev branch. Discussion ---------- Hi! As described in #1024, I added a function `code_with_match`. Commits ------- 32acac4549e8ee6d16bbb195a45fb885544347dd adding code_with_match (#1024) 179532a2f785787ddc0a52d0de9e513e41ff79f5 adding a new line c3be9515e3d81b0c3fc2f5f05a242cb9ed8ea7a3 changes requested f89811e2091f8a5716fb4a2f2c2af562a207e73c removing the whole phpdoc comment --- doc/search.md | 8 +++++- lib/Github/Api/Search.php | 15 ++++++++++ test/Github/Tests/Api/SearchTest.php | 43 ++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/doc/search.md b/doc/search.md index 0a674808001..24dbbef2302 100644 --- a/doc/search.md +++ b/doc/search.md @@ -13,13 +13,19 @@ $repos = $client->api('search')->repositories('github language:php'); Returns a list of repositories found by such criteria. ### Search code - + ```php $files = $client->api('search')->code('@todo language:php'); ``` Returns a list of files found by such criteria (containing "@todo" and language==php). +```php +$files = $client->api('search')->codeWithMatch('@todo language:php'); +``` + +Same as code, with additional data to highlight the matching fragments (see [Text match metadata](https://docs.github.com/en/rest/reference/search#text-match-metadata)). + ### Search issues ```php diff --git a/lib/Github/Api/Search.php b/lib/Github/Api/Search.php index 24bd59bbf83..96a51ea6a46 100644 --- a/lib/Github/Api/Search.php +++ b/lib/Github/Api/Search.php @@ -61,6 +61,21 @@ public function code($q, $sort = 'updated', $order = 'desc') return $this->get('/search/code', ['q' => $q, 'sort' => $sort, 'order' => $order]); } + /** + * Search code by filter (q), but will return additional data to highlight + * the matched results. + * + * @link https://docs.github.com/en/rest/reference/search#text-match-metadata + * + * @return array list of code found + */ + public function codeWithMatch(string $q, string $sort = 'updated', string $order = 'desc'): array + { + $this->acceptHeaderValue = 'application/vnd.github.v3.text-match+json'; + + return $this->code($q, $sort, $order); + } + /** * Search users by filter (q). * diff --git a/test/Github/Tests/Api/SearchTest.php b/test/Github/Tests/Api/SearchTest.php index a44c7b7499e..feecb7b5a74 100644 --- a/test/Github/Tests/Api/SearchTest.php +++ b/test/Github/Tests/Api/SearchTest.php @@ -133,6 +133,49 @@ public function shouldSearchCodeRegardingSortAndOrder() ); } + /** + * @test + */ + public function shouldSearchCodeWithMatchByQuery() + { + $expectedArray = [['total_count' => '0']]; + + $api = $this->getApiMock(); + + $api->expects($this->once()) + ->method('get') + ->with( + '/search/code', + ['q' => 'query text', 'sort' => 'updated', 'order' => 'desc'] + ) + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->codeWithMatch('query text')); + } + + /** + * @test + */ + public function shouldSearchCodeWithMatchRegardingSortAndOrder() + { + $expectedArray = [['total_count' => '0']]; + + $api = $this->getApiMock(); + + $api->expects($this->once()) + ->method('get') + ->with( + '/search/code', + ['q' => 'query text', 'sort' => 'created', 'order' => 'asc'] + ) + ->will($this->returnValue($expectedArray)); + + $this->assertEquals( + $expectedArray, + $api->codeWithMatch('query text', 'created', 'asc') + ); + } + /** * @test */ From f6123b0f04fbd779de095e9b23521891a53c46ae Mon Sep 17 00:00:00 2001 From: Alexandre PAVY Date: Sun, 3 Oct 2021 23:14:26 +0200 Subject: [PATCH 13/98] Added dir parameter for Repo readme --- lib/Github/Api/Repo.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/Github/Api/Repo.php b/lib/Github/Api/Repo.php index dfbd39b991a..750775a0458 100644 --- a/lib/Github/Api/Repo.php +++ b/lib/Github/Api/Repo.php @@ -257,13 +257,20 @@ public function remove($username, $repository) * @param string $username the user who owns the repository * @param string $repository the name of the repository * @param string $format one of formats: "raw", "html", or "v3+json" + * @param string $dir The alternate path to look for a README file * @param array $params additional query params like "ref" to fetch readme for branch/tag * * @return string|array the readme content */ - public function readme($username, $repository, $format = 'raw', $params = []) + public function readme($username, $repository, $format = 'raw', $dir = null, $params = []) { - return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/readme', $params, [ + $path = '/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/readme'; + + if (null !== $dir) { + $path .= '/'.rawurlencode($dir); + } + + return $this->get($path, $params, [ 'Accept' => "application/vnd.github.$format", ]); } From 87838df3c1d4c3cd2d6ddd09444ce49c5ca0039f Mon Sep 17 00:00:00 2001 From: Henrik Gemal Date: Mon, 25 Oct 2021 16:02:26 +0200 Subject: [PATCH 14/98] Fix incorrect phpdoc Fixes #1033 --- lib/Github/Api/Repo.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Github/Api/Repo.php b/lib/Github/Api/Repo.php index 750775a0458..5119d772b8e 100644 --- a/lib/Github/Api/Repo.php +++ b/lib/Github/Api/Repo.php @@ -626,7 +626,7 @@ public function subscribers($username, $repository, $page = 1) * @param string $head The head to merge. This can be a branch name or a commit SHA1. * @param string $message Commit message to use for the merge commit. If omitted, a default message will be used. * - * @return array|null + * @return array|string */ public function merge($username, $repository, $base, $head, $message = null) { From de2f27846139e7b4b92dcad9ff77660d0dc5dfad Mon Sep 17 00:00:00 2001 From: Paolo Rossi Date: Tue, 2 Nov 2021 07:51:42 +0100 Subject: [PATCH 15/98] feature #1036 refs #955: deprecate Client::AUTH_* constants and replace them with AuthMethod::AUTH_* const (ipalo) This PR was squashed before being merged into the 3.4.x-dev branch. Discussion ---------- Contribution for #955 Commits ------- 11c2d9f7ab51a5e1d1cf16817e092fe15c48a157 refs #955: deprecate Client::AUTH_* constants and replace them with AuthMethod::AUTH_* const f4774d0c897768256e28538f1883fa747551988b refs #955: revert the Client::AUTH_* deletion (BC) e7f1ab951ba8df11c013b7dd4bcedbb0924548d7 refs #955: fix CR issues c9cf54e65f7010821d224dfc96ada2a226ce9e81 refs #955: add upgrade to v4.0 notes ec6656c7209df6674852463c4250402e3d6e395a refs #955: set public all constants --- UPGRADE-4.0.md | 6 ++++ doc/currentuser/repositories.md | 6 ++-- doc/graphql.md | 6 ++-- doc/security.md | 18 +++++------ lib/Github/AuthMethod.php | 30 +++++++++++++++++++ lib/Github/Client.php | 14 ++++++--- .../HttpClient/Plugin/Authentication.php | 8 ++--- test/Github/Tests/ClientTest.php | 11 +++---- test/Github/Tests/Functional/CacheTest.php | 7 +++-- .../HttpClient/Plugin/AuthenticationTest.php | 8 ++--- 10 files changed, 79 insertions(+), 35 deletions(-) create mode 100644 lib/Github/AuthMethod.php diff --git a/UPGRADE-4.0.md b/UPGRADE-4.0.md index 9192a02a726..6ede78deb51 100644 --- a/UPGRADE-4.0.md +++ b/UPGRADE-4.0.md @@ -3,3 +3,9 @@ ### ResultPager * `\Github\ResultPagerInterface::postFetch` is deprecated, and the method will be removed from the ResultPager interface/class. + +### Authentication methods + +* `Github\Client::AUTH_CLIENT_ID` is deprecated, use `Github\AuthMethod::CLIENT_ID` instead. +* `Github\Client::AUTH_ACCESS_TOKEN` is deprecated, use `Github\AuthMethod::ACCESS_TOKEN` instead. +* `Github\Client::AUTH_JWT` is deprecated, use `Github\AuthMethod::JWT` instead. diff --git a/doc/currentuser/repositories.md b/doc/currentuser/repositories.md index a3e2922b20f..9b5e1d85e94 100644 --- a/doc/currentuser/repositories.md +++ b/doc/currentuser/repositories.md @@ -19,12 +19,12 @@ There are three values that can be passed into the `repositories` method: `type` | sort | `full_name` | `created`, `updated`, `pushed`, `full_name` | direction | `asc` | `asc`, `desc` -> See https://developer.github.com/v3/repos/#list-your-repositories for possible values and additional information +> See https://developer.github.com/v3/repos/#list-your-repositories for possible values and additional information #### Code Example: ```php -$client = new \Github\Client(); -$client->authenticate($github_token, null, \Github\Client::AUTH_ACCESS_TOKEN); +$client = new \Github\Client(); +$client->authenticate($github_token, null, \Github\AuthMethod::ACCESS_TOKEN); $client->currentUser()->repositories(); ``` diff --git a/doc/graphql.md b/doc/graphql.md index 99e653bf87a..83481868544 100644 --- a/doc/graphql.md +++ b/doc/graphql.md @@ -14,7 +14,7 @@ $rateLimits = $client->api('graphql')->execute($query); To use [GitHub v4 API (GraphQL API)](http://developer.github.com/v4/) requests must [authenticated]((../security.md)). ```php -$client->authenticate($token, null, Github\Client::AUTH_ACCESS_TOKEN); +$client->authenticate($token, null, Github\AuthMethod::ACCESS_TOKEN); $result = $client->api('graphql')->execute($query); ``` @@ -28,7 +28,7 @@ To use [GitHub v4 API (GraphQL API)](http://developer.github.com/v4/) with diffe ```php $result = $client->api('graphql')->execute($query, [], 'application/vnd.github.starfox-preview+json') ``` -> default accept header is `application/vnd.github.v4+json` +> default accept header is `application/vnd.github.v4+json` @@ -51,7 +51,7 @@ $variables = [ 'organizationLogin' => 'KnpLabs' ]; -$client->authenticate('', null, Github\Client::AUTH_ACCESS_TOKEN); +$client->authenticate('', null, Github\AuthMethod::ACCESS_TOKEN); $orgInfo = $client->api('graphql')->execute($query, $variables); ``` diff --git a/doc/security.md b/doc/security.md index b62ca4c05fc..7a79ee6674c 100644 --- a/doc/security.md +++ b/doc/security.md @@ -17,23 +17,23 @@ $client->authenticate($usernameOrToken, $password, $method); and guess what should contain `$password`. The `$method` can contain one of the three allowed values: #### Supported methods -* `Github\Client::AUTH_CLIENT_ID` - https://developer.github.com/v3/#oauth2-keysecret -* `Github\Client::AUTH_ACCESS_TOKEN` - https://developer.github.com/v3/#oauth2-token-sent-in-a-header -* `Github\Client::AUTH_JWT` - https://developer.github.com/apps/building-github-apps/authenticating-with-github-apps/#authenticating-as-a-github-app +* `Github\AuthMethod::CLIENT_ID` - https://developer.github.com/v3/#oauth2-keysecret +* `Github\AuthMethod::ACCESS_TOKEN` - https://developer.github.com/v3/#oauth2-token-sent-in-a-header +* `Github\AuthMethod::JWT` - https://developer.github.com/apps/building-github-apps/authenticating-with-github-apps/#authenticating-as-a-github-app -The required value of `$password` depends on the chosen `$method`. For `Github\Client::AUTH_ACCESS_TOKEN`, `Github\Client::AUTH_ACCESS_TOKEN` and -`Github\Client::JWT` methods you should provide the API token in `$usernameOrToken` variable (`$password` is omitted in +The required value of `$password` depends on the chosen `$method`. For `Github\AuthMethod::CLIENT_ID`, `Github\AuthMethod::ACCESS_TOKEN` and +`Github\AuthMethod::JWT` methods you should provide the API token in `$usernameOrToken` variable (`$password` is omitted in this particular case). -The `Github\Client::AUTH_JWT` authentication method sends the specified JSON Web Token in an Authorization header. +The `Github\AuthMethod::JWT` authentication method sends the specified JSON Web Token in an Authorization header. After executing the `$client->authenticate($usernameOrToken, $secret, $method);` method using correct credentials, all further requests are done as the given user. ### Authenticating as an Integration -To authenticate as an integration you need to supply a JSON Web Token with `Github\Client::AUTH_JWT` to request -and installation access token which is then usable with `Github\Client::AUTH_ACCESS_TOKEN`. [Github´s integration +To authenticate as an integration you need to supply a JSON Web Token with `Github\AuthMethod::JWT` to request +and installation access token which is then usable with `Github\AuthMethod::ACCESS_TOKEN`. [Github´s integration authentication docs](https://developer.github.com/apps/building-github-apps/authentication-options-for-github-apps/#authenticating-as-a-github-app) describe the flow in detail. It´s important for integration requests to use the custom Accept header `application/vnd.github.machine-man-preview`. @@ -64,7 +64,7 @@ $jwt = $config->builder(ChainedFormatter::withUnixTimestampDates()) ->getToken($config->signer(), $config->signingKey()) ; -$github->authenticate($jwt->toString(), null, Github\Client::AUTH_JWT) +$github->authenticate($jwt->toString(), null, Github\AuthMethod::JWT) ``` The `$integrationId` you can find in the about section of your github app. diff --git a/lib/Github/AuthMethod.php b/lib/Github/AuthMethod.php new file mode 100644 index 00000000000..4a390699a3c --- /dev/null +++ b/lib/Github/AuthMethod.php @@ -0,0 +1,30 @@ +method) { - case Client::AUTH_CLIENT_ID: + case AuthMethod::CLIENT_ID: return sprintf('Basic %s', base64_encode($this->tokenOrLogin.':'.$this->password)); - case Client::AUTH_ACCESS_TOKEN: + case AuthMethod::ACCESS_TOKEN: return sprintf('token %s', $this->tokenOrLogin); - case Client::AUTH_JWT: + case AuthMethod::JWT: return sprintf('Bearer %s', $this->tokenOrLogin); default: throw new RuntimeException(sprintf('%s not yet implemented', $this->method)); diff --git a/test/Github/Tests/ClientTest.php b/test/Github/Tests/ClientTest.php index d1eb5737acf..c4980b8edc5 100644 --- a/test/Github/Tests/ClientTest.php +++ b/test/Github/Tests/ClientTest.php @@ -3,6 +3,7 @@ namespace Github\Tests; use Github\Api; +use Github\AuthMethod; use Github\Client; use Github\Exception\BadMethodCallException; use Github\Exception\InvalidArgumentException; @@ -68,9 +69,9 @@ public function shouldAuthenticateUsingAllGivenParameters($login, $password, $me public function getAuthenticationFullData() { return [ - ['token', null, Client::AUTH_ACCESS_TOKEN], - ['client_id', 'client_secret', Client::AUTH_CLIENT_ID], - ['token', null, Client::AUTH_JWT], + ['token', null, AuthMethod::ACCESS_TOKEN], + ['client_id', 'client_secret', AuthMethod::CLIENT_ID], + ['token', null, AuthMethod::JWT], ]; } @@ -84,7 +85,7 @@ public function shouldAuthenticateUsingGivenParameters() ->getMock(); $builder->expects($this->once()) ->method('addPlugin') - ->with($this->equalTo(new Authentication('token', null, Client::AUTH_ACCESS_TOKEN))); + ->with($this->equalTo(new Authentication('token', null, AuthMethod::ACCESS_TOKEN))); $builder->expects($this->once()) ->method('removePlugin') @@ -98,7 +99,7 @@ public function shouldAuthenticateUsingGivenParameters() ->method('getHttpClientBuilder') ->willReturn($builder); - $client->authenticate('token', Client::AUTH_ACCESS_TOKEN); + $client->authenticate('token', AuthMethod::ACCESS_TOKEN); } /** diff --git a/test/Github/Tests/Functional/CacheTest.php b/test/Github/Tests/Functional/CacheTest.php index 58afe5f61f3..ec9be6b12e0 100644 --- a/test/Github/Tests/Functional/CacheTest.php +++ b/test/Github/Tests/Functional/CacheTest.php @@ -2,6 +2,7 @@ namespace Github\Tests\Functional; +use Github\AuthMethod; use Github\Client; use GuzzleHttp\Psr7\Response; use Symfony\Component\Cache\Adapter\ArrayAdapter; @@ -25,7 +26,7 @@ public function shouldServeCachedResponse() $github = Client::createWithHttpClient($mockClient); $github->addCache(new ArrayAdapter(), ['default_ttl'=>600]); - $github->authenticate('fake_token_aaa', Client::AUTH_ACCESS_TOKEN); + $github->authenticate('fake_token_aaa', AuthMethod::ACCESS_TOKEN); $userA = $github->currentUser()->show(); $this->assertEquals('nyholm', $userA['login']); @@ -45,11 +46,11 @@ public function shouldVaryOnAuthorization() $github = Client::createWithHttpClient($mockClient); $github->addCache(new ArrayAdapter(), ['default_ttl'=>600]); - $github->authenticate('fake_token_aaa', Client::AUTH_ACCESS_TOKEN); + $github->authenticate('fake_token_aaa', AuthMethod::ACCESS_TOKEN); $userA = $github->currentUser()->show(); $this->assertEquals('nyholm', $userA['login']); - $github->authenticate('fake_token_bbb', Client::AUTH_ACCESS_TOKEN); + $github->authenticate('fake_token_bbb', AuthMethod::ACCESS_TOKEN); $userB = $github->currentUser()->show(); $this->assertEquals('octocat', $userB['login'], 'We must vary on the Authorization header.'); } diff --git a/test/Github/Tests/HttpClient/Plugin/AuthenticationTest.php b/test/Github/Tests/HttpClient/Plugin/AuthenticationTest.php index e8c3d24a6a6..be937684d01 100644 --- a/test/Github/Tests/HttpClient/Plugin/AuthenticationTest.php +++ b/test/Github/Tests/HttpClient/Plugin/AuthenticationTest.php @@ -2,7 +2,7 @@ namespace Github\Tests\HttpClient\Plugin; -use Github\Client; +use Github\AuthMethod; use Github\HttpClient\Plugin\Authentication; use GuzzleHttp\Psr7\Request; use Http\Promise\FulfilledPromise; @@ -41,9 +41,9 @@ public function testAuthenticationMethods($tokenOrLogin, $password, $method, $ex public function getAuthenticationData() { return [ - ['access_token', null, Client::AUTH_ACCESS_TOKEN, 'token access_token'], - ['client_id', 'client_secret', Client::AUTH_CLIENT_ID, sprintf('Basic %s', base64_encode('client_id'.':'.'client_secret'))], - ['jwt_token', null, Client::AUTH_JWT, 'Bearer jwt_token'], + ['access_token', null, AuthMethod::ACCESS_TOKEN, 'token access_token'], + ['client_id', 'client_secret', AuthMethod::CLIENT_ID, sprintf('Basic %s', base64_encode('client_id'.':'.'client_secret'))], + ['jwt_token', null, AuthMethod::JWT, 'Bearer jwt_token'], ]; } } From a78ae66aca391f8ccb41254c617afc49b6ca67b9 Mon Sep 17 00:00:00 2001 From: Michael Gerdemann Date: Fri, 19 Nov 2021 08:13:44 +0100 Subject: [PATCH 16/98] feat: Add `visibility` option to repo create --- lib/Github/Api/Repo.php | 6 ++-- test/Github/Tests/Api/RepoTest.php | 48 ++++++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/lib/Github/Api/Repo.php b/lib/Github/Api/Repo.php index 5119d772b8e..4d8c012ff3e 100644 --- a/lib/Github/Api/Repo.php +++ b/lib/Github/Api/Repo.php @@ -181,6 +181,7 @@ public function showById($id) * @param int $teamId The id of the team that will be granted access to this repository. This is only valid when creating a repo in an organization. * @param bool $autoInit `true` to create an initial commit with empty README, `false` for no initial commit * @param bool $hasProjects `true` to enable projects for this repository or false to disable them. + * @param string|null $visibility * * @return array returns repository data */ @@ -195,7 +196,8 @@ public function create( $hasDownloads = false, $teamId = null, $autoInit = false, - $hasProjects = true + $hasProjects = true, + $visibility = null ) { $path = null !== $organization ? '/orgs/'.$organization.'/repos' : '/user/repos'; @@ -203,7 +205,7 @@ public function create( 'name' => $name, 'description' => $description, 'homepage' => $homepage, - 'private' => !$public, + 'visibility' => $visibility ?? ($public ? 'public' : 'private'), 'has_issues' => $hasIssues, 'has_wiki' => $hasWiki, 'has_downloads' => $hasDownloads, diff --git a/test/Github/Tests/Api/RepoTest.php b/test/Github/Tests/Api/RepoTest.php index 3761b2efb7e..a934bc6b906 100644 --- a/test/Github/Tests/Api/RepoTest.php +++ b/test/Github/Tests/Api/RepoTest.php @@ -95,7 +95,7 @@ public function shouldCreateRepositoryUsingNameOnly() 'name' => 'l3l0Repo', 'description' => '', 'homepage' => '', - 'private' => false, + 'visibility' => 'public', 'has_issues' => false, 'has_wiki' => false, 'has_downloads' => false, @@ -121,7 +121,7 @@ public function shouldCreateRepositoryForOrganization() 'name' => 'KnpLabsRepo', 'description' => '', 'homepage' => '', - 'private' => false, + 'visibility' => 'public', 'has_issues' => false, 'has_wiki' => false, 'has_downloads' => false, @@ -133,6 +133,48 @@ public function shouldCreateRepositoryForOrganization() $this->assertEquals($expectedArray, $api->create('KnpLabsRepo', '', '', true, 'KnpLabs')); } + /** + * @test + */ + public function shouldCreateRepositoryWithInternalVisibility() + { + $expectedArray = ['id' => 1, 'name' => 'KnpLabsRepo']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('/user/repos', [ + 'name' => 'KnpLabsRepo', + 'description' => '', + 'homepage' => '', + 'has_issues' => false, + 'has_wiki' => false, + 'has_downloads' => false, + 'auto_init' => false, + 'has_projects' => true, + 'visibility' => 'internal', + ]) + ->will($this->returnValue($expectedArray)); + + $this->assertEquals( + $expectedArray, + $api->create( + 'KnpLabsRepo', + '', + '', + false, + null, + false, + false, + false, + null, + false, + true, + 'internal' + ) + ); + } + /** * @test */ @@ -329,7 +371,7 @@ public function shouldCreateUsingAllParams() 'name' => 'l3l0Repo', 'description' => 'test', 'homepage' => 'http://l3l0.eu', - 'private' => true, + 'visibility' => 'private', 'has_issues' => false, 'has_wiki' => false, 'has_downloads' => false, From 65081387852031579d8006c5fec7119291b84e61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20K=C3=B3nya?= <40911283+kdaniel95@users.noreply.github.com> Date: Fri, 3 Dec 2021 11:06:31 +0100 Subject: [PATCH 17/98] feature #1041 Feature get authenticated app (kdaniel95) This PR was squashed before being merged into the 3.4.x-dev branch. Discussion ---------- https://docs.github.com/en/rest/reference/apps#get-the-authenticated-app Create endpoint to get authenticated app. Commits ------- 090a967592728b9c3551780fadf8d985373c677c Feat: Get authenticated app ce3d0fd95f1df8e9534d8365631b41cbbc83f0b8 Fix endpoint doc d666ddb76688d1a3609c7a4c88befe49e21c2198 Fix StyleCI issues bb14d054d888e54776fe533692436309cea31b43 Merge remote-tracking branch 'origin/feature-get-authenticated-app' into feature-get-authenticated-app --- doc/apps.md | 6 ++++++ lib/Github/Api/Apps.php | 12 ++++++++++++ test/Github/Tests/Api/AppTest.php | 17 +++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/doc/apps.md b/doc/apps.md index f7a61328092..14de9e4434d 100644 --- a/doc/apps.md +++ b/doc/apps.md @@ -49,3 +49,9 @@ $client->api('apps')->addRepository($installationId, $repositoryId); ```php $client->api('apps')->removeRepository($installationId, $repositoryId); ``` + +### Get authenticated app + +```php +$authenticatedApp = $client->api('apps')->getAuthenticatedApp(); +``` diff --git a/lib/Github/Api/Apps.php b/lib/Github/Api/Apps.php index bb2a2c463f9..9e9a4b6a741 100644 --- a/lib/Github/Api/Apps.php +++ b/lib/Github/Api/Apps.php @@ -186,4 +186,16 @@ public function removeRepository($installationId, $repositoryId) return $this->delete('/installations/'.$installationId.'/repositories/'.$repositoryId); } + + /** + * Get the currently authenticated app. + * + * @link https://docs.github.com/en/rest/reference/apps#get-the-authenticated-app + * + * @return array + */ + public function getAuthenticatedApp() + { + return $this->get('/app'); + } } diff --git a/test/Github/Tests/Api/AppTest.php b/test/Github/Tests/Api/AppTest.php index e5d5fcf57b4..28fa447b9a2 100644 --- a/test/Github/Tests/Api/AppTest.php +++ b/test/Github/Tests/Api/AppTest.php @@ -160,6 +160,23 @@ public function shouldRemoveRepositoryToInstallation() $api->removeRepository('1234', '5678'); } + /** + * @test + */ + public function shouldGetAuthenticatedApp() + { + $api = $this->getApiMock(); + + $result = ['authenticatedApp1']; + + $api->expects($this->once()) + ->method('get') + ->with('/app') + ->willReturn($result); + + $this->assertEquals($result, $api->getAuthenticatedApp()); + } + /** * @return string */ From bddf0f5e686a2dc72ca0ec642e3b487b08d841ce Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Wed, 8 Dec 2021 08:25:22 +0100 Subject: [PATCH 18/98] Update changelog for 3.4.0 release --- CHANGELOG-3.X.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/CHANGELOG-3.X.md b/CHANGELOG-3.X.md index 25db0b810ab..3a0963c16dc 100644 --- a/CHANGELOG-3.X.md +++ b/CHANGELOG-3.X.md @@ -1,5 +1,30 @@ # Changelog +## 3.4.0 + +### Added +- Add create a repository using a template endpoint ([martinbean](https://github.com/martinbean)) [#994](https://github.com/KnpLabs/php-github-api/issues/994) +- Allow fetching repo readme for a specific ref ([bery](https://github.com/bery)) [#1019](https://github.com/KnpLabs/php-github-api/issues/1019) +- allow assigning role to organisation members ([luceos](https://github.com/luceos)) [#1018](https://github.com/KnpLabs/php-github-api/issues/1018) +- Branch lists . ( ? query per_page) ([pitonic](https://github.com/pitonic)) [#1020](https://github.com/KnpLabs/php-github-api/issues/1020) +- Php8.1 support ([acrobat](https://github.com/acrobat)) [#1025](https://github.com/KnpLabs/php-github-api/issues/1025) +- Allow psr/cache 2.0 as well as 1.0 ([johnnoel](https://github.com/johnnoel)) [#1029](https://github.com/KnpLabs/php-github-api/issues/1029) +- adding code_with_match (#1024) ([QuentinRa](https://github.com/QuentinRa)) [#1031](https://github.com/KnpLabs/php-github-api/issues/1031) +- Added dir parameter for Repo readme ([AlexandrePavy](https://github.com/AlexandrePavy)) [#1032](https://github.com/KnpLabs/php-github-api/issues/1032) +- refs #955: deprecate Client::AUTH_* constants and replace them with AuthMethod::AUTH_* const ([ipalo](https://github.com/ipalo)) [#1036](https://github.com/KnpLabs/php-github-api/issues/1036) +- feat: Add `visibility` option to repo create ([gerdemann](https://github.com/gerdemann)) [#1038](https://github.com/KnpLabs/php-github-api/issues/1038) +- Feature get authenticated app ([kdaniel95](https://github.com/kdaniel95)) [#1041](https://github.com/KnpLabs/php-github-api/issues/1041) + +### Changed +- Fix up typos ([dereuromark](https://github.com/dereuromark)) [#1011](https://github.com/KnpLabs/php-github-api/issues/1011) +- Update integration authentication documentation for usage with lcobucci/jwt ^4 ([glaubinix](https://github.com/glaubinix)) [#1017](https://github.com/KnpLabs/php-github-api/issues/1017) +- Update result_pager.md ([tomsowerby](https://github.com/tomsowerby)) [#1023](https://github.com/KnpLabs/php-github-api/issues/1023) +- fix(doc): links to doc in CurrentUser class ([Nek-](https://github.com/Nek-)) [#1026](https://github.com/KnpLabs/php-github-api/issues/1026) +- Fix incorrect phpdoc ([gemal](https://github.com/gemal)) [#1034](https://github.com/KnpLabs/php-github-api/issues/1034) + +### Fixed +- Add accept header for creating repo from template ([davidpeach](https://github.com/davidpeach)) [#1030](https://github.com/KnpLabs/php-github-api/issues/1030) + ## 3.3.0 ### Added From ce386210cb0cb5adc32a5fa5f11a6d413bf5b2e5 Mon Sep 17 00:00:00 2001 From: Jonas Staudenmeir Date: Fri, 31 Dec 2021 08:31:14 +0100 Subject: [PATCH 19/98] Fix internal doc link --- doc/graphql.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/graphql.md b/doc/graphql.md index 83481868544..e9ba581c506 100644 --- a/doc/graphql.md +++ b/doc/graphql.md @@ -11,7 +11,7 @@ $rateLimits = $client->api('graphql')->execute($query); #### Authentication -To use [GitHub v4 API (GraphQL API)](http://developer.github.com/v4/) requests must [authenticated]((../security.md)). +To use [GitHub v4 API (GraphQL API)](http://developer.github.com/v4/) requests must [authenticated](security.md). ```php $client->authenticate($token, null, Github\AuthMethod::ACCESS_TOKEN); From 59ed2862aa304ea225645d08f31a7f0427e0a28d Mon Sep 17 00:00:00 2001 From: Stephen Stack Date: Tue, 18 Jan 2022 12:17:53 +0000 Subject: [PATCH 20/98] added support for psr\cache 3.0 - OK (704 tests, 1245 assertions) --- composer.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 71924b18e59..16533bc38f7 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "php-http/discovery": "^1.12", "php-http/httplug": "^2.2", "php-http/multipart-stream-builder": "^1.1.2", - "psr/cache": "^1.0|^2.0", + "psr/cache": "^1.0|^2.0|^3.0", "psr/http-client-implementation": "^1.0", "psr/http-factory-implementation": "^1.0", "psr/http-message": "^1.0", @@ -54,5 +54,10 @@ "dev-2.x": "2.20.x-dev", "dev-master": "3.4.x-dev" } + }, + "config": { + "allow-plugins": { + "phpstan/extension-installer": true + } } } From 52280d9321b58082b51bcb5b389bf7af85383efb Mon Sep 17 00:00:00 2001 From: Stephan Vock Date: Thu, 20 Jan 2022 16:12:00 +0000 Subject: [PATCH 21/98] Symfony: allow deprecation-contracts version 3 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 16533bc38f7..b54537bd1f5 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,7 @@ "psr/http-factory-implementation": "^1.0", "psr/http-message": "^1.0", "symfony/polyfill-php80": "^1.17", - "symfony/deprecation-contracts": "^2.2" + "symfony/deprecation-contracts": "^2.2|^3.0" }, "require-dev": { "symfony/cache": "^5.1.8", From b56a3feba87215253d0b0db27259a701068bdfe8 Mon Sep 17 00:00:00 2001 From: Asher Goldberg <43661200+asher-goldberg@users.noreply.github.com> Date: Sun, 23 Jan 2022 06:31:58 -0500 Subject: [PATCH 22/98] bug #1048 Fix Client URL Prepending For GraphQL Endpoint on Enterprise (asher-goldberg, acrobat) This PR was squashed before being merged into the 3.4.x-dev branch. Discussion ---------- fixes #1047 This checks if `v4` is passed into the Client and an Enterprise URL is set then the prepend will only be `/api`. (The class default is `v3` if no version is provided so can't just pass an empty string). TL;DR - this now allows this package to run GraphQL calls on Enterprise `$client = new Client(null, 'v4', 'https://enterpriseurl');` Commits ------- 0d989bbcff6a63e9f24784c3c0215263666245b0 Fix prepend on Enteprrise for V4 a44fa2b8d067f68518796bbbc76fc5ba3d828d04 Allow codestyle fix --- lib/Github/Client.php | 9 ++++++++- test/Github/Tests/ClientTest.php | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/Github/Client.php b/lib/Github/Client.php index 4a61af84bae..ecd4aec7904 100644 --- a/lib/Github/Client.php +++ b/lib/Github/Client.php @@ -346,7 +346,14 @@ private function setEnterpriseUrl($enterpriseUrl): void $builder->removePlugin(PathPrepend::class); $builder->addPlugin(new Plugin\AddHostPlugin(Psr17FactoryDiscovery::findUriFactory()->createUri($enterpriseUrl))); - $builder->addPlugin(new PathPrepend(sprintf('/api/%s', $this->getApiVersion()))); + + // For GHE, v4 API endpoint is at `api/graphql` so we don't want to add the version number + // For earlier versions add the version number after /api + if ($this->getApiVersion() === 'v4') { + $builder->addPlugin(new PathPrepend('/api')); + } else { + $builder->addPlugin(new PathPrepend(sprintf('/api/%s', $this->getApiVersion()))); + } } /** diff --git a/test/Github/Tests/ClientTest.php b/test/Github/Tests/ClientTest.php index c4980b8edc5..74255c9a9f3 100644 --- a/test/Github/Tests/ClientTest.php +++ b/test/Github/Tests/ClientTest.php @@ -223,4 +223,25 @@ public function testEnterpriseUrl() $client = new Client($httpClientBuilder, null, 'https://foobar.com'); $client->enterprise()->stats()->show('all'); } + + /** + * Make sure that the prepend is correct when using the v4 endpoint on Enterprise. + */ + public function testEnterprisePrependGraphQLV4() + { + $httpClientMock = $this->getMockBuilder(ClientInterface::class) + ->setMethods(['sendRequest']) + ->getMock(); + + $httpClientMock->expects($this->once()) + ->method('sendRequest') + ->with($this->callback(function (RequestInterface $request) { + return (string) $request->getUri() === 'https://foobar.com/api/graphql'; + })) + ->willReturn(new Response(200, [], '[]')); + + $httpClientBuilder = new Builder($httpClientMock); + $client = new Client($httpClientBuilder, 'v4', 'https://foobar.com'); + $client->graphql()->execute('query'); + } } From 9906308d0c0e0b551e5fd461e026592de66fe311 Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Sun, 23 Jan 2022 12:32:47 +0100 Subject: [PATCH 23/98] Update changelog for 3.5.0 release --- CHANGELOG-3.X.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG-3.X.md b/CHANGELOG-3.X.md index 3a0963c16dc..30dcb73d2ec 100644 --- a/CHANGELOG-3.X.md +++ b/CHANGELOG-3.X.md @@ -1,5 +1,17 @@ # Changelog +## 3.5.0 + +### Added +- added support for psr\cache 3.0 ([rconfig](https://github.com/rconfig)) [#1046](https://github.com/KnpLabs/php-github-api/issues/1046) +- Symfony: allow deprecation-contracts version 3 ([glaubinix](https://github.com/glaubinix)) [#1049](https://github.com/KnpLabs/php-github-api/issues/1049) + +### Changed +- Fix internal doc link ([staudenmeir](https://github.com/staudenmeir)) [#1044](https://github.com/KnpLabs/php-github-api/issues/1044) + +### Fixed +- Fix Client URL Prepending For GraphQL Endpoint on Enterprise ([asher-goldberg](https://github.com/asher-goldberg), [acrobat](https://github.com/acrobat)) [#1048](https://github.com/KnpLabs/php-github-api/issues/1048) + ## 3.4.0 ### Added From ed63fb6b5ba2936614c985b80515603d990fa42a Mon Sep 17 00:00:00 2001 From: Vit Horacek <36083550+mountiny@users.noreply.github.com> Date: Sat, 12 Feb 2022 21:09:16 +0000 Subject: [PATCH 24/98] Include optional params parameter for Commits compare With the current API, we cannot paginate compare basehead function call. The Github API limits the response to only 250 commits so for larger diffs we have no option. --- lib/Github/Api/Repository/Commits.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Github/Api/Repository/Commits.php b/lib/Github/Api/Repository/Commits.php index 8195e4baf0f..383905d28f2 100644 --- a/lib/Github/Api/Repository/Commits.php +++ b/lib/Github/Api/Repository/Commits.php @@ -16,14 +16,14 @@ public function all($username, $repository, array $params) return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/commits', $params); } - public function compare($username, $repository, $base, $head, $mediaType = null) + public function compare($username, $repository, $base, $head, $mediaType = null, array $params = []) { $headers = []; if (null !== $mediaType) { $headers['Accept'] = $mediaType; } - return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/compare/'.rawurlencode($base).'...'.rawurlencode($head), [], $headers); + return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/compare/'.rawurlencode($base).'...'.rawurlencode($head), $params, $headers); } public function show($username, $repository, $sha) From 4916a9401a27618673a26bf3c713d9d8da28ff2d Mon Sep 17 00:00:00 2001 From: mruell <46520365+mruell@users.noreply.github.com> Date: Fri, 18 Feb 2022 19:29:41 +0100 Subject: [PATCH 25/98] bug #1051 Boolean private needed to create private repo! (mruell) This PR was squashed before being merged into the 3.4.x-dev branch. Discussion ---------- Apparently there was an GitHub API change. When private is not set to `true` the visibility `private` is ignored Commits ------- bc93867eed5815ab9567f8e01f240a3b3f6b7b47 Boolean private needed to create private repo as seen in: https://docs.github.com/en/rest/reference/repos#create-an-organization-repository a1f96868c572d01a99eeca93d21b56a24b90f09d Fix tests --- lib/Github/Api/Repo.php | 1 + test/Github/Tests/Api/RepoTest.php | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/lib/Github/Api/Repo.php b/lib/Github/Api/Repo.php index 4d8c012ff3e..12fe726b450 100644 --- a/lib/Github/Api/Repo.php +++ b/lib/Github/Api/Repo.php @@ -205,6 +205,7 @@ public function create( 'name' => $name, 'description' => $description, 'homepage' => $homepage, + 'private' => ($visibility ?? ($public ? 'public' : 'private')) === 'private', 'visibility' => $visibility ?? ($public ? 'public' : 'private'), 'has_issues' => $hasIssues, 'has_wiki' => $hasWiki, diff --git a/test/Github/Tests/Api/RepoTest.php b/test/Github/Tests/Api/RepoTest.php index a934bc6b906..7ba181dd53f 100644 --- a/test/Github/Tests/Api/RepoTest.php +++ b/test/Github/Tests/Api/RepoTest.php @@ -96,6 +96,7 @@ public function shouldCreateRepositoryUsingNameOnly() 'description' => '', 'homepage' => '', 'visibility' => 'public', + 'private' => false, 'has_issues' => false, 'has_wiki' => false, 'has_downloads' => false, @@ -122,6 +123,7 @@ public function shouldCreateRepositoryForOrganization() 'description' => '', 'homepage' => '', 'visibility' => 'public', + 'private' => false, 'has_issues' => false, 'has_wiki' => false, 'has_downloads' => false, @@ -153,6 +155,7 @@ public function shouldCreateRepositoryWithInternalVisibility() 'auto_init' => false, 'has_projects' => true, 'visibility' => 'internal', + 'private' => false, ]) ->will($this->returnValue($expectedArray)); @@ -372,6 +375,7 @@ public function shouldCreateUsingAllParams() 'description' => 'test', 'homepage' => 'http://l3l0.eu', 'visibility' => 'private', + 'private' => true, 'has_issues' => false, 'has_wiki' => false, 'has_downloads' => false, From 37b167998e8e1f318b3d99633675cfa007540565 Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Sat, 19 Feb 2022 12:15:46 +0100 Subject: [PATCH 26/98] Update changelog for 3.5.1 release --- CHANGELOG-3.X.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG-3.X.md b/CHANGELOG-3.X.md index 30dcb73d2ec..8155111b104 100644 --- a/CHANGELOG-3.X.md +++ b/CHANGELOG-3.X.md @@ -1,5 +1,10 @@ # Changelog +## 3.5.1 + +### Fixed +- Boolean private needed to create private repo! ([mruell](https://github.com/mruell)) [#1051](https://github.com/KnpLabs/php-github-api/issues/1051) + ## 3.5.0 ### Added From 4d53365668c5633a12e0c86a1644462e94d24451 Mon Sep 17 00:00:00 2001 From: Andrew Ellis Date: Tue, 1 Mar 2022 15:41:06 -0700 Subject: [PATCH 27/98] fix(Apps): use /orgs/ORG/installation Signed-off-by: Andrew Ellis --- lib/Github/Api/Apps.php | 2 +- test/Github/Tests/Api/AppTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Github/Api/Apps.php b/lib/Github/Api/Apps.php index 9e9a4b6a741..62df3a3cf82 100644 --- a/lib/Github/Api/Apps.php +++ b/lib/Github/Api/Apps.php @@ -82,7 +82,7 @@ public function getInstallationForOrganization($org) { $this->configurePreviewHeader(); - return $this->get('/org/'.rawurldecode($org).'/installation'); + return $this->get('/orgs/'.rawurldecode($org).'/installation'); } /** diff --git a/test/Github/Tests/Api/AppTest.php b/test/Github/Tests/Api/AppTest.php index 28fa447b9a2..b813a11dd1f 100644 --- a/test/Github/Tests/Api/AppTest.php +++ b/test/Github/Tests/Api/AppTest.php @@ -66,7 +66,7 @@ public function shouldGetInstallationForOrganization() $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('/org/1234/installation') + ->with('/orgs/1234/installation') ->willReturn($result); $this->assertEquals($result, $api->getInstallationForOrganization('1234')); From 38146135651a9ed8c98778648849894799e842e4 Mon Sep 17 00:00:00 2001 From: Rafik Abdulwahab <97947131+pheeque1@users.noreply.github.com> Date: Wed, 23 Mar 2022 15:47:15 +0100 Subject: [PATCH 28/98] Update incorrect documentation The `find` method is no longer used and has been removed in the latest version. --- doc/users.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/doc/users.md b/doc/users.md index 5bac98a7d16..dbc6a6bb302 100644 --- a/doc/users.md +++ b/doc/users.md @@ -6,11 +6,7 @@ Wrap [GitHub User API](http://developer.github.com/v3/users/). ### Search for users by keyword -```php -$users = $client->api('user')->find('KnpLabs'); -``` - -Returns an array of found users. +Use the [Search API](https://github.com/KnpLabs/php-github-api/blob/master/doc/search.md#search-users) to find users by keyword. ### Lists all users, in the order they signed up, since the last user you've seen From 5629ba3846298a48199061d1e0acd8f6c840e3c5 Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Thu, 24 Mar 2022 09:57:22 +0100 Subject: [PATCH 29/98] Fix ResponseMediator test after update in guzzle/psr-7 --- composer.json | 3 ++- .../HttpClient/Message/ResponseMediatorTest.php | 15 +++++---------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/composer.json b/composer.json index b54537bd1f5..ce6d0072118 100644 --- a/composer.json +++ b/composer.json @@ -57,7 +57,8 @@ }, "config": { "allow-plugins": { - "phpstan/extension-installer": true + "phpstan/extension-installer": true, + "composer/package-versions-deprecated": true } } } diff --git a/test/Github/Tests/HttpClient/Message/ResponseMediatorTest.php b/test/Github/Tests/HttpClient/Message/ResponseMediatorTest.php index c14eac8a297..8c1bfd29243 100644 --- a/test/Github/Tests/HttpClient/Message/ResponseMediatorTest.php +++ b/test/Github/Tests/HttpClient/Message/ResponseMediatorTest.php @@ -54,18 +54,13 @@ public function testGetContentInvalidJson() public function testGetPagination() { - $header = <<<'TEXT' -; rel="first", -; rel="next", -; rel="prev", -; rel="last", -TEXT; + $header = '; rel="first",; rel="next",; rel="prev",; rel="last",'; $pagination = [ - 'first' => 'http://github.com', - 'next' => 'http://github.com', - 'prev' => 'http://github.com', - 'last' => 'http://github.com', + 'first' => 'https://github.com', + 'next' => 'https://github.com', + 'prev' => 'https://github.com', + 'last' => 'https://github.com', ]; // response mock From 7f283177b96eb626e5cf6038d8771859a0af4b02 Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Thu, 24 Mar 2022 10:08:32 +0100 Subject: [PATCH 30/98] Update changelog for 3.6.0 release --- CHANGELOG-3.X.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG-3.X.md b/CHANGELOG-3.X.md index 8155111b104..b8516f0b6a8 100644 --- a/CHANGELOG-3.X.md +++ b/CHANGELOG-3.X.md @@ -1,5 +1,16 @@ # Changelog +## 3.6.0 + +### Added +- Include optional params parameter for Commits compare method ([mountiny](https://github.com/mountiny)) [#1053](https://github.com/KnpLabs/php-github-api/issues/1053) + +### Changed +- Update incorrect documentation ([pheeque1](https://github.com/pheeque1)) [#1058](https://github.com/KnpLabs/php-github-api/issues/1058) + +### Fixed +- fix(Apps): use /orgs/ORG/installation ([ellisio](https://github.com/ellisio)) [#1056](https://github.com/KnpLabs/php-github-api/issues/1056) + ## 3.5.1 ### Fixed From 8ab22f61666477b9f67066be44af14ac64ad4fe3 Mon Sep 17 00:00:00 2001 From: Elliot Date: Wed, 6 Apr 2022 09:20:33 +0100 Subject: [PATCH 31/98] Updates ReviewRequest Create with type Array As per docs this query returns an array. Specific docs link added in docblock too. --- lib/Github/Api/PullRequest/ReviewRequest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Github/Api/PullRequest/ReviewRequest.php b/lib/Github/Api/PullRequest/ReviewRequest.php index d95913ccde3..7d77f3e5fd6 100644 --- a/lib/Github/Api/PullRequest/ReviewRequest.php +++ b/lib/Github/Api/PullRequest/ReviewRequest.php @@ -39,7 +39,7 @@ public function all($username, $repository, $pullRequest, array $params = []) } /** - * @link https://developer.github.com/v3/pulls/review_requests/#create-a-review-request + * @link https://docs.github.com/en/rest/reference/pulls#request-reviewers-for-a-pull-request * * @param string $username * @param string $repository @@ -47,7 +47,7 @@ public function all($username, $repository, $pullRequest, array $params = []) * @param array $reviewers * @param array $teamReviewers * - * @return string + * @return array */ public function create($username, $repository, $pullRequest, array $reviewers = [], array $teamReviewers = []) { From 40ba3e7c9df728b1e2d8f5577190d1022a7f2d48 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 2 Jun 2022 18:43:02 +0200 Subject: [PATCH 32/98] added phpdocs --- lib/Github/Api/PullRequest.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/Github/Api/PullRequest.php b/lib/Github/Api/PullRequest.php index ce1c2b1d901..22922c1ee92 100644 --- a/lib/Github/Api/PullRequest.php +++ b/lib/Github/Api/PullRequest.php @@ -108,16 +108,25 @@ public function status($username, $repository, $id) return $this->get($link); } + /** + * @return Comments + */ public function comments() { return new Comments($this->getClient()); } + /** + * @return Review + */ public function reviews() { return new Review($this->getClient()); } + /** + * @return ReviewRequest + */ public function reviewRequests() { return new ReviewRequest($this->getClient()); From c67780893b0cb14222e845b08bfe0c1b0cc68125 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 2 Jun 2022 18:45:53 +0200 Subject: [PATCH 33/98] added missing magic method phpdocs for deployments --- lib/Github/Client.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/Github/Client.php b/lib/Github/Client.php index ecd4aec7904..56d68d59cec 100644 --- a/lib/Github/Client.php +++ b/lib/Github/Client.php @@ -62,6 +62,8 @@ * @method Api\Authorizations authorizations() * @method Api\Meta meta() * @method Api\GraphQL graphql() + * @method Api\Deployment deployment() + * @method Api\Deployment deployments() * * @author Joseph Bielawski * From 3cdd4be64f6f649b4c99e79790dd00dfc8a8057d Mon Sep 17 00:00:00 2001 From: mruell <46520365+mruell@users.noreply.github.com> Date: Sun, 12 Jun 2022 19:37:04 +0200 Subject: [PATCH 34/98] feature #1062 Fix issue https://github.com/KnpLabs/php-github-api/issues/1061 (mruell) This PR was squashed before being merged into the 3.4.x-dev branch. Discussion ---------- Commits ------- bc93867eed5815ab9567f8e01f240a3b3f6b7b47 Boolean private needed to create private repo as seen in: https://docs.github.com/en/rest/reference/repos#create-an-organization-repository a1f96868c572d01a99eeca93d21b56a24b90f09d Fix tests 74a46eeb9002dcd2b3a340ef5004b179b3bc9fdb Merge branch 'KnpLabs:master' into master 11d92e73ab2d63e54410640fbf0d6cdbe292dcf5 Fix issue d2780b50b0169c540ad5edee1b2c60a9831a01a9 Fix tests --- lib/Github/Api/Repo.php | 5 ++++- test/Github/Tests/Api/RepoTest.php | 3 --- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Github/Api/Repo.php b/lib/Github/Api/Repo.php index 12fe726b450..5760a587bed 100644 --- a/lib/Github/Api/Repo.php +++ b/lib/Github/Api/Repo.php @@ -206,7 +206,6 @@ public function create( 'description' => $description, 'homepage' => $homepage, 'private' => ($visibility ?? ($public ? 'public' : 'private')) === 'private', - 'visibility' => $visibility ?? ($public ? 'public' : 'private'), 'has_issues' => $hasIssues, 'has_wiki' => $hasWiki, 'has_downloads' => $hasDownloads, @@ -214,6 +213,10 @@ public function create( 'has_projects' => $hasProjects, ]; + if ($visibility) { + $parameters['visibility'] = $visibility; + } + if ($organization && $teamId) { $parameters['team_id'] = $teamId; } diff --git a/test/Github/Tests/Api/RepoTest.php b/test/Github/Tests/Api/RepoTest.php index 7ba181dd53f..9cfa7f84a88 100644 --- a/test/Github/Tests/Api/RepoTest.php +++ b/test/Github/Tests/Api/RepoTest.php @@ -95,7 +95,6 @@ public function shouldCreateRepositoryUsingNameOnly() 'name' => 'l3l0Repo', 'description' => '', 'homepage' => '', - 'visibility' => 'public', 'private' => false, 'has_issues' => false, 'has_wiki' => false, @@ -122,7 +121,6 @@ public function shouldCreateRepositoryForOrganization() 'name' => 'KnpLabsRepo', 'description' => '', 'homepage' => '', - 'visibility' => 'public', 'private' => false, 'has_issues' => false, 'has_wiki' => false, @@ -374,7 +372,6 @@ public function shouldCreateUsingAllParams() 'name' => 'l3l0Repo', 'description' => 'test', 'homepage' => 'http://l3l0.eu', - 'visibility' => 'private', 'private' => true, 'has_issues' => false, 'has_wiki' => false, From c230ab0162afeaec4318276e6a470af4b52da5fe Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Sun, 12 Jun 2022 19:59:07 +0200 Subject: [PATCH 35/98] Update changelog for 3.7.0 release --- CHANGELOG-3.X.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG-3.X.md b/CHANGELOG-3.X.md index b8516f0b6a8..6e413c1c5f7 100644 --- a/CHANGELOG-3.X.md +++ b/CHANGELOG-3.X.md @@ -1,5 +1,15 @@ # Changelog +## 3.7.0 + +### Added +- added phpdocs ([staabm](https://github.com/staabm)) [#1068](https://github.com/KnpLabs/php-github-api/issues/1068) +- added missing magic method phpdocs for deployments ([staabm](https://github.com/staabm)) [#1069](https://github.com/KnpLabs/php-github-api/issues/1069) +- Fix issue https://github.com/KnpLabs/php-github-api/issues/1061 ([mruell](https://github.com/mruell)) [#1062](https://github.com/KnpLabs/php-github-api/issues/1062) + +### Changed +- Updates ReviewRequest Create method to return type Array ([ejntaylor](https://github.com/ejntaylor)) [#1060](https://github.com/KnpLabs/php-github-api/issues/1060) + ## 3.6.0 ### Added From 55e881aa02e04453f27d2344d9ccbf1de6af3164 Mon Sep 17 00:00:00 2001 From: Matthew Nessworthy Date: Mon, 13 Jun 2022 12:52:57 +0200 Subject: [PATCH 36/98] API rate limit error status can be 403 --- .../Plugin/GithubExceptionThrower.php | 15 ++++++++ .../Plugin/GithubExceptionThrowerTest.php | 34 +++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/lib/Github/HttpClient/Plugin/GithubExceptionThrower.php b/lib/Github/HttpClient/Plugin/GithubExceptionThrower.php index 4603f629881..78628c6740f 100644 --- a/lib/Github/HttpClient/Plugin/GithubExceptionThrower.php +++ b/lib/Github/HttpClient/Plugin/GithubExceptionThrower.php @@ -120,6 +120,21 @@ public function handleRequest(RequestInterface $request, callable $next, callabl throw new SsoRequiredException($url); } + $remaining = ResponseMediator::getHeader($response, 'X-RateLimit-Remaining'); + if ((403 === $response->getStatusCode()) && null !== $remaining && 1 > $remaining && isset($content['message']) && (0 === strpos($content['message'], 'API rate limit exceeded'))) { + $limit = (int) ResponseMediator::getHeader($response, 'X-RateLimit-Limit'); + $reset = (int) ResponseMediator::getHeader($response, 'X-RateLimit-Reset'); + + throw new ApiLimitExceedException($limit, $reset); + } + + $reset = (int) ResponseMediator::getHeader($response, 'X-RateLimit-Reset'); + if ((403 === $response->getStatusCode()) && 0 < $reset && isset($content['message']) && (0 === strpos($content['message'], 'You have exceeded a secondary rate limit.'))) { + $limit = (int) ResponseMediator::getHeader($response, 'X-RateLimit-Limit'); + + throw new ApiLimitExceedException($limit, $reset); + } + throw new RuntimeException(isset($content['message']) ? $content['message'] : $content, $response->getStatusCode()); }); } diff --git a/test/Github/Tests/HttpClient/Plugin/GithubExceptionThrowerTest.php b/test/Github/Tests/HttpClient/Plugin/GithubExceptionThrowerTest.php index 99973521980..f8090ef622c 100644 --- a/test/Github/Tests/HttpClient/Plugin/GithubExceptionThrowerTest.php +++ b/test/Github/Tests/HttpClient/Plugin/GithubExceptionThrowerTest.php @@ -75,6 +75,40 @@ public static function responseProvider() ), 'exception' => new \Github\Exception\ApiLimitExceedException(5000), ], + 'Rate Limit Exceeded via 403 status' => [ + 'response' => new Response( + 403, + [ + 'Content-Type' => 'application/json', + 'X-RateLimit-Remaining' => 0, + 'X-RateLimit-Limit' => 5000, + 'X-RateLimit-Reset' => 1609245810, + ], + json_encode( + [ + 'message' => 'API rate limit exceeded for installation ID xxxxxxx.', + ] + ) + ), + 'exception' => new \Github\Exception\ApiLimitExceedException(5000), + ], + 'Secondary Rate Limit Exceeded via 403 status' => [ + 'response' => new Response( + 403, + [ + 'Content-Type' => 'application/json', + 'X-RateLimit-Remaining' => 100, + 'X-RateLimit-Limit' => 5000, + 'X-RateLimit-Reset' => 1609245810, + ], + json_encode( + [ + 'message' => 'You have exceeded a secondary rate limit. Please wait a few minutes before you try again.', + ] + ) + ), + 'exception' => new \Github\Exception\ApiLimitExceedException(5000), + ], 'Two Factor Authentication Required' => [ 'response' => new Response( 401, From 83b8a32867d7dc293d89c852062540f5f709726e Mon Sep 17 00:00:00 2001 From: Henrik Gemal Date: Fri, 17 Jun 2022 15:04:10 +0200 Subject: [PATCH 37/98] bug #1071 dont require encoding (gemal) This PR was squashed before being merged into the 3.4.x-dev branch. Discussion ---------- fixes #1042 Commits ------- 89c71de08c47c8f78ff68fd3597ad08bb0a0e4b4 dont require encoding 35c97c280e5b19a842bf6273d1bd532f9a6fdb1b Update BlobsTest.php --- lib/Github/Api/GitData/Blobs.php | 4 ++-- test/Github/Tests/Api/GitData/BlobsTest.php | 15 --------------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/lib/Github/Api/GitData/Blobs.php b/lib/Github/Api/GitData/Blobs.php index 3b7357f3dd9..31aacda5674 100644 --- a/lib/Github/Api/GitData/Blobs.php +++ b/lib/Github/Api/GitData/Blobs.php @@ -59,8 +59,8 @@ public function show($username, $repository, $sha) */ public function create($username, $repository, array $params) { - if (!isset($params['content'], $params['encoding'])) { - throw new MissingArgumentException(['content', 'encoding']); + if (!isset($params['content'])) { + throw new MissingArgumentException('content'); } return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/git/blobs', $params); diff --git a/test/Github/Tests/Api/GitData/BlobsTest.php b/test/Github/Tests/Api/GitData/BlobsTest.php index 368d47c3cc2..4b87ed33e41 100644 --- a/test/Github/Tests/Api/GitData/BlobsTest.php +++ b/test/Github/Tests/Api/GitData/BlobsTest.php @@ -68,21 +68,6 @@ public function shouldCreateBlob() $this->assertEquals($expectedValue, $api->create('l3l0', 'l3l0repo', $data)); } - /** - * @test - */ - public function shouldNotCreateBlobWithoutEncoding() - { - $this->expectException(MissingArgumentException::class); - $data = ['content' => 'some cotent']; - - $api = $this->getApiMock(); - $api->expects($this->never()) - ->method('post'); - - $api->create('l3l0', 'l3l0repo', $data); - } - /** * @test */ From 2354dce31f0a5544eb99f5d9ef07ca8f48a009dc Mon Sep 17 00:00:00 2001 From: Guy Sartorelli Date: Mon, 20 Jun 2022 12:06:00 +1200 Subject: [PATCH 38/98] Add method to use generate release notes endpoint --- lib/Github/Api/Repository/Releases.php | 14 +++++++++++++ .../Tests/Api/Repository/ReleasesTest.php | 20 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/lib/Github/Api/Repository/Releases.php b/lib/Github/Api/Repository/Releases.php index 10dfe09d290..6cd7fda4f0a 100644 --- a/lib/Github/Api/Repository/Releases.php +++ b/lib/Github/Api/Repository/Releases.php @@ -68,6 +68,20 @@ public function show($username, $repository, $id) return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/'.$id); } + /** + * Generate release notes content for a release. + * + * @param string $username + * @param string $repository + * @param array $params + * + * @return array + */ + public function generateNotes($username, $repository, array $params) + { + return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/generate-notes', $params); + } + /** * Create new release in selected repository. * diff --git a/test/Github/Tests/Api/Repository/ReleasesTest.php b/test/Github/Tests/Api/Repository/ReleasesTest.php index 8668195c1e6..dda8999a163 100644 --- a/test/Github/Tests/Api/Repository/ReleasesTest.php +++ b/test/Github/Tests/Api/Repository/ReleasesTest.php @@ -76,6 +76,26 @@ public function shouldGetSingleRepositoryRelease() $this->assertEquals($expectedValue, $api->show('KnpLabs', 'php-github-api', $id)); } + /** + * @test + */ + public function shouldGenerateReleaseNotes() + { + $expectedValue = [ + 'name' => 'Release v1.0.0 is now available!', + 'body' => '##Changes in Release v1.0.0 ... ##Contributors @monalisa', + ]; + $data = ['tag_name' => 'some-tag']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('/repos/KnpLabs/php-github-api/releases/generate-notes') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->generateNotes('KnpLabs', 'php-github-api', $data)); + } + /** * @test */ From 72b353383097c4518a184dfbfb43efe75a5601b6 Mon Sep 17 00:00:00 2001 From: secalith-code <109801896+secalith-code@users.noreply.github.com> Date: Thu, 28 Jul 2022 20:19:06 +0200 Subject: [PATCH 39/98] Update security.md --- doc/security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/security.md b/doc/security.md index 7a79ee6674c..7aed2f9806c 100644 --- a/doc/security.md +++ b/doc/security.md @@ -64,7 +64,7 @@ $jwt = $config->builder(ChainedFormatter::withUnixTimestampDates()) ->getToken($config->signer(), $config->signingKey()) ; -$github->authenticate($jwt->toString(), null, Github\AuthMethod::JWT) +$github->authenticate($jwt->toString(), null, Github\AuthMethod::JWT); ``` The `$integrationId` you can find in the about section of your github app. From e15ee949f315900fa50c6044281685aaafa4dee9 Mon Sep 17 00:00:00 2001 From: Cameron Eagans Date: Mon, 1 Aug 2022 12:57:07 -0600 Subject: [PATCH 40/98] feature #1066 Fix typehint for repository dispatch method (cweagans) This PR was squashed before being merged into the 3.4.x-dev branch. Discussion ---------- Closes https://github.com/KnpLabs/php-github-api/issues/1065 Commits ------- 714798ce7bde498dafae276ac54194cbd1e05144 Fix typehint for repository dispatch method 5005773664c5f0be14c6d6b7d6c2a5bce90e7671 styleci fixes --- lib/Github/Api/Repo.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/Github/Api/Repo.php b/lib/Github/Api/Repo.php index 5760a587bed..f5762279e7a 100644 --- a/lib/Github/Api/Repo.php +++ b/lib/Github/Api/Repo.php @@ -286,14 +286,19 @@ public function readme($username, $repository, $format = 'raw', $dir = null, $pa * * @link https://developer.github.com/v3/repos/#create-a-repository-dispatch-event * - * @param string $username the user who owns the repository - * @param string $repository the name of the repository - * @param string $eventType A custom webhook event name + * @param string $username the user who owns the repository + * @param string $repository the name of the repository + * @param string $eventType A custom webhook event name + * @param array|object $clientPayload The payload to pass to Github. * * @return mixed null on success, array on error with 'message' */ - public function dispatch($username, $repository, $eventType, array $clientPayload) + public function dispatch($username, $repository, $eventType, $clientPayload) { + if (is_array($clientPayload)) { + $clientPayload = (object) $clientPayload; + } + return $this->post(\sprintf('/repos/%s/%s/dispatches', rawurlencode($username), rawurlencode($repository)), [ 'event_type' => $eventType, 'client_payload' => $clientPayload, From a43662d7c9d4032768ec829dde2cf143878a4104 Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Mon, 1 Aug 2022 20:58:16 +0200 Subject: [PATCH 41/98] Update changelog for 3.8.0 release --- CHANGELOG-3.X.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG-3.X.md b/CHANGELOG-3.X.md index 6e413c1c5f7..6117a31c262 100644 --- a/CHANGELOG-3.X.md +++ b/CHANGELOG-3.X.md @@ -1,5 +1,18 @@ # Changelog +## 3.8.0 + +### Added +- API rate limit error status can be 403 ([matthewnessworthy](https://github.com/matthewnessworthy)) [#1072](https://github.com/KnpLabs/php-github-api/issues/1072) +- Add method to use generate release notes endpoint ([GuySartorelli](https://github.com/GuySartorelli)) [#1074](https://github.com/KnpLabs/php-github-api/issues/1074) +- Fix typehint for repository dispatch method ([cweagans](https://github.com/cweagans)) [#1066](https://github.com/KnpLabs/php-github-api/issues/1066) + +### Changed +- Update security.md ([secalith-code](https://github.com/secalith-code)) [#1076](https://github.com/KnpLabs/php-github-api/issues/1076) + +### Fixed +- dont require encoding ([gemal](https://github.com/gemal)) [#1071](https://github.com/KnpLabs/php-github-api/issues/1071) + ## 3.7.0 ### Added From 0158c304ae7c1c44ef261baf51e7c412585aa1db Mon Sep 17 00:00:00 2001 From: Thomas Genin Date: Mon, 15 Aug 2022 15:35:56 +0200 Subject: [PATCH 42/98] feature #1075 Add the ability to download raw file, needed when size > 1MB (genintho) This PR was squashed before being merged into the 3.4.x-dev branch. Discussion ---------- API DOC https://docs.github.com/en/rest/repos/contents The API call to return the content of a file return an empty content if a file is bigger than 1MB. To be able to download that file, we need to provide the header `application/vnd.github.VERSION.raw`. When doing so, the API return a the raw file, instead of a JSON object with some attributes + the file content. Because the API has a different behavior, I preferred to create a dedicated method as opposed to provide accept more option in the download method and having a bunch of if/else. Note: a 3rd behavior exists for that API call when downloading markdown and passing the `application/vnd.github.VERSION.html` header, which is not supported by this code change. Commits ------- 520ffb9c2c6887bb5c25c32f515a8f93077635c0 Add the ability to download raw file, needed when size > 1MB ff458a2cab21cd3939eb48a2da98c0400768fb07 Restore modification committed by mistake e7c393ffae6dbbfd70d455eafc887d0b85619f40 Style fix --- lib/Github/Api/Repository/Contents.php | 34 +++++++++++++++---- .../Tests/Api/Repository/ContentsTest.php | 17 ++++++++++ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/lib/Github/Api/Repository/Contents.php b/lib/Github/Api/Repository/Contents.php index bc78503b2f9..4f9693dcbe1 100644 --- a/lib/Github/Api/Repository/Contents.php +++ b/lib/Github/Api/Repository/Contents.php @@ -61,14 +61,15 @@ public function readme($username, $repository, $reference = null) * * @link http://developer.github.com/v3/repos/contents/ * - * @param string $username the user who owns the repository - * @param string $repository the name of the repository - * @param string|null $path path to file or directory - * @param string|null $reference reference to a branch or commit + * @param string $username the user who owns the repository + * @param string $repository the name of the repository + * @param string|null $path path to file or directory + * @param string|null $reference reference to a branch or commit + * @param array $requestHeaders request headers * * @return array|string information for file | information for each item in directory */ - public function show($username, $repository, $path = null, $reference = null) + public function show($username, $repository, $path = null, $reference = null, $requestHeaders = []) { $url = '/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/contents'; if (null !== $path) { @@ -77,7 +78,7 @@ public function show($username, $repository, $path = null, $reference = null) return $this->get($url, [ 'ref' => $reference, - ]); + ], $requestHeaders); } /** @@ -294,4 +295,25 @@ public function download($username, $repository, $path, $reference = null) return base64_decode($file['content']) ?: null; } + + /** + * Get the raw content of a file in a repository. + * + * Use this method instead of the download method if your file is bigger than 1MB + * + * @see https://docs.github.com/en/rest/repos/contents + * + * @param string $username the user who owns the repository + * @param string $repository the name of the repository + * @param string $path path to file + * @param string|null $reference reference to a branch or commit + * + * @return array|string + */ + public function rawDownload($username, $repository, $path, $reference = null) + { + return $this->show($username, $repository, $path, $reference, [ + 'Accept' => 'application/vnd.github.VERSION.raw', + ]); + } } diff --git a/test/Github/Tests/Api/Repository/ContentsTest.php b/test/Github/Tests/Api/Repository/ContentsTest.php index 122fbf5cdf9..1cc828c370d 100644 --- a/test/Github/Tests/Api/Repository/ContentsTest.php +++ b/test/Github/Tests/Api/Repository/ContentsTest.php @@ -319,6 +319,23 @@ public function shouldDownloadForSpacedPath() $this->assertEquals($expectedValue, $api->download('mads379', 'scala.tmbundle', 'Syntaxes/Simple Build Tool.tmLanguage')); } + /** + * @test + */ + public function shouldRawDownloadForGivenPath() + { + // The show() method return + $getValue = include __DIR__.'/fixtures/ContentsDownloadFixture.php'; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/repos/KnpLabs/php-github-api/contents/test%2FGithub%2FTests%2FApi%2FRepository%2FContentsTest.php', ['ref' => null]) + ->will($this->returnValue($getValue)); + + $this->assertEquals($getValue, $api->rawDownload('KnpLabs', 'php-github-api', 'test/Github/Tests/Api/Repository/ContentsTest.php')); + } + /** * @return string */ From 6b3c7eafb6e42de97400f82bd3f84f61e1bf99ae Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Mon, 15 Aug 2022 15:37:19 +0200 Subject: [PATCH 43/98] Update branch alias --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index ce6d0072118..8d51cdd7421 100644 --- a/composer.json +++ b/composer.json @@ -52,7 +52,7 @@ "extra": { "branch-alias": { "dev-2.x": "2.20.x-dev", - "dev-master": "3.4.x-dev" + "dev-master": "3.9.x-dev" } }, "config": { From e1c8cb9ee91545d018dc6107e1dc235504336ae1 Mon Sep 17 00:00:00 2001 From: Robert Korulczyk Date: Fri, 26 Aug 2022 16:02:09 +0200 Subject: [PATCH 44/98] minor #1078 Fix return types in phpdoc for `Assignees` and `ReviewRequest` (rob006) This PR was squashed before being merged into the 3.9.x-dev branch. Discussion ---------- Commits ------- 628a74914f7d61451ef5fe4ba696f3fad6e65374 PHPDoc: fix return type in `Assignees::remove()` 3d40ebb3b42f15c3b521a595d1a0855bf3b7b760 PHPDoc: fix return type in `Assignees::add()` a8747acb0974807e7ea6920b141a02460a25d1ee PHPDoc: fix return type in `ReviewRequest::remove()` --- lib/Github/Api/Issue/Assignees.php | 4 ++-- lib/Github/Api/PullRequest/ReviewRequest.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Github/Api/Issue/Assignees.php b/lib/Github/Api/Issue/Assignees.php index 8ae86d1cd99..46435650823 100644 --- a/lib/Github/Api/Issue/Assignees.php +++ b/lib/Github/Api/Issue/Assignees.php @@ -51,7 +51,7 @@ public function check($username, $repository, $assignee) * @throws InvalidArgumentException * @throws MissingArgumentException * - * @return string + * @return array */ public function add($username, $repository, $issue, array $parameters) { @@ -78,7 +78,7 @@ public function add($username, $repository, $issue, array $parameters) * * @throws MissingArgumentException * - * @return string + * @return array */ public function remove($username, $repository, $issue, array $parameters) { diff --git a/lib/Github/Api/PullRequest/ReviewRequest.php b/lib/Github/Api/PullRequest/ReviewRequest.php index 7d77f3e5fd6..e9b9280a119 100644 --- a/lib/Github/Api/PullRequest/ReviewRequest.php +++ b/lib/Github/Api/PullRequest/ReviewRequest.php @@ -63,7 +63,7 @@ public function create($username, $repository, $pullRequest, array $reviewers = * @param array $reviewers * @param array $teamReviewers * - * @return string + * @return array */ public function remove($username, $repository, $pullRequest, array $reviewers = [], array $teamReviewers = []) { From 3467a347db3027815ca012461e0583c7d0284717 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Mon, 12 Sep 2022 14:13:43 -0400 Subject: [PATCH 45/98] feature #1082 Feat: Support new Team Repositories Endpoint (iBotPeaches) This PR was squashed before being merged into the 3.9.x-dev branch. Discussion ---------- * old - https://docs.github.com/en/rest/teams/teams#list-team-repositories-legacy * new - https://docs.github.com/en/rest/teams/teams#list-team-repositories Commits ------- ca597858d2dbd62c9fb7626da2dd0b975c159b7f refactor: support new team endpoint, fallback to legacy if no org 69e82d6f07c26c77eadd702686288f6f9bfa4cdb test: support new team endpoint, fallback to legacy if no org --- lib/Github/Api/Organization/Teams.php | 11 +++++++++-- test/Github/Tests/Api/Organization/TeamsTest.php | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/Github/Api/Organization/Teams.php b/lib/Github/Api/Organization/Teams.php index 3af63b73679..20bb2791a7a 100644 --- a/lib/Github/Api/Organization/Teams.php +++ b/lib/Github/Api/Organization/Teams.php @@ -95,9 +95,16 @@ public function removeMember($team, $username, $organization) return $this->delete('/orgs/'.rawurlencode($organization).'/teams/'.rawurlencode($team).'/memberships/'.rawurlencode($username)); } - public function repositories($team) + /** + * @link https://docs.github.com/en/rest/teams/teams#list-team-repositories + */ + public function repositories($team, $organization = '') { - return $this->get('/teams/'.rawurlencode($team).'/repos'); + if (empty($organization)) { + return $this->get('/teams/'.rawurlencode($team).'/repos'); + } + + return $this->get('/orgs/'.rawurlencode($organization).'/teams/'.rawurlencode($team).'/repos'); } public function repository($team, $organization, $repository) diff --git a/test/Github/Tests/Api/Organization/TeamsTest.php b/test/Github/Tests/Api/Organization/TeamsTest.php index 45c98cb9a1d..18b476986aa 100644 --- a/test/Github/Tests/Api/Organization/TeamsTest.php +++ b/test/Github/Tests/Api/Organization/TeamsTest.php @@ -126,6 +126,22 @@ public function shouldGetTeamRepositories() { $expectedValue = [['name' => 'l3l0repo']]; + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/orgs/KnpLabs/teams/KnpWorld/repos') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->repositories('KnpWorld', 'KnpLabs')); + } + + /** + * @test + */ + public function shouldGetTeamRepositoriesViaLegacy() + { + $expectedValue = [['name' => 'l3l0repo']]; + $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') From 4e2900e736b9ac37f345423795b1037c951dae89 Mon Sep 17 00:00:00 2001 From: Stephan Vock Date: Mon, 10 Oct 2022 16:13:43 +0100 Subject: [PATCH 46/98] App: add hook endpoints --- lib/Github/Api/App/Hook.php | 76 +++++++++++++++++ lib/Github/Api/Apps.php | 14 ++++ test/Github/Tests/Api/App/HookTest.php | 109 +++++++++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 lib/Github/Api/App/Hook.php create mode 100644 test/Github/Tests/Api/App/HookTest.php diff --git a/lib/Github/Api/App/Hook.php b/lib/Github/Api/App/Hook.php new file mode 100644 index 00000000000..e7475dce740 --- /dev/null +++ b/lib/Github/Api/App/Hook.php @@ -0,0 +1,76 @@ +get('/app/hook/config'); + } + + /** + * Update the hook configuration of an app. + * + * @link https://docs.github.com/en/rest/apps/webhooks#update-a-webhook-configuration-for-an-app + * + * @param array $params + * + * @return array + */ + public function updateConfig(array $params) + { + return $this->patch('/app/hook/config', $params); + } + + /** + * List deliveries for an app webhook. + * + * @link https://docs.github.com/en/rest/apps/webhooks#list-deliveries-for-an-app-webhook + * + * @return array + */ + public function deliveries() + { + return $this->get('/app/hook/deliveries'); + } + + /** + * Get a delivery for an app webhook. + * + * @link https://docs.github.com/en/rest/apps/webhooks#get-a-delivery-for-an-app-webhook + * + * @param int $delivery + * + * @return array + */ + public function delivery($delivery) + { + return $this->get('/app/hook/deliveries/'.$delivery); + } + + /** + * Redeliver a delivery for an app webhook. + * + * @link https://docs.github.com/en/rest/apps/webhooks#redeliver-a-delivery-for-an-app-webhook + * + * @param int $delivery + * + * @return array + */ + public function redeliver($delivery) + { + return $this->post('/app/hook/deliveries/'.$delivery.'/attempts'); + } +} diff --git a/lib/Github/Api/Apps.php b/lib/Github/Api/Apps.php index 62df3a3cf82..15e1dfdcd4a 100644 --- a/lib/Github/Api/Apps.php +++ b/lib/Github/Api/Apps.php @@ -2,6 +2,8 @@ namespace Github\Api; +use Github\Api\App\Hook; + /** * @link https://developer.github.com/v3/apps/ * @@ -198,4 +200,16 @@ public function getAuthenticatedApp() { return $this->get('/app'); } + + /** + * Manage the hook of an app. + * + * @link https://docs.github.com/en/rest/apps/webhooks + * + * @return Hook + */ + public function hook() + { + return new Hook($this->getClient()); + } } diff --git a/test/Github/Tests/Api/App/HookTest.php b/test/Github/Tests/Api/App/HookTest.php new file mode 100644 index 00000000000..f2ed6ae5ab4 --- /dev/null +++ b/test/Github/Tests/Api/App/HookTest.php @@ -0,0 +1,109 @@ + 'json', + 'insecure_ssl' => 0, + 'secret' => '********', + 'url' => 'https://localhost/', + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/app/hook/config', []) + ->willReturn($result); + + $this->assertEquals($result, $api->showConfig()); + } + + /** + * @test + */ + public function shouldUpdateHookConfiguration() + { + $parameters = [ + 'content_type' => 'json', + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('patch') + ->with('/app/hook/config', $parameters) + ->willReturn([]); + + $this->assertEquals([], $api->updateConfig($parameters)); + } + + /** + * @test + */ + public function shouldListHookDelivieries() + { + $result = []; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/app/hook/deliveries', []) + ->willReturn($result); + + $this->assertEquals($result, $api->deliveries()); + } + + /** + * @test + */ + public function shouldListHookDeliviery() + { + $result = []; + + $delivery = 1234567; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/app/hook/deliveries/'.$delivery, []) + ->willReturn($result); + + $this->assertEquals($result, $api->delivery($delivery)); + } + + /** + * @test + */ + public function shouldRedeliveryHook() + { + $result = []; + + $delivery = 1234567; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('/app/hook/deliveries/'.$delivery.'/attempts', []) + ->willReturn($result); + + $this->assertEquals($result, $api->redeliver($delivery)); + } + + /** + * @return string + */ + protected function getApiClass() + { + return \Github\Api\App\Hook::class; + } +} From d3307477a77cad3b1aa6a99c78586625aff112e8 Mon Sep 17 00:00:00 2001 From: Andrew Dawes Date: Sat, 22 Oct 2022 19:11:28 +0200 Subject: [PATCH 47/98] Fixed several typos and grammar errors --- doc/activity.md | 6 +++--- doc/caching.md | 2 +- doc/currentuser/publickeys.md | 2 +- doc/customize.md | 2 +- doc/graphql.md | 2 +- doc/project/projects.md | 4 ++-- doc/pull_request/comments.md | 2 +- doc/repo/hooks.md | 2 +- doc/repos.md | 6 +++--- doc/request_response_info.md | 2 +- doc/result_pager.md | 4 ++-- doc/security.md | 4 ++-- doc/testing.md | 24 ++++++++++++------------ doc/two_factor_authentication.md | 2 +- doc/users.md | 2 +- 15 files changed, 33 insertions(+), 33 deletions(-) diff --git a/doc/activity.md b/doc/activity.md index c15690e9fe3..48d7cfb423d 100644 --- a/doc/activity.md +++ b/doc/activity.md @@ -24,7 +24,7 @@ Returns an array of watched repos. > *** Requires [authentication](security.md). *** -### Get repos that a authenticated user has starred +### Get repos that an authenticated user has starred ```php $activity = $client->api('current_user')->starring()->all(); @@ -38,7 +38,7 @@ $activity = $client->api('user')->events('ornicar'); ``` Returns an array of private and public events created for all repos related to the user. -### Get repos that a authenticated user has starred with creation date +### Get repos that an authenticated user has starred with creation date Support for getting the star creation timestamp in the response, using the custom `Accept: application/vnd.github.v3.star+json` header. @@ -75,7 +75,7 @@ $activity = $client->api('current_user')->starring()->unstar($owner, $repo); Throws an Exception in case of failure or NULL in case of success. -### Get repos that a authenticated user is watching +### Get repos that an authenticated user is watching ```php $activity = $client->api('current_user')->watchers()->all(); diff --git a/doc/caching.md b/doc/caching.md index a95f92e9eea..1a004cc8781 100644 --- a/doc/caching.md +++ b/doc/caching.md @@ -26,5 +26,5 @@ $client->removeCache(); ``` Using cache, the client will get cached responses if resources haven't changed since last time, -**without** reaching the `X-Rate-Limit` [imposed by github](http://developer.github.com/v3/#rate-limiting). +**without** reaching the `X-Rate-Limit` [imposed by GitHub](http://developer.github.com/v3/#rate-limiting). diff --git a/doc/currentuser/publickeys.md b/doc/currentuser/publickeys.md index a9d19018f2d..444dd58fa0c 100644 --- a/doc/currentuser/publickeys.md +++ b/doc/currentuser/publickeys.md @@ -25,7 +25,7 @@ $key = $client->me()->keys()->show(1234); $key = $client->me()->keys()->create(array('title' => 'key title', 'key' => 12345)); ``` -Adds a key with title 'key title' to the authenticated user and returns a the created key for the user. +Adds a key with title 'key title' to the authenticated user and returns the created key for the user. ### Remove a public key from the authenticated user. diff --git a/doc/customize.md b/doc/customize.md index 1d5ae51e766..b475ee57322 100644 --- a/doc/customize.md +++ b/doc/customize.md @@ -22,7 +22,7 @@ To use the symfony http client composer require symfony/http-client nyholm/psr7 ``` -To set up the github client with this http client +To set up the GitHub client with this http client ```php use Github\Client; diff --git a/doc/graphql.md b/doc/graphql.md index e9ba581c506..dfe83639085 100644 --- a/doc/graphql.md +++ b/doc/graphql.md @@ -11,7 +11,7 @@ $rateLimits = $client->api('graphql')->execute($query); #### Authentication -To use [GitHub v4 API (GraphQL API)](http://developer.github.com/v4/) requests must [authenticated](security.md). +To use [GitHub v4 API (GraphQL API)](http://developer.github.com/v4/) requests must [authenticate](security.md). ```php $client->authenticate($token, null, Github\AuthMethod::ACCESS_TOKEN); diff --git a/doc/project/projects.md b/doc/project/projects.md index 5763e0060e7..103bbe10c86 100644 --- a/doc/project/projects.md +++ b/doc/project/projects.md @@ -1,10 +1,10 @@ ## Repo / Projects API [Back to the "Repos API"](../) | [Back to the navigation](../README.md) -This api is currently only available to developers in Early Access. To access the API during the Early Access period, +This api is currently only available to developers in Early Access. To access the API during the Early Access period, you must provide a custom media type in the Accept header. -Both repositories and organisations have projects. The api is only different for gettings all or a single project. +Both repositories and organisations have projects. The api is only different for getting all or a single project. All the example use the repository projects api but this also works form the organization api (`$client->api('org_projects')`) ```php diff --git a/doc/pull_request/comments.md b/doc/pull_request/comments.md index 87ca5f8e443..e996f804989 100644 --- a/doc/pull_request/comments.md +++ b/doc/pull_request/comments.md @@ -67,7 +67,7 @@ $comment = $client->api('pull_request')->comments()->update('KnpLabs', 'php-gith This returns the details of the updated comment. -### Remove a review comment from an pull request +### Remove a review comment from a pull request > Requires [authentication](../security.md). diff --git a/doc/repo/hooks.md b/doc/repo/hooks.md index 1f89ed40405..a4f9d9af655 100644 --- a/doc/repo/hooks.md +++ b/doc/repo/hooks.md @@ -1,7 +1,7 @@ ## Repo / Hooks API [Back to the "Repos API"](../repos.md) | [Back to the navigation](../README.md) -For extended info see the [Github documentation](https://docs.github.com/en/rest/reference/repos#webhooks) +For extended info see the [GitHub documentation](https://docs.github.com/en/rest/reference/repos#webhooks) ### List repository webhooks diff --git a/doc/repos.md b/doc/repos.md index ab412dc77c2..a0f822ce446 100644 --- a/doc/repos.md +++ b/doc/repos.md @@ -310,8 +310,8 @@ $activity = $client->api('repo')->activity('ornicar', 'php-github-api'); Returns an array of commit activity group by week. ### `Moved` repositories -Github repositories can be moved to another org/user, but it remains the `id`. -In case if you can't no more find repo, you can retrieve it by `id`: +GitHub repositories can be moved to another org/user, but it remains the `id`. +In case you can't find the repo anymore, you can retrieve it by `id`: ```php use Github\HttpClient\Message\ResponseMediator; @@ -365,7 +365,7 @@ $repo = $client->api('repo')->transfer('KnpLabs', 'php-github-api', 'github', [1 ### Create a repository dispatch event -Example when you want to configure custom github action workflows. +Example when you want to configure custom GitHub action workflows. ```php $client->api('repo')->dispatch('KnpLabs', 'php-github-api', 'acme-event', ['foo'=>'bar']); diff --git a/doc/request_response_info.md b/doc/request_response_info.md index 880e7f85a22..32e30981ea4 100644 --- a/doc/request_response_info.md +++ b/doc/request_response_info.md @@ -3,7 +3,7 @@ ### Get response headers -Get the repsonse header for the latest request +Get the response header for the latest request ``` $headers = $githubClient->getLastResponse()->getHeaders(); diff --git a/doc/result_pager.md b/doc/result_pager.md index b13432cb569..f074f1cc4a1 100644 --- a/doc/result_pager.md +++ b/doc/result_pager.md @@ -3,7 +3,7 @@ ### Usage examples -#### Get all repositories of a organization +#### Get all repositories of an organization ```php $client = new Github\Client(); @@ -21,7 +21,7 @@ Parameters of the `fetchAll` method: * The method of the API object you're using * The parameters of the method -Parameters are passed to the API method via [call_user_func_array](https://www.php.net/manual/en/function.call-user-func-array.php). +Parameters are passed to the API method via [call_user_func_array](https://www.php.net/manual/en/function.call-user-func-array.php). ```php $parameters = array('github', 'all', 1); // $organization, $type, $page diff --git a/doc/security.md b/doc/security.md index 7aed2f9806c..a8596de20b1 100644 --- a/doc/security.md +++ b/doc/security.md @@ -33,7 +33,7 @@ further requests are done as the given user. ### Authenticating as an Integration To authenticate as an integration you need to supply a JSON Web Token with `Github\AuthMethod::JWT` to request -and installation access token which is then usable with `Github\AuthMethod::ACCESS_TOKEN`. [Github´s integration +and installation access token which is then usable with `Github\AuthMethod::ACCESS_TOKEN`. [GitHub´s integration authentication docs](https://developer.github.com/apps/building-github-apps/authentication-options-for-github-apps/#authenticating-as-a-github-app) describe the flow in detail. It´s important for integration requests to use the custom Accept header `application/vnd.github.machine-man-preview`. @@ -67,5 +67,5 @@ $jwt = $config->builder(ChainedFormatter::withUnixTimestampDates()) $github->authenticate($jwt->toString(), null, Github\AuthMethod::JWT); ``` -The `$integrationId` you can find in the about section of your github app. +The `$integrationId` you can find in the about section of your GitHub app. The `$installationId` you can find by installing the app and using the id in the url. diff --git a/doc/testing.md b/doc/testing.md index ec2effb3b5c..36df32097eb 100644 --- a/doc/testing.md +++ b/doc/testing.md @@ -4,7 +4,7 @@ ### Run Test Suite -The code is unit tested, there are also some functional tests. To run tests on +The code is unit tested, there are also some functional tests. To run tests on your machine, from a CLI, run ```bash @@ -14,12 +14,12 @@ $ phpunit ### Write tests -It is always great if someone wants to contribute and extend the functionality of -the API client. But all new features must be properly tested. To test a new API -function, one should test its communication with the HTTP client. The code should -never make an actual call to Github. Testing could easily be done with mocking. +It is always great if someone wants to contribute and extend the functionality of +the API client. But all new features must be properly tested. To test a new API +function, one should test its communication with the HTTP client. The code should +never make an actual call to GitHub. Testing could easily be done with mocking. -If you want to write test for the function that shows you comments to a gist. +If you want to write test for the function that shows you comments to a gist. ```php class Comments extends AbstractApi @@ -32,7 +32,7 @@ class Comments extends AbstractApi } ``` -The test will look like this: +The test will look like this: ```php use Github\Tests\Api\TestCase; @@ -51,7 +51,7 @@ class CommentsTest extends TestCase // Get the API mock (see "getApiClass" below). $api = $this->getApiMock(); - + $api->expects($this->once()) // Expect one call ->method('get') // A GET request ->with('/gists/123/comments/456') // URI should be "/gists/123/comments/456" @@ -59,14 +59,14 @@ class CommentsTest extends TestCase // Call Comments::show $result = $api->show(123, 456); - - // Verify that the result is the "Server response" as we expect. + + // Verify that the result is the "Server response" as we expect. $this->assertEquals($expectedValue, $result); } - + protected function getApiClass() { - // Tell the "getAPIMock" what class to mock. + // Tell the "getAPIMock" what class to mock. return \Github\Api\Gist\Comments::class; } } diff --git a/doc/two_factor_authentication.md b/doc/two_factor_authentication.md index 46e84e0daa5..3b58de49abc 100644 --- a/doc/two_factor_authentication.md +++ b/doc/two_factor_authentication.md @@ -1,4 +1,4 @@ -## Two factor authentication +## Two-factor authentication [Back to the navigation](README.md) diff --git a/doc/users.md b/doc/users.md index dbc6a6bb302..48bb0d7dc15 100644 --- a/doc/users.md +++ b/doc/users.md @@ -33,7 +33,7 @@ $user = $client->api('user')->show('KnpLabs'); Returns an array of information about the user. -You can also use the User ID, but it will use an undocumented Github API +You can also use the User ID, but it will use an undocumented GitHub API ```php $user = $client->api('user')->showById(202732); From f1cb6b620426184f3351dcbcf3b1c32b83d53bca Mon Sep 17 00:00:00 2001 From: Mahmud Date: Mon, 24 Oct 2022 15:40:34 +0300 Subject: [PATCH 48/98] feature #1084 Add sync a fork branch with the upstream repository (DAGpro) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR was squashed before being merged into the 3.9.x-dev branch. Discussion ---------- | Q | A | ------------- | --- | New feature? | ✔️ | Fixed issues | #1083 Commits ------- 184826b93898f9fca03397891a35d46b92262635 Add sync a fork branch with the upstream repository c6b2d3966202586a4688192995e7b86ae2b445af Mark the default branch 06e6c9bab0d154ec232c833b57fa87ef4c0acffa Add tests and documentation for the mergeUpstream method 0de3d781a404198dde89473a4a64a74ac656d7e2 Make parameter required d5d9aff69d85343b05d36b0d608dd1dccf7d8aaf Add typings to the mergeUpstream method --- doc/repos.md | 9 +++++++++ lib/Github/Api/Repo.php | 15 +++++++++++++++ test/Github/Tests/Api/RepoTest.php | 20 ++++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/doc/repos.md b/doc/repos.md index a0f822ce446..7e091e005fe 100644 --- a/doc/repos.md +++ b/doc/repos.md @@ -223,6 +223,15 @@ $repository = $client->api('repo')->forks()->create('ornicar', 'php-github-api') Creates a fork of the 'php-github-api' owned by 'ornicar' and returns the newly created repository. +### Merge upstream repository + +> Requires [authentication](security.md). + +```php +$repository = $client->api('repo')->mergeUpstream('ornicar', 'php-github-api', 'branchName'); +``` +Merge upstream a branch of a forked repository to keep it up-to-date with the upstream repository. + ### Get the tags of a repository ```php diff --git a/lib/Github/Api/Repo.php b/lib/Github/Api/Repo.php index f5762279e7a..7536d7007dd 100644 --- a/lib/Github/Api/Repo.php +++ b/lib/Github/Api/Repo.php @@ -535,6 +535,21 @@ public function branches($username, $repository, $branch = null, array $paramete return $this->get($url, $parameters); } + /** + * Sync a fork branch with the upstream repository. + * + * @link https://docs.github.com/en/rest/branches/branches#sync-a-fork-branch-with-the-upstream-repository + * + * @return array|string + */ + public function mergeUpstream(string $username, string $repository, string $branchName) + { + return $this->post( + '/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/merge-upstream', + ['branch' => $branchName] + ); + } + /** * Manage the protection of a repository branch. * diff --git a/test/Github/Tests/Api/RepoTest.php b/test/Github/Tests/Api/RepoTest.php index 9cfa7f84a88..b4603bcddf9 100644 --- a/test/Github/Tests/Api/RepoTest.php +++ b/test/Github/Tests/Api/RepoTest.php @@ -240,6 +240,26 @@ public function shouldGetRepositoryBranch() $this->assertEquals($expectedArray, $api->branches('KnpLabs', 'php-github-api', 'master')); } + /** + * @test + */ + public function shouldMergeUpstreamRepository() + { + $expectedArray = [ + 'message' => 'Successfully fetched and fast-forwarded from upstream upstreamRepo:main', + 'merge_type' => 'fast-forward', + 'merge_branch' => 'upstreamRepo:main', + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('/repos/KnpLabs/php-github-api/merge-upstream', ['branch' => 'main']) + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->mergeUpstream('KnpLabs', 'php-github-api', 'main')); + } + /** * @test */ From 665ba275dbf36f9e9ef78876f27ca87796e3599c Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Mon, 24 Oct 2022 14:42:09 +0200 Subject: [PATCH 49/98] Update changelog for 3.9.0 release --- CHANGELOG-3.X.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG-3.X.md b/CHANGELOG-3.X.md index 6117a31c262..5aa309b25b3 100644 --- a/CHANGELOG-3.X.md +++ b/CHANGELOG-3.X.md @@ -1,5 +1,17 @@ # Changelog +## 3.9.0 + +### Added +- Add the ability to download raw file, needed when size > 1MB ([genintho](https://github.com/genintho)) [#1075](https://github.com/KnpLabs/php-github-api/issues/1075) +- Feat: Support new Team Repositories Endpoint ([iBotPeaches](https://github.com/iBotPeaches)) [#1082](https://github.com/KnpLabs/php-github-api/issues/1082) +- App: add hook endpoints ([glaubinix](https://github.com/glaubinix)) [#1086](https://github.com/KnpLabs/php-github-api/issues/1086) +- Add sync a fork branch with the upstream repository ([DAGpro](https://github.com/DAGpro)) [#1084](https://github.com/KnpLabs/php-github-api/issues/1084) + +### Changed +- Fix return types in phpdoc for `Assignees` and `ReviewRequest` ([rob006](https://github.com/rob006)) [#1078](https://github.com/KnpLabs/php-github-api/issues/1078) +- Fixed several typos and grammar errors ([AndrewDawes](https://github.com/AndrewDawes)) [#1088](https://github.com/KnpLabs/php-github-api/issues/1088) + ## 3.8.0 ### Added From 28029f21d714cba67426ef20bdec0fed5ce97b53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Dartigues?= Date: Tue, 25 Oct 2022 12:14:22 +0545 Subject: [PATCH 50/98] minor #1090 Create authorization removed from docs (rafasashi) This PR was squashed before being merged into the 3.9.x-dev branch. Discussion ---------- Create authorization deprecated and removed in V3 ([2fe12b8](https://github.com/KnpLabs/php-github-api/commit/2fe12b82a7fe5896ae4f067d4c62326c4041602f)) Commits ------- 92e683afc9d9e9305e4058f09dcca06a22e65a1c Create authorization removed cbac8bf36f2e2b0c56774d3daae3c2b68bdedf98 Delete two_factor_authentication.md --- doc/authorizations.md | 12 ------------ doc/two_factor_authentication.md | 19 ------------------- 2 files changed, 31 deletions(-) delete mode 100644 doc/two_factor_authentication.md diff --git a/doc/authorizations.md b/doc/authorizations.md index 2865fd63e19..b037e402c27 100644 --- a/doc/authorizations.md +++ b/doc/authorizations.md @@ -15,18 +15,6 @@ $authorizations = $github->api('authorizations')->all(); $authorization = $github->api('authorizations')->show(1); ``` -#### Create an authorization - -```php -$data = array( - 'note' => 'This is an optional description' -); - -$authorization = $github->api('authorizations')->create($data); -``` - -Creates and returns an authorization. - #### Update an authorization You can update ``note``. diff --git a/doc/two_factor_authentication.md b/doc/two_factor_authentication.md deleted file mode 100644 index 3b58de49abc..00000000000 --- a/doc/two_factor_authentication.md +++ /dev/null @@ -1,19 +0,0 @@ -## Two-factor authentication -[Back to the navigation](README.md) - - -### Raising the exception - -```php -try { - $authorization = $github->api('authorizations')->create(); -} catch (Github\Exception\TwoFactorAuthenticationRequiredException $e) { - echo sprintf("Two factor authentication of type %s is required.", $e->getType()); -} -``` - -Once the code has been retrieved (by sms for example), you can create an authorization: - -``` -$authorization = $github->api('authorizations')->create(array('note' => 'Optional'), $code); -``` From 7245b02233934f5c90fbaf25aa4076bb37417801 Mon Sep 17 00:00:00 2001 From: Andreia Bohner Date: Wed, 1 Feb 2023 22:22:10 -0300 Subject: [PATCH 51/98] Add vulnerability alerts endpoints --- doc/repos.md | 24 +++++++++++++ lib/Github/Api/Repo.php | 45 +++++++++++++++++++++++++ test/Github/Tests/Api/RepoTest.php | 54 ++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+) diff --git a/doc/repos.md b/doc/repos.md index 7e091e005fe..d7c30d490f4 100644 --- a/doc/repos.md +++ b/doc/repos.md @@ -390,3 +390,27 @@ $client->api('repo')->createFromTemplate('template-owner', 'template-repo', [ 'owner' => 'name-of-new-repo-owner', // can be user or org ]); ``` + +### Check if vulnerability alerts (dependabot alerts) are enabled for a repository + +https://developer.github.com/v3/repos/#check-if-vulnerability-alerts-are-enabled-for-a-repository + +```php +$client->api('repo')->isVulnerabilityAlertsEnabled('KnpLabs', 'php-github-api'); +``` + +### Enable vulnerability alerts (dependabot alerts) + +https://developer.github.com/v3/repos/#enable-vulnerability-alerts + +```php +$client->api('repo')->enableVulnerabilityAlerts('KnpLabs', 'php-github-api'); +``` + +### Disable vulnerability alerts (dependabot alerts) + +https://developer.github.com/v3/repos/#disable-vulnerability-alerts + +```php +$client->api('repo')->disableVulnerabilityAlerts('KnpLabs', 'php-github-api'); +``` diff --git a/lib/Github/Api/Repo.php b/lib/Github/Api/Repo.php index 7536d7007dd..42a5e16a610 100644 --- a/lib/Github/Api/Repo.php +++ b/lib/Github/Api/Repo.php @@ -843,4 +843,49 @@ public function createFromTemplate(string $templateOwner, string $templateRepo, return $this->post('/repos/'.rawurldecode($templateOwner).'/'.rawurldecode($templateRepo).'/generate', $parameters); } + + /** + * Check if vulnerability alerts are enabled for a repository. + * + * @link https://developer.github.com/v3/repos/#check-if-vulnerability-alerts-are-enabled-for-a-repository + * + * @param string $username the username + * @param string $repository the repository + * + * @return array|string + */ + public function isVulnerabilityAlertsEnabled(string $username, string $repository) + { + return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/vulnerability-alerts'); + } + + /** + * Enable vulnerability alerts for a repository. + * + * @link https://developer.github.com/v3/repos/#enable-vulnerability-alerts + * + * @param string $username the username + * @param string $repository the repository + * + * @return array|string + */ + public function enableVulnerabilityAlerts(string $username, string $repository) + { + return $this->put('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/vulnerability-alerts'); + } + + /** + * Disable vulnerability alerts for a repository. + * + * @link https://developer.github.com/v3/repos/#disable-vulnerability-alerts + * + * @param string $username the username + * @param string $repository the repository + * + * @return array|string + */ + public function disableVulnerabilityAlerts(string $username, string $repository) + { + return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/vulnerability-alerts'); + } } diff --git a/test/Github/Tests/Api/RepoTest.php b/test/Github/Tests/Api/RepoTest.php index b4603bcddf9..7d30bace2af 100644 --- a/test/Github/Tests/Api/RepoTest.php +++ b/test/Github/Tests/Api/RepoTest.php @@ -722,4 +722,58 @@ protected function getApiClass() { return \Github\Api\Repo::class; } + + /** + * @test + */ + public function shouldCheckVulnerabilityAlertsEnabled() + { + $expectedResponse = ''; + + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('get') + ->with('/repos/KnpLabs/php-github-api/vulnerability-alerts') + ->will($this->returnValue($expectedResponse)); + + $this->assertEquals($expectedResponse, $api->isVulnerabilityAlertsEnabled('KnpLabs', 'php-github-api')); + } + + /** + * @test + */ + public function shouldEnableVulnerabilityAlerts() + { + $expectedResponse = ''; + + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('put') + ->with('/repos/KnpLabs/php-github-api/vulnerability-alerts') + ->will($this->returnValue($expectedResponse)); + + $this->assertEquals($expectedResponse, $api->enableVulnerabilityAlerts('KnpLabs', 'php-github-api')); + } + + /** + * @test + */ + public function shouldDisableVulnerabilityAlerts() + { + $expectedResponse = ''; + + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('delete') + ->with('/repos/KnpLabs/php-github-api/vulnerability-alerts') + ->will($this->returnValue($expectedResponse)); + + $this->assertEquals($expectedResponse, $api->disableVulnerabilityAlerts('KnpLabs', 'php-github-api')); + } } From 131e597d7897c920f48f42eca88ea5657cd19b26 Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Sun, 5 Feb 2023 16:35:12 +0100 Subject: [PATCH 52/98] Setup dependabot for github action workflows --- .github/dependabot.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000000..6d2d16a545f --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" From 782da176b1b16e86a19bebb2f8e3ba91993fc561 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Feb 2023 15:37:15 +0000 Subject: [PATCH 53/98] Bump actions/checkout from 2 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/backwards-compatibility.yml | 2 +- .github/workflows/ci.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/backwards-compatibility.yml b/.github/workflows/backwards-compatibility.yml index 1dd4c3a4e05..cdb19e8dfe6 100644 --- a/.github/workflows/backwards-compatibility.yml +++ b/.github/workflows/backwards-compatibility.yml @@ -8,7 +8,7 @@ jobs: name: "Roave BC check" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 175c5f09a0e..4dfec2cdf92 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1'] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -33,7 +33,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: shivammathur/setup-php@v2 with: From d120c79919378c7ae544439fbc8824d94f579b41 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Feb 2023 15:37:18 +0000 Subject: [PATCH 54/98] Bump ramsey/composer-install from 1 to 2 Bumps [ramsey/composer-install](https://github.com/ramsey/composer-install) from 1 to 2. - [Release notes](https://github.com/ramsey/composer-install/releases) - [Commits](https://github.com/ramsey/composer-install/compare/v1...v2) --- updated-dependencies: - dependency-name: ramsey/composer-install dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 175c5f09a0e..8a7a356223d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: coverage: none - name: Install Composer Dependencies - uses: ramsey/composer-install@v1 + uses: ramsey/composer-install@v2 - name: Run phpunit run: vendor/bin/phpunit --verbose @@ -41,7 +41,7 @@ jobs: coverage: none - name: Install Composer Dependencies - uses: ramsey/composer-install@v1 + uses: ramsey/composer-install@v2 - name: Run phpstan run: vendor/bin/phpstan analyse --no-progress From 32f79ea8436e19a7dc858dcda7a7c1d3fe0e7fd5 Mon Sep 17 00:00:00 2001 From: Sergkei Melingk Date: Thu, 9 Mar 2023 12:24:13 +0200 Subject: [PATCH 55/98] feature #1103 Added environments (Froxz) This PR was squashed before being merged into the 3.9.x-dev branch. Discussion ---------- Added support for environments #1102 Commits ------- 75c79306f76844d0d1916df1ea2890f81f76c539 Added environments 329c72fe2cb4b4a5f5e8bc78b830007d7b7be8c2 environment b163de2daab9d490bca111eb22671c3b8f960750 fixes e9da726b127d03f012348c074cc42dc5e12a30c4 fixes 536ac080141039b5b4082c4084942e419e92eb59 Fixed Tests 48da33703f488680d5a0985e8d0817f380eb282f Fixed tests 6c79b05de665277081fcae8e2d9cf825f12c0646 Removed trait for custom beta accept header, 7c97a2c7a4d68a47d6f052e6ec93d73036c60cb2 removed unready changes --- doc/README.md | 1 + doc/repo/environments.md | 28 +++++++++ lib/Github/Api/Environment.php | 70 ++++++++++++++++++++++ lib/Github/Client.php | 5 ++ test/Github/Tests/Api/EnvironmentTest.php | 71 +++++++++++++++++++++++ 5 files changed, 175 insertions(+) create mode 100644 doc/repo/environments.md create mode 100644 lib/Github/Api/Environment.php create mode 100644 test/Github/Tests/Api/EnvironmentTest.php diff --git a/doc/README.md b/doc/README.md index acae0d3a441..3c1579f3269 100644 --- a/doc/README.md +++ b/doc/README.md @@ -59,6 +59,7 @@ v3 APIs: * [Check Suites](repo/check_suites.md) * [Contents](repo/contents.md) * [Deployments](repo/deployments.md) + * [Environments](repo/environments.md) * [Labels](repo/labels.md) * [Protection](repo/protection.md) * [Releases](repo/releases.md) diff --git a/doc/repo/environments.md b/doc/repo/environments.md new file mode 100644 index 00000000000..56387ef8bfc --- /dev/null +++ b/doc/repo/environments.md @@ -0,0 +1,28 @@ +## Repo / Environments API +[Back to the "Repos API"](../repos.md) | [Back to the navigation](../index.md) + +Provides information about environments for a repository. Wraps [GitHub Environments API](https://docs.github.com/en/rest/deployments/environments?apiVersion=2022-11-28). + +#### List all environments. + +```php +$environments = $client->api('environment')->all('KnpLabs', 'php-github-api'); +``` + +### Get one environment. + +```php +$environment = $client->api('environment')->show('KnpLabs', 'php-github-api', $name); +``` + +#### Create or update environment. + +```php +$data = $client->api('environment')->createOrUpdate('KnpLabs', 'php-github-api', $name); +``` + +#### Delete a existing environment. + +```php +$environment = $client->api('environment')->remove('KnpLabs', 'php-github-api', $name); +``` diff --git a/lib/Github/Api/Environment.php b/lib/Github/Api/Environment.php new file mode 100644 index 00000000000..057d1edf0d8 --- /dev/null +++ b/lib/Github/Api/Environment.php @@ -0,0 +1,70 @@ +get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/environments', $params); + } + + /** + * Get a environment in selected repository. + * + * @param string $username the user who owns the repo + * @param string $repository the name of the repo + * @param string $name the name of the environment + * + * @return array + */ + public function show($username, $repository, $name) + { + return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/environments/'.$name); + } + + /** + * Create or update a environment for the given username and repo. + * + * @link https://docs.github.com/en/rest/deployments/environments?apiVersion=2022-11-28#create-or-update-an-environment + * + * @param string $username the username + * @param string $repository the repository + * @param string $name the name of the environment + * @param array $params the new environment data + * + * @return array information about the environment + */ + public function createOrUpdate($username, $repository, $name, array $params = []) + { + return $this->put('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/environments', $params); + } + + /** + * Delete a environment for the given username and repo. + * + * @link https://docs.github.com/en/rest/deployments/environments?apiVersion=2022-11-28#delete-an-environment + * + * @return mixed null on success, array on error with 'message' + */ + public function remove(string $username, string $repository, string $name) + { + return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/environments/'.$name); + } +} diff --git a/lib/Github/Client.php b/lib/Github/Client.php index 56d68d59cec..c1eaa501faf 100644 --- a/lib/Github/Client.php +++ b/lib/Github/Client.php @@ -181,6 +181,11 @@ public function api($name): AbstractApi $api = new Api\Deployment($this); break; + case 'environment': + case 'environments': + $api = new Api\Environment($this); + break; + case 'ent': case 'enterprise': $api = new Api\Enterprise($this); diff --git a/test/Github/Tests/Api/EnvironmentTest.php b/test/Github/Tests/Api/EnvironmentTest.php new file mode 100644 index 00000000000..56efbc0afc8 --- /dev/null +++ b/test/Github/Tests/Api/EnvironmentTest.php @@ -0,0 +1,71 @@ +getApiMock(); + + $api->expects($this->once()) + ->method('put') + ->with('/repos/KnpLabs/php-github-api/environments'); + + $api->createOrUpdate('KnpLabs', 'php-github-api', 'production'); + } + + /** + * @test + */ + public function shouldGetAllEnvironments() + { + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/repos/KnpLabs/php-github-api/environments'); + + $api->all('KnpLabs', 'php-github-api'); + } + + /** + * @test + */ + public function shouldShowEnvironment() + { + $expectedValue = 'production'; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/repos/KnpLabs/php-github-api/environments/production') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->show('KnpLabs', 'php-github-api', 'production')); + } + + /** + * @test + */ + public function shouldDeleteEnvironment() + { + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('/repos/KnpLabs/php-github-api/environments/production') + ->will($this->returnValue(null)); + + $this->assertNull($api->remove('KnpLabs', 'php-github-api', 'production')); + } + + /** + * @return string + */ + protected function getApiClass() + { + return \Github\Api\Environment::class; + } +} From 799aa2b8c9dd9b03e5c353339d083601407e3cc4 Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Thu, 9 Mar 2023 11:26:52 +0100 Subject: [PATCH 56/98] Update changelog for 3.10.0 release --- CHANGELOG-3.X.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG-3.X.md b/CHANGELOG-3.X.md index 5aa309b25b3..3ec12940b20 100644 --- a/CHANGELOG-3.X.md +++ b/CHANGELOG-3.X.md @@ -1,5 +1,17 @@ # Changelog +## 3.10.0 + +### Added +- Add vulnerability alerts endpoints ([andreia](https://github.com/andreia)) [#1096](https://github.com/KnpLabs/php-github-api/issues/1096) +- Added environments ([Froxz](https://github.com/Froxz)) [#1103](https://github.com/KnpLabs/php-github-api/issues/1103) + +### Changed +- Create authorization removed from docs ([rafasashi](https://github.com/rafasashi)) [#1090](https://github.com/KnpLabs/php-github-api/issues/1090) +- Setup dependabot for github action workflows ([acrobat](https://github.com/acrobat)) [#1098](https://github.com/KnpLabs/php-github-api/issues/1098) +- Bump actions/checkout from 2 to 3 ([dependabot](https://github.com/dependabot)[[bot](https://github.com/bot)]) [#1099](https://github.com/KnpLabs/php-github-api/issues/1099) +- Bump ramsey/composer-install from 1 to 2 ([dependabot](https://github.com/dependabot)[[bot](https://github.com/bot)]) [#1100](https://github.com/KnpLabs/php-github-api/issues/1100) + ## 3.9.0 ### Added From fcc99dd95d762c091754a5233f479549bf5e91ac Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Thu, 9 Mar 2023 11:27:43 +0100 Subject: [PATCH 57/98] Update branch alias --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8d51cdd7421..886b5993221 100644 --- a/composer.json +++ b/composer.json @@ -52,7 +52,7 @@ "extra": { "branch-alias": { "dev-2.x": "2.20.x-dev", - "dev-master": "3.9.x-dev" + "dev-master": "3.10.x-dev" } }, "config": { From 01bd3eed8161bfdbe0ca3f2520f28f79286b425e Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Thu, 9 Mar 2023 11:50:37 +0000 Subject: [PATCH 58/98] Test on PHP 8.2 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 87f37d2af8f..31af3510052 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1'] + php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2'] steps: - uses: actions/checkout@v3 From 8168261aae9891a38974f8b2294a5ab7f9368a0f Mon Sep 17 00:00:00 2001 From: Sergkei Melingk Date: Thu, 9 Mar 2023 22:59:45 +0200 Subject: [PATCH 59/98] bug #1107 Bugfix creating env (Froxz) This PR was squashed before being merged into the 3.10.x-dev branch. Discussion ---------- Commits ------- 22cbc82fd8fb12a9206f0296d3fc67328b7255a5 Bugfix creating env ce974e1009ec36cd363113024c3d8ce3b7d8cc05 fixed tests 8b365a303bfeb3a4cfd08c429d832dbe21090465 added rawurlencode for $name --- lib/Github/Api/Environment.php | 6 +++--- test/Github/Tests/Api/EnvironmentTest.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Github/Api/Environment.php b/lib/Github/Api/Environment.php index 057d1edf0d8..c154666daf3 100644 --- a/lib/Github/Api/Environment.php +++ b/lib/Github/Api/Environment.php @@ -36,7 +36,7 @@ public function all($username, $repository, array $params = []) */ public function show($username, $repository, $name) { - return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/environments/'.$name); + return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/environments/'.rawurlencode($name)); } /** @@ -53,7 +53,7 @@ public function show($username, $repository, $name) */ public function createOrUpdate($username, $repository, $name, array $params = []) { - return $this->put('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/environments', $params); + return $this->put('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/environments/'.rawurlencode($name), $params); } /** @@ -65,6 +65,6 @@ public function createOrUpdate($username, $repository, $name, array $params = [] */ public function remove(string $username, string $repository, string $name) { - return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/environments/'.$name); + return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/environments/'.rawurlencode($name)); } } diff --git a/test/Github/Tests/Api/EnvironmentTest.php b/test/Github/Tests/Api/EnvironmentTest.php index 56efbc0afc8..3b6f6f417fe 100644 --- a/test/Github/Tests/Api/EnvironmentTest.php +++ b/test/Github/Tests/Api/EnvironmentTest.php @@ -13,7 +13,7 @@ public function shouldCreateOrUpdateEnvironment() $api->expects($this->once()) ->method('put') - ->with('/repos/KnpLabs/php-github-api/environments'); + ->with('/repos/KnpLabs/php-github-api/environments/production'); $api->createOrUpdate('KnpLabs', 'php-github-api', 'production'); } From acc045397ae283b13473fd2d999ec1766667b365 Mon Sep 17 00:00:00 2001 From: Sergkei Melingk Date: Fri, 10 Mar 2023 13:16:59 +0200 Subject: [PATCH 60/98] feature #1104 Added environment variables & secrets (Froxz) This PR was squashed before being merged into the 3.10.x-dev branch. Discussion ---------- Added environment: [Secrets](https://docs.github.com/en/rest/actions/secrets?apiVersion=2022-11-28#list-environment-secrets) [Variables](https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#list-environment-variables) Commits ------- 7de0912505f3e47f920185f802ca260db1ae4fe6 Added environment variables & secrets d08d18df6c7111274831e44f921b36177adcca9a fixes for styleCI 3f4fff0f2ea254635853e93ccb3a5d4d60108173 removed rawurlencode for repo id 289c0ab0cd4b78937120011bd2325ab396d06a30 added link to secrets and varaibles cbf08fc221b7c9b703a3a04baf3432927ea9e9fb Removed validation of parameters --- doc/README.md | 2 + doc/environment/secrets.md | 46 +++++++ doc/environment/variables.md | 49 ++++++++ doc/repo/environments.md | 4 + lib/Github/Api/Environment.php | 19 +++ lib/Github/Api/Environment/Secrets.php | 80 ++++++++++++ lib/Github/Api/Environment/Variables.php | 81 ++++++++++++ .../Tests/Api/Environment/SecretsTest.php | 116 +++++++++++++++++ .../Tests/Api/Environment/VariablesTest.php | 118 ++++++++++++++++++ 9 files changed, 515 insertions(+) create mode 100644 doc/environment/secrets.md create mode 100644 doc/environment/variables.md create mode 100644 lib/Github/Api/Environment/Secrets.php create mode 100644 lib/Github/Api/Environment/Variables.php create mode 100644 test/Github/Tests/Api/Environment/SecretsTest.php create mode 100644 test/Github/Tests/Api/Environment/VariablesTest.php diff --git a/doc/README.md b/doc/README.md index 3c1579f3269..58547e32cda 100644 --- a/doc/README.md +++ b/doc/README.md @@ -59,6 +59,8 @@ v3 APIs: * [Check Suites](repo/check_suites.md) * [Contents](repo/contents.md) * [Deployments](repo/deployments.md) + * [Secrets](environment/secrets.md) + * [Variables](environment/variables.md) * [Environments](repo/environments.md) * [Labels](repo/labels.md) * [Protection](repo/protection.md) diff --git a/doc/environment/secrets.md b/doc/environment/secrets.md new file mode 100644 index 00000000000..a956945d61b --- /dev/null +++ b/doc/environment/secrets.md @@ -0,0 +1,46 @@ +## Environment / Secrets API +[Back to the "Environments API"](../repo/environments.md) | [Back to the navigation](../README.md) + +### List environment secrets + +https://docs.github.com/en/rest/actions/secrets?apiVersion=2022-11-28 + +```php +$secrets = $client->environment()->secrets()->all($repoId, $envName); +``` + +### Get an environment secret + +https://docs.github.com/en/rest/actions/secrets?apiVersion=2022-11-28#get-an-environment-secret + +```php +$secret = $client->environment()->secrets()->show($repoId, $envName, $secretName); +``` + +### Create or Update an environment secret + +https://docs.github.com/en/rest/actions/secrets?apiVersion=2022-11-28#create-or-update-an-environment-secret + +```php +$client->environment()->secrets()->createOrUpdate($repoId, $envName, $secretName, [ + 'encrypted_value' => $encryptedValue, + 'key_id' => $key_id +]); +``` + +### Delete an environment secret + +https://docs.github.com/en/rest/reference/actions#delete-an-organization-secret + +```php +$client->environment()->secrets()->remove($repoId, $envName, $secretName); +``` + +### Get an environment public key + +https://docs.github.com/en/rest/reference/actions#get-an-organization-public-key + +```php +$client->environment()->secrets()->publicKey($repoId, $envName); +``` + diff --git a/doc/environment/variables.md b/doc/environment/variables.md new file mode 100644 index 00000000000..d9de932589e --- /dev/null +++ b/doc/environment/variables.md @@ -0,0 +1,49 @@ +## Environment / Variables API +[Back to the "Environments API"](../repo/environments.md) | [Back to the navigation](../README.md) + +### List environment variables + +https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#list-environment-variables + +```php +$variables = $client->environment()->variables()->all($repoId, $envName); +``` + +### Get an environment variable + +https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#get-an-environment-variable + +```php +$variable = $client->environment()->variables()->show($repoId, $envName, $variableName); +``` + +### Create environment variable + +https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#create-an-environment-variable + +```php +$client->environment()->variables()->create($repoId, $envName, [ + 'name' => $name, + 'value' => $value +]); +``` + +### Update environment variable + +https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#update-an-environment-variable + +```php +$client->environment()->variables()->update($repoId, $envName, $variableName, [ + 'name' => $name, + 'value' => $value +]); +``` + +### Delete an environment variable + +https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#delete-an-environment-variable + +```php +$client->environment()->variables()->remove($repoId, $envName, $variableName); +``` + diff --git a/doc/repo/environments.md b/doc/repo/environments.md index 56387ef8bfc..2d3e23a8796 100644 --- a/doc/repo/environments.md +++ b/doc/repo/environments.md @@ -3,6 +3,10 @@ Provides information about environments for a repository. Wraps [GitHub Environments API](https://docs.github.com/en/rest/deployments/environments?apiVersion=2022-11-28). +Additional APIs: +* [Secrets API](environment/secrets.md) +* [Variables API](environment/variables.md) + #### List all environments. ```php diff --git a/lib/Github/Api/Environment.php b/lib/Github/Api/Environment.php index c154666daf3..099ca9e1e9b 100644 --- a/lib/Github/Api/Environment.php +++ b/lib/Github/Api/Environment.php @@ -2,6 +2,9 @@ namespace Github\Api; +use Github\Api\Environment\Secrets; +use Github\Api\Environment\Variables; + /** * Listing, creating and updating environments. * @@ -67,4 +70,20 @@ public function remove(string $username, string $repository, string $name) { return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/environments/'.rawurlencode($name)); } + + /** + * @link https://docs.github.com/en/rest/actions/secrets?apiVersion=2022-11-28#about-secrets-in-github-actions + */ + public function secrets(): Secrets + { + return new Secrets($this->getClient()); + } + + /** + * @link https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#about-variables-in-github-actions + */ + public function variables(): Variables + { + return new Variables($this->getClient()); + } } diff --git a/lib/Github/Api/Environment/Secrets.php b/lib/Github/Api/Environment/Secrets.php new file mode 100644 index 00000000000..cef84c34958 --- /dev/null +++ b/lib/Github/Api/Environment/Secrets.php @@ -0,0 +1,80 @@ +get('/repositories/'.$id.'/environments/'.rawurlencode($name).'/secrets'); + } + + /** + * @link https://docs.github.com/en/rest/actions/secrets?apiVersion=2022-11-28#get-an-environment-secret + * + * @param int $id + * @param string $name + * @param string $secretName + * + * @return array|string + */ + public function show(int $id, string $name, string $secretName) + { + return $this->get('/repositories/'.$id.'/environments/'.rawurlencode($name).'/secrets/'.rawurlencode($secretName)); + } + + /** + * @link https://docs.github.com/en/rest/actions/secrets?apiVersion=2022-11-28#create-or-update-an-environment-secret + * + * @param int $id + * @param string $name + * @param string $secretName + * @param array $parameters + * + * @return array|string + */ + public function createOrUpdate(int $id, string $name, string $secretName, array $parameters = []) + { + return $this->put('/repositories/'.$id.'/environments/'.rawurlencode($name).'/secrets/'.rawurlencode($secretName), $parameters); + } + + /** + * @link https://docs.github.com/en/rest/actions/secrets?apiVersion=2022-11-28#delete-an-environment-secret + * + * @param int $id + * @param string $name + * @param string $secretName + * + * @return array|string + */ + public function remove(int $id, string $name, string $secretName) + { + return $this->delete('/repositories/'.$id.'/environments/'.rawurlencode($name).'/secrets/'.rawurlencode($secretName)); + } + + /** + * @link https://docs.github.com/en/rest/actions/secrets?apiVersion=2022-11-28#get-an-environment-public-key + * + * @param int $id + * @param string $name + * + * @return array|string + */ + public function publicKey(int $id, string $name) + { + return $this->get('/repositories/'.$id.'/environments/'.rawurlencode($name).'/secrets/public-key'); + } +} diff --git a/lib/Github/Api/Environment/Variables.php b/lib/Github/Api/Environment/Variables.php new file mode 100644 index 00000000000..035a8f605a3 --- /dev/null +++ b/lib/Github/Api/Environment/Variables.php @@ -0,0 +1,81 @@ +get('/repositories/'.$id.'/environments/'.rawurlencode($name).'/variables'); + } + + /** + * @link https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#get-an-environment-variable + * + * @param int $id + * @param string $name + * @param string $variableName + * + * @return array|string + */ + public function show(int $id, string $name, string $variableName) + { + return $this->get('/repositories/'.$id.'/environments/'.rawurlencode($name).'/variables/'.rawurlencode($variableName)); + } + + /** + * @link https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#create-an-environment-variable + * + * @param int $id + * @param string $name + * @param array $parameters + * + * @return array|string + */ + public function create(int $id, string $name, array $parameters) + { + return $this->post('/repositories/'.$id.'/environments/'.rawurlencode($name).'/variables', $parameters); + } + + /** + * @link https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#update-an-environment-variable + * + * @param int $id + * @param string $name + * @param string $variableName + * @param array $parameters + * + * @return array|string + */ + public function update(int $id, string $name, string $variableName, array $parameters) + { + return $this->patch('/repositories/'.$id.'/environments/'.rawurlencode($name).'/variables/'.rawurlencode($variableName), $parameters); + } + + /** + * @link https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#delete-an-environment-variable + * + * @param int $id + * @param string $name + * @param string $variableName + * + * @return array|string + */ + public function remove(int $id, string $name, string $variableName) + { + return $this->delete('/repositories/'.$id.'/environments/'.rawurlencode($name).'/variables/'.rawurlencode($variableName)); + } +} diff --git a/test/Github/Tests/Api/Environment/SecretsTest.php b/test/Github/Tests/Api/Environment/SecretsTest.php new file mode 100644 index 00000000000..0609a64f0f6 --- /dev/null +++ b/test/Github/Tests/Api/Environment/SecretsTest.php @@ -0,0 +1,116 @@ + 'name', 'created_at' => 'created_at', 'updated_at' => 'updated_at'], + ['name' => 'name', 'created_at' => 'created_at', 'updated_at' => 'updated_at'], + ['name' => 'name', 'created_at' => 'created_at', 'updated_at' => 'updated_at'], + ]; + + /** @var Secrets|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('get') + ->with('/repositories/3948501/environments/production/secrets') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->all(3948501, 'production')); + } + + /** + * @test + */ + public function shouldGetEnvironmentSecret() + { + $expectedArray = []; + + /** @var Secrets|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('get') + ->with('/repositories/3948501/environments/production/secrets/secretName') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->show(3948501, 'production', 'secretName')); + } + + /** + * @test + */ + public function shouldUpdateOrCreateEnvironmentSecret() + { + $expectedValue = 'response'; + + /** @var Secrets|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('put') + ->with('/repositories/3948501/environments/production/secrets/secretName') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->createOrUpdate(3948501, 'production', 'secretName', [ + 'encrypted_value' => 'foo', 'key_id' => 'key_id', + ])); + } + + /** + * @test + */ + public function shouldRemoveEnvironmentSecret() + { + $expectedValue = 'response'; + + /** @var Secrets|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('delete') + ->with('/repositories/3948501/environments/production/secrets/secretName') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->remove(3948501, 'production', 'secretName')); + } + + /** + * @test + */ + public function shouldGetPublicKey() + { + $expectedArray = ['key_id' => 'key_id', 'key' => 'foo']; + + /** @var Secrets|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('get') + ->with('/repositories/3948501/environments/production/secrets/public-key') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->publicKey(3948501, 'production')); + } + + protected function getApiClass() + { + return Secrets::class; + } +} diff --git a/test/Github/Tests/Api/Environment/VariablesTest.php b/test/Github/Tests/Api/Environment/VariablesTest.php new file mode 100644 index 00000000000..0fc01193fd1 --- /dev/null +++ b/test/Github/Tests/Api/Environment/VariablesTest.php @@ -0,0 +1,118 @@ + 'name', 'value' => 'value', 'created_at' => 'created_at', 'updated_at' => 'updated_at'], + ['name' => 'name', 'value' => 'value', 'created_at' => 'created_at', 'updated_at' => 'updated_at'], + ['name' => 'name', 'value' => 'value', 'created_at' => 'created_at', 'updated_at' => 'updated_at'], + ]; + + /** @var Variables|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('get') + ->with('/repositories/3948501/environments/production/variables') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->all(3948501, 'production')); + } + + /** + * @test + */ + public function shouldGetEnvironmentVariable() + { + $expectedArray = []; + + /** @var Variables|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('get') + ->with('/repositories/3948501/environments/production/variables/variableName') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->show(3948501, 'production', 'variableName')); + } + + /** + * @test + */ + public function shouldCreateEnvironmentVariable() + { + $expectedValue = 'response'; + + /** @var Variables|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('post') + ->with('/repositories/3948501/environments/production/variables') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->create(3948501, 'production', [ + 'name' => 'foo', 'value' => 'bar', + ])); + } + + /** + * @test + */ + public function shouldUpdateEnvironmentVariable() + { + $expectedValue = 'response'; + + /** @var Variables|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('patch') + ->with('/repositories/3948501/environments/production/variables/variableName') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->update(3948501, 'production', 'variableName', [ + 'name' => 'variableName', 'value' => 'bar', + ])); + } + + /** + * @test + */ + public function shouldRemoveEnvironmentVariable() + { + $expectedValue = 'response'; + + /** @var Variables|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('delete') + ->with('/repositories/3948501/environments/production/variables/variableName') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->remove(3948501, 'production', 'variableName')); + } + + protected function getApiClass() + { + return Variables::class; + } +} From bdb9bfb336784c1e3210f17da8f6303c6b3100f0 Mon Sep 17 00:00:00 2001 From: Sergkei Melingk Date: Fri, 10 Mar 2023 13:18:04 +0200 Subject: [PATCH 61/98] feature #1106 Added Org & Repository variables (Froxz) This PR was squashed before being merged into the 3.10.x-dev branch. Discussion ---------- Commits ------- ff0fb37ddab2f78043528bf6efffb399d121763d Added Org & Repository varaibles 4a50d98e86fe100d58768baf203e69dd7b19c067 fixed type hint 7569055fc3bc64e0570cfbbcdfded7fbc546dea1 Fixes 37e12a62316c533bc78fd3a0cf770b607074bb1d added repo variables test 1da518f55c63b767b656f2e577efe28b965073ca StyleCI fixes 9f90a4a38857691b7d7b37161934bf7bbbcfc04e Removed params validation --- doc/README.md | 3 + doc/organization/actions/variables.md | 87 ++++++++ doc/repo/actions/variables.md | 48 +++++ lib/Github/Api/Organization.php | 9 + .../Api/Organization/Actions/Variables.php | 131 ++++++++++++ lib/Github/Api/Repo.php | 9 + .../Api/Repository/Actions/Variables.php | 81 +++++++ .../Organization/Actions/VariablesTest.php | 198 ++++++++++++++++++ test/Github/Tests/Api/OrganizationTest.php | 10 + test/Github/Tests/Api/RepoTest.php | 10 + .../Api/Repository/Actions/VariablesTest.php | 119 +++++++++++ 11 files changed, 705 insertions(+) create mode 100644 doc/organization/actions/variables.md create mode 100644 doc/repo/actions/variables.md create mode 100644 lib/Github/Api/Organization/Actions/Variables.php create mode 100644 lib/Github/Api/Repository/Actions/Variables.php create mode 100644 test/Github/Tests/Api/Organization/Actions/VariablesTest.php create mode 100644 test/Github/Tests/Api/Repository/Actions/VariablesTest.php diff --git a/doc/README.md b/doc/README.md index 58547e32cda..c5b9e8cf363 100644 --- a/doc/README.md +++ b/doc/README.md @@ -39,6 +39,8 @@ v3 APIs: * [Organization](organization.md) * [Members](organization/members.md) * [Teams](organization/teams.md) + * [Secrets](organization/actions/secrets.md) + * [Variables](organization/actions/variables.md) * [Projects](project/projects.md) * [Columns](project/columns.md) * [Cards](project/cards.md) @@ -51,6 +53,7 @@ v3 APIs: * Actions * [Artifacts](repo/actions/artifacts.md) * [Secrets](repo/actions/secrets.md) + * [Variables](repo/actions/variables.md) * [Self hosted runners](repo/actions/self_hosted_runners.md) * [Workflow jobs](repo/actions/workflow_jobs.md) * [Workflow runs](repo/actions/workflow_runs.md) diff --git a/doc/organization/actions/variables.md b/doc/organization/actions/variables.md new file mode 100644 index 00000000000..89c641007f3 --- /dev/null +++ b/doc/organization/actions/variables.md @@ -0,0 +1,87 @@ +## Organization / Variables API +[Back to the "Organization API"](../organization.md) | [Back to the navigation](../README.md) + +### List organization variables + +https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#list-organization-variables + +```php +$variables = $client->organization()->variables()->all('KnpLabs'); +``` + +### Get an organization variable + +https://docs.github.com/en/rest/reference/actions#get-an-organization-secret + +```php +$variable = $client->organization()->variables()->show('KnpLabs', $variableName); +``` + +### Create an organization variable + +https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#create-an-organization-variable + +```php +$client->organization()->variables()->create('KnpLabs', [ + 'name' => $name, + 'value' => $value, + 'visibility' => $visibility, + 'selected_repository_ids' => $selectedRepositoryIds, +]); +``` + +### Update an organization variable + +https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#update-an-organization-variable + +```php +$client->organization()->variables()->update('KnpLabs', $variableName, [ + 'name' => $name, + 'value' => $value, + 'visibility' => $visibility, + 'selected_repository_ids' => $selectedRepositoryIds +]); +``` + +### Delete an organization variable + +https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#delete-an-organization-variable + +```php +$client->organization()->variables()->remove('KnpLabs', $variableName); +``` + +### List selected repositories for organization variable + +https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#list-selected-repositories-for-an-organization-variable + +```php +$client->organization()->variables()->selectedRepositories('KnpLabs', $variableName); +``` + +### Set selected repositories for an organization variable + +https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#set-selected-repositories-for-an-organization-variable + +```php +$client->organization()->variables()->setSelectedRepositories('KnpLabs', 'variableName', [ + 'selected_repository_ids' => [1, 2, 3], +]); +``` + +### Add selected repository to an organization variable + +https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#add-selected-repository-to-an-organization-variable + +```php +$client->organization()->variables()->addRepository('KnpLabs', $repositoryId, $variableName); +``` + +### Remove selected repository from an organization variable + +https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#remove-selected-repository-from-an-organization-variable + +```php +$client->organization()->variables()->removeRepository('KnpLabs', $repositoryId, $variableName); +``` + diff --git a/doc/repo/actions/variables.md b/doc/repo/actions/variables.md new file mode 100644 index 00000000000..c6cc26ac1df --- /dev/null +++ b/doc/repo/actions/variables.md @@ -0,0 +1,48 @@ +## Repo / Actions / Variables API +[Back to the "Repos API"](../../repos.md) | [Back to the navigation](../../README.md) + +### List repository variables + +https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#list-repository-variables + +```php +$variables = $client->api('repo')->variables()->all('KnpLabs', 'php-github-api'); +``` + +### Get a repository variable + +https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#get-a-repository-variable + +```php +$variable = $client->api('repo')->variables()->show('KnpLabs', 'php-github-api', $variableName); +``` + +### Create a repository variable + +https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#create-a-repository-variable + +```php +$client->api('repo')->variables()->create('KnpLabs', 'php-github-api', [ + 'name' => $name, + 'value' => $value, +]); +``` + +### Update a repository variable + +https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#update-a-repository-variable + +```php +$client->api('repo')->variables()->update('KnpLabs', 'php-github-api', $variableName, [ + 'name' => $name, + 'value' => $value, +]); +``` + +### Delete a repository variable + +https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#delete-a-repository-variable + +```php +$client->api('repo')->variables()->remove('KnpLabs', 'php-github-api', $variableName); +``` diff --git a/lib/Github/Api/Organization.php b/lib/Github/Api/Organization.php index d3e7646651d..d1997dabc7a 100644 --- a/lib/Github/Api/Organization.php +++ b/lib/Github/Api/Organization.php @@ -3,6 +3,7 @@ namespace Github\Api; use Github\Api\Organization\Actions\Secrets; +use Github\Api\Organization\Actions\Variables; use Github\Api\Organization\Hooks; use Github\Api\Organization\Members; use Github\Api\Organization\OutsideCollaborators; @@ -110,6 +111,14 @@ public function secrets(): Secrets return new Secrets($this->getClient()); } + /** + * @return Variables + */ + public function variables(): Variables + { + return new Variables($this->getClient()); + } + /** * @return OutsideCollaborators */ diff --git a/lib/Github/Api/Organization/Actions/Variables.php b/lib/Github/Api/Organization/Actions/Variables.php new file mode 100644 index 00000000000..88c037238d3 --- /dev/null +++ b/lib/Github/Api/Organization/Actions/Variables.php @@ -0,0 +1,131 @@ +get('/orgs/'.rawurlencode($organization).'/actions/variables'); + } + + /** + * @link https://docs.github.com/en/rest/reference/actions#get-an-organization-secret + * + * @param string $organization + * @param string $variableName + * + * @return array|string + */ + public function show(string $organization, string $variableName) + { + return $this->get('/orgs/'.rawurlencode($organization).'/actions/variables/'.rawurlencode($variableName)); + } + + /** + * @link https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#create-an-organization-variable + * + * @param string $organization + * @param array $parameters + * + * @return array|string + */ + public function create(string $organization, array $parameters) + { + return $this->post('/orgs/'.rawurlencode($organization).'/actions/variables', $parameters); + } + + /** + * @link https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#update-an-organization-variable + * + * @param string $organization + * @param string $variableName + * @param array $parameters + * + * @return array|string + */ + public function update(string $organization, string $variableName, array $parameters = []) + { + return $this->patch('/orgs/'.rawurlencode($organization).'/actions/variables/'.rawurlencode($variableName), $parameters); + } + + /** + * @link https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#delete-an-organization-variable + * + * @param string $organization + * @param string $variableName + * + * @return array|string + */ + public function remove(string $organization, string $variableName) + { + return $this->delete('/orgs/'.rawurlencode($organization).'/actions/variables/'.rawurlencode($variableName)); + } + + /** + * @link https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#list-selected-repositories-for-an-organization-variable + * + * @param string $organization + * @param string $variableName + * + * @return array|string + */ + public function selectedRepositories(string $organization, string $variableName) + { + return $this->get('/orgs/'.rawurlencode($organization).'/actions/variables/'.rawurlencode($variableName).'/repositories'); + } + + /** + * @link https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#set-selected-repositories-for-an-organization-variable + * + * @param string $organization + * @param string $variableName + * @param array $parameters + * + * @return array|string + */ + public function setSelectedRepositories(string $organization, string $variableName, array $parameters = []) + { + return $this->put('/orgs/'.rawurlencode($organization).'/actions/variables/'.rawurlencode($variableName).'/repositories', $parameters); + } + + /** + * @link https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#add-selected-repository-to-an-organization-variable + * + * @param string $organization + * @param int $repositoryId + * @param string $variableName + * + * @return array|string + */ + public function addRepository(string $organization, int $repositoryId, string $variableName) + { + return $this->put('/orgs/'.rawurlencode($organization).'/actions/variables/'.rawurlencode($variableName).'/repositories/'.$repositoryId); + } + + /** + * @link https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#remove-selected-repository-from-an-organization-variable + * + * @param string $organization + * @param int $repositoryId + * @param string $variableName + * + * @return array|string + */ + public function removeRepository(string $organization, int $repositoryId, string $variableName) + { + return $this->delete('/orgs/'.rawurlencode($organization).'/actions/variables/'.rawurlencode($variableName).'/repositories/'.$repositoryId); + } +} diff --git a/lib/Github/Api/Repo.php b/lib/Github/Api/Repo.php index 42a5e16a610..bcfe13edb73 100644 --- a/lib/Github/Api/Repo.php +++ b/lib/Github/Api/Repo.php @@ -5,6 +5,7 @@ use Github\Api\Repository\Actions\Artifacts; use Github\Api\Repository\Actions\Secrets; use Github\Api\Repository\Actions\SelfHostedRunners; +use Github\Api\Repository\Actions\Variables; use Github\Api\Repository\Actions\WorkflowJobs; use Github\Api\Repository\Actions\WorkflowRuns; use Github\Api\Repository\Actions\Workflows; @@ -405,6 +406,14 @@ public function secrets(): Secrets return new Secrets($this->getClient()); } + /** + * @link https://docs.github.com/en/rest/reference/actions#secrets + */ + public function variables(): Variables + { + return new Variables($this->getClient()); + } + /** * Manage the content of a repository. * diff --git a/lib/Github/Api/Repository/Actions/Variables.php b/lib/Github/Api/Repository/Actions/Variables.php new file mode 100644 index 00000000000..7414e82810b --- /dev/null +++ b/lib/Github/Api/Repository/Actions/Variables.php @@ -0,0 +1,81 @@ +get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/variables'); + } + + /** + * @link https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#get-a-repository-variable + * + * @param string $username + * @param string $repository + * @param string $variableName + * + * @return array|string + */ + public function show(string $username, string $repository, string $variableName) + { + return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/variables/'.rawurlencode($variableName)); + } + + /** + * @link https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#create-a-repository-variable + * + * @param string $username + * @param string $repository + * @param array $parameters + * + * @return array|string + */ + public function create(string $username, string $repository, array $parameters = []) + { + return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/variables', $parameters); + } + + /** + * @link https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#update-a-repository-variable + * + * @param string $username + * @param string $repository + * @param string $variableName + * @param array $parameters + * + * @return array|string + */ + public function update(string $username, string $repository, string $variableName, array $parameters = []) + { + return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/variables/'.rawurlencode($variableName), $parameters); + } + + /** + * @link https://docs.github.com/en/rest/actions/variables?apiVersion=2022-11-28#delete-a-repository-variable + * + * @param string $username + * @param string $repository + * @param string $variableName + * + * @return array|string + */ + public function remove(string $username, string $repository, string $variableName) + { + return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/variables/'.rawurlencode($variableName)); + } +} diff --git a/test/Github/Tests/Api/Organization/Actions/VariablesTest.php b/test/Github/Tests/Api/Organization/Actions/VariablesTest.php new file mode 100644 index 00000000000..98d5072377e --- /dev/null +++ b/test/Github/Tests/Api/Organization/Actions/VariablesTest.php @@ -0,0 +1,198 @@ + 'name', 'value' => 'value', 'created_at' => 'created_at', 'updated_at' => 'updated_at', 'visibility' => 'all'], + ['name' => 'name', 'value' => 'value', 'created_at' => 'created_at', 'updated_at' => 'updated_at', 'visibility' => 'private'], + ['name' => 'name', 'value' => 'value', 'created_at' => 'created_at', 'updated_at' => 'updated_at', 'visibility' => 'selected'], + ]; + + /** @var Variables|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('get') + ->with('/orgs/KnpLabs/actions/variables') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->all('KnpLabs')); + } + + /** + * @test + */ + public function shouldGetOrganizationVariable() + { + $expectedArray = []; + + /** @var Variables|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('get') + ->with('/orgs/KnpLabs/actions/variables/variableName') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->show('KnpLabs', 'variableName')); + } + + /** + * @test + */ + public function shouldCreateOrganizationVariable() + { + $expectedValue = 'response'; + + /** @var Variables|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('post') + ->with('/orgs/KnpLabs/actions/variables') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->create('KnpLabs', [ + 'name' => 'foo', 'value' => 'value', 'visibility' => 'all', + ])); + } + + /** + * @test + */ + public function shouldUpdateOrganizationVariable() + { + $expectedValue = 'response'; + + /** @var Variables|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('patch') + ->with('/orgs/KnpLabs/actions/variables/variableName') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->update('KnpLabs', 'variableName', [ + 'name' => 'foo', 'value' => 'value', 'visibility' => 'private', + ])); + } + + /** + * @test + */ + public function shouldRemoveOrganizationVariable() + { + $expectedValue = 'response'; + + /** @var Variables|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('delete') + ->with('/orgs/KnpLabs/actions/variables/variableName') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->remove('KnpLabs', 'variableName')); + } + + /** + * @test + */ + public function shouldGetSelectedRepositories() + { + $expectedArray = [1, 2, 3]; + + /** @var Variables|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('get') + ->with('/orgs/KnpLabs/actions/variables/variableName/repositories') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->selectedRepositories('KnpLabs', 'variableName')); + } + + /** + * @test + */ + public function shouldSetSelectedRepositories() + { + $expectedArray = [ + 'selected_repository_ids' => [1, 2, 3], + ]; + + /** @var Variables|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('put') + ->with('/orgs/KnpLabs/actions/variables/variableName/repositories') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->setSelectedRepositories('KnpLabs', 'variableName', [ + 'selected_repository_ids' => [1, 2, 3], + ])); + } + + /** + * @test + */ + public function shouldAddRepository() + { + $expectedValue = 'response'; + + /** @var Variables|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('put') + ->with('/orgs/KnpLabs/actions/variables/variableName/repositories/1') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->addRepository('KnpLabs', 1, 'variableName')); + } + + /** + * @test + */ + public function shouldRemoveRepository() + { + $expectedValue = 'response'; + + /** @var Variables|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('delete') + ->with('/orgs/KnpLabs/actions/variables/variableName/repositories/1') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->removeRepository('KnpLabs', 1, 'variableName')); + } + + protected function getApiClass() + { + return Variables::class; + } +} diff --git a/test/Github/Tests/Api/OrganizationTest.php b/test/Github/Tests/Api/OrganizationTest.php index 04f389c0337..d13547bd663 100644 --- a/test/Github/Tests/Api/OrganizationTest.php +++ b/test/Github/Tests/Api/OrganizationTest.php @@ -88,6 +88,16 @@ public function shouldGetTeamsApiObject() $this->assertInstanceOf(\Github\Api\Organization\Teams::class, $api->teams()); } + /** + * @test + */ + public function shouldGetVariablesApiObject() + { + $api = $this->getApiMock(); + + $this->assertInstanceOf(\Github\Api\Organization\Actions\Variables::class, $api->variables()); + } + /** * @return string */ diff --git a/test/Github/Tests/Api/RepoTest.php b/test/Github/Tests/Api/RepoTest.php index 7d30bace2af..7b84a6b52ac 100644 --- a/test/Github/Tests/Api/RepoTest.php +++ b/test/Github/Tests/Api/RepoTest.php @@ -570,6 +570,16 @@ public function shouldGetReleasesApiObject() $this->assertInstanceOf(\Github\Api\Repository\Releases::class, $api->releases()); } + /** + * @test + */ + public function shouldGetVariablesApiObject() + { + $api = $this->getApiMock(); + + $this->assertInstanceOf(\Github\Api\Repository\Actions\Variables::class, $api->variables()); + } + /** * @test */ diff --git a/test/Github/Tests/Api/Repository/Actions/VariablesTest.php b/test/Github/Tests/Api/Repository/Actions/VariablesTest.php new file mode 100644 index 00000000000..e362d31f7bc --- /dev/null +++ b/test/Github/Tests/Api/Repository/Actions/VariablesTest.php @@ -0,0 +1,119 @@ + 'GH_TOKEN', 'value' => 'value', 'created_at' => 'created_at', 'updated_at' => 'updated_at'], + ['name' => 'GIST_ID', 'value' => 'value', 'created_at' => 'created_at', 'updated_at' => 'updated_at'], + ]; + + /** @var Variables|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('get') + ->with('/repos/KnpLabs/php-github-api/actions/variables') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->all('KnpLabs', 'php-github-api')); + } + + /** + * @test + */ + public function shouldGetVariable() + { + $expectedArray = ['name' => 'name', 'value' => 'value', 'created_at' => 'created_at', 'updated_at' => 'updated_at']; + + /** @var Variables|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('get') + ->with('/repos/KnpLabs/php-github-api/actions/variables/variableName') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->show('KnpLabs', 'php-github-api', 'variableName')); + } + + /** + * @test + */ + public function shouldCreateVariable() + { + $expectedValue = 'response'; + + /** @var Variables|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('post') + ->with('/repos/KnpLabs/php-github-api/actions/variables') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->create('KnpLabs', 'php-github-api', [ + 'name' => 'name', + 'value' => 'value', + ])); + } + + /** + * @test + */ + public function shouldUpdateVariable() + { + $expectedValue = 'response'; + + /** @var Variables|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('patch') + ->with('/repos/KnpLabs/php-github-api/actions/variables/variableName') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->update('KnpLabs', 'php-github-api', 'variableName', [ + 'name' => 'name', + 'value' => 'value', + ])); + } + + /** + * @test + */ + public function shouldRemoveVariable() + { + $expectedValue = 'response'; + + /** @var Variables|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('delete') + ->with('/repos/KnpLabs/php-github-api/actions/variables/variableName') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->remove('KnpLabs', 'php-github-api', 'variableName')); + } + + protected function getApiClass() + { + return Variables::class; + } +} From 00570ac2c22d5d4d074a7bb29103a5a5329e172f Mon Sep 17 00:00:00 2001 From: Sergkei Melingk Date: Fri, 10 Mar 2023 13:39:43 +0200 Subject: [PATCH 62/98] feature #1108 Deployment branch policies (Froxz) This PR was squashed before being merged into the 3.10.x-dev branch. Discussion ---------- * added Deployment branch policies * Moved environments under deployment Commits ------- 9734d230e6c5e98f4bed1c86696de1b47c3c87fb Deployment branch policies c72fdae237d59aeb058d18850a7e3cb012a65197 removed params validation a61fe843d39a4fd48408bb1c167dd6c07cdf6bb6 StyleCI fixes c30050c9c84eac1b81bddb0a9bb8f558b449f6c2 styleCI fixes 5d7048f8b3b34289cd53ac296060f43a8b74bee9 Merge branch 'master' into feature/deployment-branch-policies f657c3fd16a899b8c34294f028ebb739270618eb StyleCi fixes d9f0195fa677a571314408f77a3b5779488816bf Changes to docs --- doc/README.md | 7 +- .../deployments}/environment/secrets.md | 2 +- .../deployments}/environment/variables.md | 2 +- doc/repo/deployments/environments.md | 32 ++++++ doc/repo/deployments/policies.md | 38 ++++++++ doc/repo/environments.md | 32 ------ lib/Github/Api/Deployment.php | 18 ++++ .../Environments.php} | 5 +- lib/Github/Api/Deployment/Policies.php | 97 +++++++++++++++++++ lib/Github/Client.php | 5 - .../EnvironmentsTest.php} | 6 +- .../Tests/Api/Deployment/PoliciesTest.php | 91 +++++++++++++++++ test/Github/Tests/Api/DeploymentTest.php | 20 ++++ 13 files changed, 309 insertions(+), 46 deletions(-) rename doc/{ => repo/deployments}/environment/secrets.md (92%) rename doc/{ => repo/deployments}/environment/variables.md (92%) create mode 100644 doc/repo/deployments/environments.md create mode 100644 doc/repo/deployments/policies.md delete mode 100644 doc/repo/environments.md rename lib/Github/Api/{Environment.php => Deployment/Environments.php} (96%) create mode 100644 lib/Github/Api/Deployment/Policies.php rename test/Github/Tests/Api/{EnvironmentTest.php => Deployment/EnvironmentsTest.php} (92%) create mode 100644 test/Github/Tests/Api/Deployment/PoliciesTest.php diff --git a/doc/README.md b/doc/README.md index c5b9e8cf363..cecccfb90b7 100644 --- a/doc/README.md +++ b/doc/README.md @@ -62,9 +62,10 @@ v3 APIs: * [Check Suites](repo/check_suites.md) * [Contents](repo/contents.md) * [Deployments](repo/deployments.md) - * [Secrets](environment/secrets.md) - * [Variables](environment/variables.md) - * [Environments](repo/environments.md) + * [Policies](repo/deployments/policies.md) + * [Environments](repo/deployments/environments.md) + * [Secrets](repo/deployments/environment/secrets.md) + * [Variables](repo/deployments/environment/variables.md) * [Labels](repo/labels.md) * [Protection](repo/protection.md) * [Releases](repo/releases.md) diff --git a/doc/environment/secrets.md b/doc/repo/deployments/environment/secrets.md similarity index 92% rename from doc/environment/secrets.md rename to doc/repo/deployments/environment/secrets.md index a956945d61b..5c0c86b85d7 100644 --- a/doc/environment/secrets.md +++ b/doc/repo/deployments/environment/secrets.md @@ -1,5 +1,5 @@ ## Environment / Secrets API -[Back to the "Environments API"](../repo/environments.md) | [Back to the navigation](../README.md) +[Back to the "Environments API"](../environments.md) | [Back to the navigation](../README.md) ### List environment secrets diff --git a/doc/environment/variables.md b/doc/repo/deployments/environment/variables.md similarity index 92% rename from doc/environment/variables.md rename to doc/repo/deployments/environment/variables.md index d9de932589e..d645349a204 100644 --- a/doc/environment/variables.md +++ b/doc/repo/deployments/environment/variables.md @@ -1,5 +1,5 @@ ## Environment / Variables API -[Back to the "Environments API"](../repo/environments.md) | [Back to the navigation](../README.md) +[Back to the "Environments API"](../environments.md) | [Back to the navigation](../README.md) ### List environment variables diff --git a/doc/repo/deployments/environments.md b/doc/repo/deployments/environments.md new file mode 100644 index 00000000000..6cb409ae3b3 --- /dev/null +++ b/doc/repo/deployments/environments.md @@ -0,0 +1,32 @@ +## Deployment / Environments API +[Back to the "Deployment API"](../deployments.md) | [Back to the navigation](../index.md) + +Provides information about environments for a repository. Wraps [GitHub Environments API](https://docs.github.com/en/rest/deployments/environments?apiVersion=2022-11-28). + +Additional APIs: +* [Secrets API](environment/secrets.md) +* [Variables API](environment/variables.md) + +#### List all environments. + +```php +$environments = $client->deployment()->environment()->all('KnpLabs', 'php-github-api'); +``` + +### Get one environment. + +```php +$environment = $client->deployment()->environment()->show('KnpLabs', 'php-github-api', $name); +``` + +#### Create or update environment. + +```php +$data = $client->deployment()->environment()->createOrUpdate('KnpLabs', 'php-github-api', $name); +``` + +#### Delete a existing environment. + +```php +$environment = $client->deployment()->environment()->remove('KnpLabs', 'php-github-api', $name); +``` diff --git a/doc/repo/deployments/policies.md b/doc/repo/deployments/policies.md new file mode 100644 index 00000000000..442fc0c4acb --- /dev/null +++ b/doc/repo/deployments/policies.md @@ -0,0 +1,38 @@ +## Deployment / Branch policies API +[Back to the "Deployment API"](../deployments.md) | [Back to the navigation](../index.md) + +Provides information about deployment branch policies. Wraps [GitHub Deployment branch policies API](https://docs.github.com/en/rest/deployments/branch-policies?apiVersion=2022-11-28#about-deployment-branch-policies). + +#### List deployment branch policies. + +```php +$policies = $client->deployment()->policies()->all('KnpLabs', 'php-github-api', 'production'); +``` + +### Get one environment. + +```php +$policy = $client->deployment()->policies()->show('KnpLabs', 'php-github-api', 'production', $branchPolicyId); +``` + +#### Create policy. + +```php +$data = $client->deployment()->policies()->create('KnpLabs', 'php-github-api', 'production', [ + 'name' => 'name' +]); +``` + +#### Update policy. + +```php +$data = $client->deployment()->policies()->update('KnpLabs', 'php-github-api', 'production', $branchPolicyId, [ + 'name' => 'name' +]); +``` + +#### Delete a existing policy. + +```php +$policy = $client->deployment()->policies()->remove('KnpLabs', 'php-github-api', 'production', $branchPolicyId); +``` diff --git a/doc/repo/environments.md b/doc/repo/environments.md deleted file mode 100644 index 2d3e23a8796..00000000000 --- a/doc/repo/environments.md +++ /dev/null @@ -1,32 +0,0 @@ -## Repo / Environments API -[Back to the "Repos API"](../repos.md) | [Back to the navigation](../index.md) - -Provides information about environments for a repository. Wraps [GitHub Environments API](https://docs.github.com/en/rest/deployments/environments?apiVersion=2022-11-28). - -Additional APIs: -* [Secrets API](environment/secrets.md) -* [Variables API](environment/variables.md) - -#### List all environments. - -```php -$environments = $client->api('environment')->all('KnpLabs', 'php-github-api'); -``` - -### Get one environment. - -```php -$environment = $client->api('environment')->show('KnpLabs', 'php-github-api', $name); -``` - -#### Create or update environment. - -```php -$data = $client->api('environment')->createOrUpdate('KnpLabs', 'php-github-api', $name); -``` - -#### Delete a existing environment. - -```php -$environment = $client->api('environment')->remove('KnpLabs', 'php-github-api', $name); -``` diff --git a/lib/Github/Api/Deployment.php b/lib/Github/Api/Deployment.php index f6127357ee9..de5b0cb0eb9 100644 --- a/lib/Github/Api/Deployment.php +++ b/lib/Github/Api/Deployment.php @@ -2,6 +2,8 @@ namespace Github\Api; +use Github\Api\Deployment\Environments; +use Github\Api\Deployment\Policies; use Github\Exception\MissingArgumentException; /** @@ -130,4 +132,20 @@ public function getStatuses($username, $repository, $id) { return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/deployments/'.$id.'/statuses'); } + + /** + * @return Environments + */ + public function environments() + { + return new Environments($this->getClient()); + } + + /** + * @return Policies + */ + public function policies() + { + return new Policies($this->getClient()); + } } diff --git a/lib/Github/Api/Environment.php b/lib/Github/Api/Deployment/Environments.php similarity index 96% rename from lib/Github/Api/Environment.php rename to lib/Github/Api/Deployment/Environments.php index 099ca9e1e9b..191ec498eab 100644 --- a/lib/Github/Api/Environment.php +++ b/lib/Github/Api/Deployment/Environments.php @@ -1,7 +1,8 @@ get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/environments/'.rawurlencode($environment).'/deployment-branch-policies', $params); + } + + /** + * Get a deployment branch policy. + * + * @link https://docs.github.com/en/rest/deployments/branch-policies?apiVersion=2022-11-28#get-a-deployment-branch-policy + * + * @param string $username the username of the user who owns the repository + * @param string $repository the name of the repository + * @param string $environment the name of the environment. + * @param int $id the unique identifier of the branch policy. + * + * @return array + */ + public function show(string $username, string $repository, string $environment, int $id) + { + return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/environments/'.rawurlencode($environment).'/deployment-branch-policies/'.$id); + } + + /** + * Creates a deployment branch policy for an environment. + * + * @link https://docs.github.com/en/rest/deployments/branch-policies?apiVersion=2022-11-28#create-a-deployment-branch-policy + * + * @param string $username the username of the user who owns the repository + * @param string $repository the name of the repository + * @param string $environment the name of the environment. + * + * @return array information about the deployment branch policy + */ + public function create(string $username, string $repository, string $environment, array $params) + { + return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/environments/'.rawurlencode($environment).'/deployment-branch-policies', $params); + } + + /** + * Updates a deployment branch policy for an environment. + * + * @link https://docs.github.com/en/rest/deployments/branch-policies?apiVersion=2022-11-28#update-a-deployment-branch-policy + * + * @param string $username the username of the user who owns the repository + * @param string $repository the name of the repository + * @param string $environment the name of the environment. + * @param int $id the unique identifier of the branch policy. + * + * @return array information about the deployment branch policy + */ + public function update(string $username, string $repository, string $environment, int $id, array $params) + { + return $this->put('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/environments/'.rawurlencode($environment).'/deployment-branch-policies/'.$id, $params); + } + + /** + * Delete a deployment branch policy. + * + * @link https://docs.github.com/en/rest/deployments/branch-policies?apiVersion=2022-11-28#delete-a-deployment-branch-policy + * + * @param string $username the username of the user who owns the repository + * @param string $repository the name of the repository + * @param string $environment the name of the environment. + * @param int $id the unique identifier of the branch policy. + * + * @return mixed null on success, array on error with 'message' + */ + public function remove(string $username, string $repository, string $environment, int $id) + { + return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/environments/'.rawurlencode($environment).'/deployment-branch-policies/'.$id); + } +} diff --git a/lib/Github/Client.php b/lib/Github/Client.php index c1eaa501faf..56d68d59cec 100644 --- a/lib/Github/Client.php +++ b/lib/Github/Client.php @@ -181,11 +181,6 @@ public function api($name): AbstractApi $api = new Api\Deployment($this); break; - case 'environment': - case 'environments': - $api = new Api\Environment($this); - break; - case 'ent': case 'enterprise': $api = new Api\Enterprise($this); diff --git a/test/Github/Tests/Api/EnvironmentTest.php b/test/Github/Tests/Api/Deployment/EnvironmentsTest.php similarity index 92% rename from test/Github/Tests/Api/EnvironmentTest.php rename to test/Github/Tests/Api/Deployment/EnvironmentsTest.php index 3b6f6f417fe..ab761ab90cf 100644 --- a/test/Github/Tests/Api/EnvironmentTest.php +++ b/test/Github/Tests/Api/Deployment/EnvironmentsTest.php @@ -1,6 +1,8 @@ getApiMock(); + + $api->expects($this->once()) + ->method('post') + ->with('/repos/KnpLabs/php-github-api/environments/production/deployment-branch-policies'); + + $api->create('KnpLabs', 'php-github-api', 'production', [ + 'name' => 'name', + ]); + } + + /** + * @test + */ + public function shouldUpdatePolicy() + { + $api = $this->getApiMock(); + + $api->expects($this->once()) + ->method('put') + ->with('/repos/KnpLabs/php-github-api/environments/production/deployment-branch-policies/1'); + + $api->update('KnpLabs', 'php-github-api', 'production', 1, [ + 'name' => 'name', + ]); + } + + /** + * @test + */ + public function shouldGetAllPolicies() + { + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/repos/KnpLabs/php-github-api/environments/production/deployment-branch-policies'); + + $api->all('KnpLabs', 'php-github-api', 'production'); + } + + /** + * @test + */ + public function shouldShowPolicy() + { + $expectedValue = 'production'; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/repos/KnpLabs/php-github-api/environments/production/deployment-branch-policies/1') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->show('KnpLabs', 'php-github-api', 'production', 1)); + } + + /** + * @test + */ + public function shouldDeletePolicy() + { + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('/repos/KnpLabs/php-github-api/environments/production/deployment-branch-policies/1') + ->will($this->returnValue(null)); + + $this->assertNull($api->remove('KnpLabs', 'php-github-api', 'production', 1)); + } + + /** + * @return string + */ + protected function getApiClass() + { + return \Github\Api\Deployment\Policies::class; + } +} diff --git a/test/Github/Tests/Api/DeploymentTest.php b/test/Github/Tests/Api/DeploymentTest.php index 88e8c923ce1..8741ee625f7 100644 --- a/test/Github/Tests/Api/DeploymentTest.php +++ b/test/Github/Tests/Api/DeploymentTest.php @@ -118,6 +118,26 @@ public function shouldGetAllStatuses() $api->getStatuses('KnpLabs', 'php-github-api', 1); } + /** + * @test + */ + public function shouldGetEnvironmentsApiObject() + { + $api = $this->getApiMock(); + + $this->assertInstanceOf(\Github\Api\Deployment\Environments::class, $api->environments()); + } + + /** + * @test + */ + public function shouldGetPoliciesApiObject() + { + $api = $this->getApiMock(); + + $this->assertInstanceOf(\Github\Api\Deployment\Policies::class, $api->policies()); + } + /** * @return string */ From c68b874ac3267c3cc0544b726dbb4e49a72a9920 Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Fri, 10 Mar 2023 12:40:14 +0100 Subject: [PATCH 63/98] Update changelog for 3.11.0 release --- CHANGELOG-3.X.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG-3.X.md b/CHANGELOG-3.X.md index 3ec12940b20..b4f7fd83bdb 100644 --- a/CHANGELOG-3.X.md +++ b/CHANGELOG-3.X.md @@ -1,5 +1,18 @@ # Changelog +## 3.11.0 + +### Added +- Added environment variables & secrets ([Froxz](https://github.com/Froxz)) [#1104](https://github.com/KnpLabs/php-github-api/issues/1104) +- Added Org & Repository variables ([Froxz](https://github.com/Froxz)) [#1106](https://github.com/KnpLabs/php-github-api/issues/1106) +- Deployment branch policies ([Froxz](https://github.com/Froxz)) [#1108](https://github.com/KnpLabs/php-github-api/issues/1108) + +### Changed +- Test on PHP 8.2 ([GrahamCampbell](https://github.com/GrahamCampbell)) [#1105](https://github.com/KnpLabs/php-github-api/issues/1105) + +### Fixed +- Bugfix creating env ([Froxz](https://github.com/Froxz)) [#1107](https://github.com/KnpLabs/php-github-api/issues/1107) + ## 3.10.0 ### Added From b6fe0492dd7ed23b3424088abd9df81541a33671 Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Fri, 10 Mar 2023 12:02:27 +0000 Subject: [PATCH 64/98] Fixed branch alias --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 886b5993221..ef8d0a84f38 100644 --- a/composer.json +++ b/composer.json @@ -52,7 +52,7 @@ "extra": { "branch-alias": { "dev-2.x": "2.20.x-dev", - "dev-master": "3.10.x-dev" + "dev-master": "3.11.x-dev" } }, "config": { From 0e2399c93eb53be2243871c420eb1c6641cf0c7b Mon Sep 17 00:00:00 2001 From: Hari Darshan Gorana Date: Sun, 2 Apr 2023 23:51:46 +0530 Subject: [PATCH 65/98] feature #1101 feat: Support for Organization Runners (haridarshan, renovate[bot]) This PR was squashed before being merged into the 3.11.x-dev branch. Discussion ---------- Commits ------- 9d1ab1e7c9a5082fbb3e664b36194fa8426d9b57 feat: Support for Organization Runners 02bd5bc04e4bafab335af40fe453766816a89d21 fix: StyleCI ea2f3ececb90f030c066d687591d8e1c9166242a docs: Add Organization Self-Hosted runner doc 6df9b8fe3212f4dc60eaea090bc245c5a6afcbec docs: Add org runner link in README.md 70e7bbe13aa1cc692b832c390b897841eb51b655 Merge branch 'KnpLabs:master' into master 50a0ee1ceac5b8d86c555805454b43f6239146aa Merge branch 'master' into master 370927e8d59925a1bc807ebb16661378d63d2bdf Merge branch 'KnpLabs:master' into master 91c80431771f2440cce7d7aebf944fb66457daf9 chore: change argument of `all` method to `$parameters` array ca9467642c5230a8357d01f5bde840bdb87e9468 chore: fix StyleCi 5ff2a51502bd654d2c013be3abb1cb6c30511521 chore: minor fix 987a552a69ba8ba0e0387076e15365a21f04570a Add renovate.json 234a7a219772166a4d75234bb600cb5d0369fd80 Merge pull request #1 from haridarshan/renovate/configure be155523bd5368280c05584aa45879c446ef2a7c Update renovate.json 748354251877a9a5487dbf5ef10c2c845a9afe2f Delete renovate.json --- doc/README.md | 1 + .../actions/self_hosted_runners.md | 51 ++++++++ lib/Github/Api/Organization.php | 9 ++ .../Actions/SelfHostedRunners.php | 59 +++++++++ .../Actions/SelfHostedRunnersTest.php | 115 ++++++++++++++++++ test/Github/Tests/Api/OrganizationTest.php | 10 ++ 6 files changed, 245 insertions(+) create mode 100644 doc/organization/actions/self_hosted_runners.md create mode 100644 lib/Github/Api/Organization/Actions/SelfHostedRunners.php create mode 100644 test/Github/Tests/Api/Organization/Actions/SelfHostedRunnersTest.php diff --git a/doc/README.md b/doc/README.md index cecccfb90b7..ee453269d35 100644 --- a/doc/README.md +++ b/doc/README.md @@ -39,6 +39,7 @@ v3 APIs: * [Organization](organization.md) * [Members](organization/members.md) * [Teams](organization/teams.md) + * [Self hosted runners](organization/actions/self_hosted_runners.md) * [Secrets](organization/actions/secrets.md) * [Variables](organization/actions/variables.md) * [Projects](project/projects.md) diff --git a/doc/organization/actions/self_hosted_runners.md b/doc/organization/actions/self_hosted_runners.md new file mode 100644 index 00000000000..f6e915cdce5 --- /dev/null +++ b/doc/organization/actions/self_hosted_runners.md @@ -0,0 +1,51 @@ +## Organization / Actions / Self Hosted Runners API +[Back to the "Organization API"](../../organization.md) | [Back to the navigation](../../README.md) + +# List self-hosted runners for an Organization + +https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#list-self-hosted-runners-for-an-organization + +```php +$runners = $client->api('organization')->runners()->all('KnpLabs'); +``` + +# Get a self-hosted runner for an Organization + + https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#get-a-self-hosted-runner-for-an-organization + +```php +$runner = $client->api('organization')->runners()->show('KnpLabs', $runnerId); +``` + +# Delete a self-hosted runner from an Organization + +https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#delete-a-self-hosted-runner-from-an-organization + +```php +$client->api('organization')->runners()->remove('KnpLabs', $runnerId); +``` + +# List runner applications for an Organization + +https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#list-runner-applications-for-an-organization + +```php +$applications = $client->api('organization')->selfHostedRunners()->applications('KnpLabs'); +``` + +# List of all runners with Pagination + +```php +$api = $github->api('organization')->runners(); +$paginator = new Github\ResultPager($github); +$parameters = array('KnpLabs'); +$runners = $paginator->fetchAll($api, 'all', $parameters); + +do { + foreach ($runners['runners'] as $runner) { + // code + } + $runners = $paginator->fetchNext(); +} +while($paginator->hasNext()); +``` diff --git a/lib/Github/Api/Organization.php b/lib/Github/Api/Organization.php index d1997dabc7a..0756fbaefe4 100644 --- a/lib/Github/Api/Organization.php +++ b/lib/Github/Api/Organization.php @@ -3,6 +3,7 @@ namespace Github\Api; use Github\Api\Organization\Actions\Secrets; +use Github\Api\Organization\Actions\SelfHostedRunners; use Github\Api\Organization\Actions\Variables; use Github\Api\Organization\Hooks; use Github\Api\Organization\Members; @@ -140,4 +141,12 @@ public function issues($organization, array $params = [], $page = 1) { return $this->get('/orgs/'.rawurlencode($organization).'/issues', array_merge(['page' => $page], $params)); } + + /** + * @return SelfHostedRunners + */ + public function runners(): SelfHostedRunners + { + return new SelfHostedRunners($this->getClient()); + } } diff --git a/lib/Github/Api/Organization/Actions/SelfHostedRunners.php b/lib/Github/Api/Organization/Actions/SelfHostedRunners.php new file mode 100644 index 00000000000..f0b989f5751 --- /dev/null +++ b/lib/Github/Api/Organization/Actions/SelfHostedRunners.php @@ -0,0 +1,59 @@ +get('/orgs/'.rawurlencode($organization).'/actions/runners', $parameters); + } + + /** + * @link https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#get-a-self-hosted-runner-for-an-organization + * + * @param string $organization + * @param int $runnerId + * + * @return array|string + */ + public function show(string $organization, int $runnerId) + { + return $this->get('/orgs/'.rawurlencode($organization).'/actions/runners/'.$runnerId); + } + + /** + * @link https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#delete-a-self-hosted-runner-from-an-organization + * + * @param string $organization + * @param int $runnerId + * + * @return array|string + */ + public function remove(string $organization, int $runnerId) + { + return $this->delete('/orgs/'.rawurlencode($organization).'/actions/runners/'.$runnerId); + } + + /** + * @link https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#list-runner-applications-for-an-organization + * + * @param string $organization + * + * @return array|string + */ + public function applications(string $organization) + { + return $this->get('/orgs/'.rawurlencode($organization).'/actions/runners/downloads'); + } +} diff --git a/test/Github/Tests/Api/Organization/Actions/SelfHostedRunnersTest.php b/test/Github/Tests/Api/Organization/Actions/SelfHostedRunnersTest.php new file mode 100644 index 00000000000..e313a88202a --- /dev/null +++ b/test/Github/Tests/Api/Organization/Actions/SelfHostedRunnersTest.php @@ -0,0 +1,115 @@ + 1, + 'name' => 'MBP', + 'os' => 'macos', + 'status' => 'online', + ], + [ + 'id' => 2, + 'name' => 'iMac', + 'os' => 'macos', + 'status' => 'offline', + ], + ]; + + /** @var SelfHostedRunners|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('get') + ->with('/orgs/KnpLabs/actions/runners') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->all('KnpLabs')); + } + + /** + * @test + */ + public function shouldGetSelfHostedRunner() + { + $expectedArray = [ + 'id' => 1, + 'name' => 'MBP', + 'os' => 'macos', + 'status' => 'online', + ]; + + /** @var SelfHostedRunners|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('get') + ->with('/orgs/KnpLabs/actions/runners/1') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->show('KnpLabs', 1)); + } + + /** + * @test + */ + public function shouldRemoveSelfHostedRunner() + { + $expectedValue = 'response'; + + /** @var SelfHostedRunners|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('delete') + ->with('/orgs/KnpLabs/actions/runners/1') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->remove('KnpLabs', 1)); + } + + /** + * @test + */ + public function shouldGetSelfHostedRunnerApps() + { + $expectedArray = [ + ['os' => 'osx', 'architecture' => 'x64', 'download_url' => 'download_url', 'filename' => 'filename'], + ['os' => 'linux', 'architecture' => 'x64', 'download_url' => 'download_url', 'filename' => 'filename'], + ['os' => 'linux', 'architecture' => 'arm', 'download_url' => 'download_url', 'filename' => 'filename'], + ['os' => 'win', 'architecture' => 'x64', 'download_url' => 'download_url', 'filename' => 'filename'], + ['os' => 'linux', 'architecture' => 'arm64', 'download_url' => 'download_url', 'filename' => 'filename'], + ]; + + /** @var SelfHostedRunners|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('get') + ->with('/orgs/KnpLabs/actions/runners/downloads') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->applications('KnpLabs')); + } + + protected function getApiClass() + { + return SelfHostedRunners::class; + } +} diff --git a/test/Github/Tests/Api/OrganizationTest.php b/test/Github/Tests/Api/OrganizationTest.php index d13547bd663..2b920662691 100644 --- a/test/Github/Tests/Api/OrganizationTest.php +++ b/test/Github/Tests/Api/OrganizationTest.php @@ -88,6 +88,16 @@ public function shouldGetTeamsApiObject() $this->assertInstanceOf(\Github\Api\Organization\Teams::class, $api->teams()); } + /** + * @test + */ + public function shouldGetSelfHostedRunnersApiObject() + { + $api = $this->getApiMock(); + + $this->assertInstanceOf(\Github\Api\Organization\Actions\SelfHostedRunners::class, $api->runners()); + } + /** * @test */ From d005523078f4c31eabd964fd670f4c3f411d8c76 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 02:30:17 +0000 Subject: [PATCH 66/98] Bump actions/checkout from 3 to 4 Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/backwards-compatibility.yml | 2 +- .github/workflows/ci.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/backwards-compatibility.yml b/.github/workflows/backwards-compatibility.yml index cdb19e8dfe6..af330f06daa 100644 --- a/.github/workflows/backwards-compatibility.yml +++ b/.github/workflows/backwards-compatibility.yml @@ -8,7 +8,7 @@ jobs: name: "Roave BC check" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 31af3510052..7e09521e245 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2'] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -33,7 +33,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 with: From 2a3a71b784ab7552b9134d3abed4ec1d0a83fe44 Mon Sep 17 00:00:00 2001 From: Kevin Pfeifer Date: Fri, 29 Sep 2023 13:41:14 -0700 Subject: [PATCH 67/98] allow psr/http-message v2 --- composer.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index ef8d0a84f38..cbd418fbada 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "psr/cache": "^1.0|^2.0|^3.0", "psr/http-client-implementation": "^1.0", "psr/http-factory-implementation": "^1.0", - "psr/http-message": "^1.0", + "psr/http-message": "^1.0|^2.0", "symfony/polyfill-php80": "^1.17", "symfony/deprecation-contracts": "^2.2|^3.0" }, @@ -58,7 +58,8 @@ "config": { "allow-plugins": { "phpstan/extension-installer": true, - "composer/package-versions-deprecated": true + "composer/package-versions-deprecated": true, + "php-http/discovery": true } } } From 6fd7aacdabccb7489a72ac8df907721797b67f19 Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Sat, 30 Sep 2023 18:02:27 +0200 Subject: [PATCH 68/98] Update changelog for 3.12.0 release --- CHANGELOG-3.X.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG-3.X.md b/CHANGELOG-3.X.md index b4f7fd83bdb..a0cfebd17d8 100644 --- a/CHANGELOG-3.X.md +++ b/CHANGELOG-3.X.md @@ -1,5 +1,14 @@ # Changelog +## 3.12.0 + +### Added +- feat: Support for Organization Runners ([haridarshan](https://github.com/haridarshan), [renovate](https://github.com/renovate)[[bot](https://github.com/bot)]) [#1101](https://github.com/KnpLabs/php-github-api/issues/1101) +- allow psr/http-message v2 ([LordSimal](https://github.com/LordSimal)) [#1122](https://github.com/KnpLabs/php-github-api/issues/1122) + +### Changed +- Fixed branch alias ([GrahamCampbell](https://github.com/GrahamCampbell)) [#1109](https://github.com/KnpLabs/php-github-api/issues/1109) + ## 3.11.0 ### Added From b50fc1f40bb5ac50957d32c5732fcde9167ac30a Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Sat, 30 Sep 2023 18:42:04 +0200 Subject: [PATCH 69/98] Update changelog for 3.12.0 release --- CHANGELOG-3.X.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG-3.X.md b/CHANGELOG-3.X.md index a0cfebd17d8..e8f05acc917 100644 --- a/CHANGELOG-3.X.md +++ b/CHANGELOG-3.X.md @@ -9,6 +9,15 @@ ### Changed - Fixed branch alias ([GrahamCampbell](https://github.com/GrahamCampbell)) [#1109](https://github.com/KnpLabs/php-github-api/issues/1109) +## 3.12.0 + +### Added +- feat: Support for Organization Runners ([haridarshan](https://github.com/haridarshan), [renovate](https://github.com/renovate)[[bot](https://github.com/bot)]) [#1101](https://github.com/KnpLabs/php-github-api/issues/1101) +- allow psr/http-message v2 ([LordSimal](https://github.com/LordSimal)) [#1122](https://github.com/KnpLabs/php-github-api/issues/1122) + +### Changed +- Fixed branch alias ([GrahamCampbell](https://github.com/GrahamCampbell)) [#1109](https://github.com/KnpLabs/php-github-api/issues/1109) + ## 3.11.0 ### Added From 3bac0b8e80ad79699757e8a9bacef231ea2cd48e Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Sat, 30 Sep 2023 18:42:17 +0200 Subject: [PATCH 70/98] Update composer branch-alias --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index cbd418fbada..4145268c86a 100644 --- a/composer.json +++ b/composer.json @@ -52,7 +52,7 @@ "extra": { "branch-alias": { "dev-2.x": "2.20.x-dev", - "dev-master": "3.11.x-dev" + "dev-master": "3.12-dev" } }, "config": { From a02113fa03c78fa9fe31bc80e9967c1434b5e80c Mon Sep 17 00:00:00 2001 From: Markus Staab <47448731+clxmstaab@users.noreply.github.com> Date: Mon, 2 Oct 2023 11:59:10 +0200 Subject: [PATCH 71/98] CHANGELOG-3.X: fix release 3.12.0 mentioned twice --- CHANGELOG-3.X.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/CHANGELOG-3.X.md b/CHANGELOG-3.X.md index e8f05acc917..a0cfebd17d8 100644 --- a/CHANGELOG-3.X.md +++ b/CHANGELOG-3.X.md @@ -9,15 +9,6 @@ ### Changed - Fixed branch alias ([GrahamCampbell](https://github.com/GrahamCampbell)) [#1109](https://github.com/KnpLabs/php-github-api/issues/1109) -## 3.12.0 - -### Added -- feat: Support for Organization Runners ([haridarshan](https://github.com/haridarshan), [renovate](https://github.com/renovate)[[bot](https://github.com/bot)]) [#1101](https://github.com/KnpLabs/php-github-api/issues/1101) -- allow psr/http-message v2 ([LordSimal](https://github.com/LordSimal)) [#1122](https://github.com/KnpLabs/php-github-api/issues/1122) - -### Changed -- Fixed branch alias ([GrahamCampbell](https://github.com/GrahamCampbell)) [#1109](https://github.com/KnpLabs/php-github-api/issues/1109) - ## 3.11.0 ### Added From c1b440aa41eb285c297aee083fabcf1eb0bbe562 Mon Sep 17 00:00:00 2001 From: Serhii Petrov Date: Tue, 10 Oct 2023 10:39:54 +0300 Subject: [PATCH 72/98] Test against php 8.3 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7e09521e245..c1569cc97bf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2'] + php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3'] steps: - uses: actions/checkout@v4 From 113f6b3c52f98eb0a09a94397a84214c2343a706 Mon Sep 17 00:00:00 2001 From: Hari Darshan Gorana Date: Wed, 18 Oct 2023 01:52:42 +0530 Subject: [PATCH 73/98] feature #1114 feat: Secret Scanning Alerts (haridarshan) This PR was squashed before being merged into the 3.12-dev branch. Discussion ---------- Feature: - Secret Scanning Alerts Doc: - Secret Scanning doc Closes #1080 Commits ------- 98053b5af23849906cf25f00cb4e649fe0464e8d feat: Add Secret Scanning Alerts (Enterprise, Organization & Repository) 7b434a9752725a2533d6de089dafad942f13483e chore(styleci): apply styleci patch --- doc/README.md | 3 + doc/enterprise/secret-scanning.md | 10 ++ doc/organization/secret-scanning.md | 10 ++ doc/repo/secret-scanning.md | 37 +++++ lib/Github/Api/Enterprise.php | 9 ++ lib/Github/Api/Enterprise/SecretScanning.php | 21 +++ lib/Github/Api/Organization.php | 9 ++ .../Api/Organization/SecretScanning.php | 19 +++ lib/Github/Api/Repo.php | 9 ++ lib/Github/Api/Repository/SecretScanning.php | 64 +++++++++ .../Api/Enterprise/SecretScanningTest.php | 41 ++++++ .../Api/Organization/SecretScanningTest.php | 41 ++++++ .../Api/Repository/SecretScanningTest.php | 132 ++++++++++++++++++ 13 files changed, 405 insertions(+) create mode 100644 doc/enterprise/secret-scanning.md create mode 100644 doc/organization/secret-scanning.md create mode 100644 doc/repo/secret-scanning.md create mode 100644 lib/Github/Api/Enterprise/SecretScanning.php create mode 100644 lib/Github/Api/Organization/SecretScanning.php create mode 100644 lib/Github/Api/Repository/SecretScanning.php create mode 100644 test/Github/Tests/Api/Enterprise/SecretScanningTest.php create mode 100644 test/Github/Tests/Api/Organization/SecretScanningTest.php create mode 100644 test/Github/Tests/Api/Repository/SecretScanningTest.php diff --git a/doc/README.md b/doc/README.md index ee453269d35..37838e126a1 100644 --- a/doc/README.md +++ b/doc/README.md @@ -14,6 +14,7 @@ v3 APIs: * [Public keys](currentuser/publickeys.md) * [Memberships](currentuser/memberships.md) * [Enterprise](enterprise.md) + * [Secret Scanning Alert](enterprise/secret-scanning.md) * [Gists](gists.md) * [Comments](gists/comments.md) * GitData @@ -42,6 +43,7 @@ v3 APIs: * [Self hosted runners](organization/actions/self_hosted_runners.md) * [Secrets](organization/actions/secrets.md) * [Variables](organization/actions/variables.md) + * [Secret Scanning Alert](organization/secret-scanning.md) * [Projects](project/projects.md) * [Columns](project/columns.md) * [Cards](project/cards.md) @@ -74,6 +76,7 @@ v3 APIs: * [Stargazers](repo/stargazers.md) * [Statuses](repo/statuses.md) * [Tags](repo/tags.md) + * [Secret Scanning Alert](repo/secret-scanning.md) * [Search](search.md) * [Users](users.md) diff --git a/doc/enterprise/secret-scanning.md b/doc/enterprise/secret-scanning.md new file mode 100644 index 00000000000..ad7626c4709 --- /dev/null +++ b/doc/enterprise/secret-scanning.md @@ -0,0 +1,10 @@ +## Enterprise / Secret Scanning API +[Back to the "Enterprise API"](../../enterprise.md) | [Back to the navigation](../../README.md) + +# List secret-scanning alerts for an Enterprise + +https://docs.github.com/en/enterprise-server@3.5/rest/secret-scanning#list-secret-scanning-alerts-for-an-enterprise + +```php +$alerts = $client->api('enterprise')->secretScanning()->alerts('KnpLabs'); +``` diff --git a/doc/organization/secret-scanning.md b/doc/organization/secret-scanning.md new file mode 100644 index 00000000000..9ee5d4d972d --- /dev/null +++ b/doc/organization/secret-scanning.md @@ -0,0 +1,10 @@ +## Organization / Secret Scanning API +[Back to the "Organization API"](../../organization.md) | [Back to the navigation](../../README.md) + +# List secret-scanning alerts for an Organization + +https://docs.github.com/en/enterprise-server@3.5/rest/secret-scanning#list-secret-scanning-alerts-for-an-organization + +```php +$alerts = $client->api('organization')->secretScanning()->alerts('KnpLabs'); +``` diff --git a/doc/repo/secret-scanning.md b/doc/repo/secret-scanning.md new file mode 100644 index 00000000000..18f3ef20b28 --- /dev/null +++ b/doc/repo/secret-scanning.md @@ -0,0 +1,37 @@ +## Repository / Secret Scanning API +[Back to the "Repos API"](../../repos.md) | [Back to the navigation](../../README.md) + +# List secret-scanning alerts for a repository + +https://docs.github.com/en/enterprise-server@3.5/rest/secret-scanning#list-secret-scanning-alerts-for-a-repository + +```php +$alerts = $client->api('repos')->secretScanning()->alerts('KnpLabs', 'php-github-api'); +``` + +# Get a secret-scanning alert + +https://docs.github.com/en/enterprise-server@3.5/rest/secret-scanning#get-a-secret-scanning-alert + +```php +$alert = $client->api('repos')->secretScanning()->getAlert('KnpLabs', 'php-github-api', $alertNumber); +``` + +# Update a secret-scanning alert + +https://docs.github.com/en/enterprise-server@3.5/rest/secret-scanning#update-a-secret-scanning-alert + +```php +$client->api('repos')->secretScanning()->updateAlert('KnpLabs', 'php-github-api', $alertNumber, [ + 'state' => 'resolved', + 'resolution' => 'wont-fix' +]); +``` + +# List Locations for a secret-scanning alert + +https://docs.github.com/en/enterprise-server@3.5/rest/secret-scanning#list-locations-for-a-secret-scanning-alert + +```php +$locations = $client->api('repos')->secretScanning()->locations('KnpLabs', 'php-github-api', $alertNumber); +``` diff --git a/lib/Github/Api/Enterprise.php b/lib/Github/Api/Enterprise.php index b3daf95a177..62abaff577e 100644 --- a/lib/Github/Api/Enterprise.php +++ b/lib/Github/Api/Enterprise.php @@ -4,6 +4,7 @@ use Github\Api\Enterprise\License; use Github\Api\Enterprise\ManagementConsole; +use Github\Api\Enterprise\SecretScanning; use Github\Api\Enterprise\Stats; use Github\Api\Enterprise\UserAdmin; @@ -48,4 +49,12 @@ public function userAdmin() { return new UserAdmin($this->getClient()); } + + /** + * @return SecretScanning + */ + public function secretScanning(): SecretScanning + { + return new SecretScanning($this->getClient()); + } } diff --git a/lib/Github/Api/Enterprise/SecretScanning.php b/lib/Github/Api/Enterprise/SecretScanning.php new file mode 100644 index 00000000000..5d92c1d8a47 --- /dev/null +++ b/lib/Github/Api/Enterprise/SecretScanning.php @@ -0,0 +1,21 @@ +get('/enterprises/'.rawurlencode($enterprise).'/secret-scanning/alerts', $params); + } +} diff --git a/lib/Github/Api/Organization.php b/lib/Github/Api/Organization.php index 0756fbaefe4..ada7e66836d 100644 --- a/lib/Github/Api/Organization.php +++ b/lib/Github/Api/Organization.php @@ -8,6 +8,7 @@ use Github\Api\Organization\Hooks; use Github\Api\Organization\Members; use Github\Api\Organization\OutsideCollaborators; +use Github\Api\Organization\SecretScanning; use Github\Api\Organization\Teams; /** @@ -149,4 +150,12 @@ public function runners(): SelfHostedRunners { return new SelfHostedRunners($this->getClient()); } + + /** + * @return SecretScanning + */ + public function secretScanning(): SecretScanning + { + return new SecretScanning($this->getClient()); + } } diff --git a/lib/Github/Api/Organization/SecretScanning.php b/lib/Github/Api/Organization/SecretScanning.php new file mode 100644 index 00000000000..a323fd06fcc --- /dev/null +++ b/lib/Github/Api/Organization/SecretScanning.php @@ -0,0 +1,19 @@ +get('/orgs/'.rawurlencode($organization).'/secret-scanning/alerts', $params); + } +} diff --git a/lib/Github/Api/Repo.php b/lib/Github/Api/Repo.php index bcfe13edb73..d362830c2a7 100644 --- a/lib/Github/Api/Repo.php +++ b/lib/Github/Api/Repo.php @@ -24,6 +24,7 @@ use Github\Api\Repository\Projects; use Github\Api\Repository\Protection; use Github\Api\Repository\Releases; +use Github\Api\Repository\SecretScanning; use Github\Api\Repository\Stargazers; use Github\Api\Repository\Statuses; use Github\Api\Repository\Traffic; @@ -897,4 +898,12 @@ public function disableVulnerabilityAlerts(string $username, string $repository) { return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/vulnerability-alerts'); } + + /** + * @return SecretScanning + */ + public function secretScanning(): SecretScanning + { + return new SecretScanning($this->getClient()); + } } diff --git a/lib/Github/Api/Repository/SecretScanning.php b/lib/Github/Api/Repository/SecretScanning.php new file mode 100644 index 00000000000..968d352c3ec --- /dev/null +++ b/lib/Github/Api/Repository/SecretScanning.php @@ -0,0 +1,64 @@ +get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/secret-scanning/alerts', $params); + } + + /** + * @link https://docs.github.com/en/enterprise-server@3.5/rest/secret-scanning#get-a-secret-scanning-alert + * + * @param string $username + * @param string $repository + * @param int $alertNumber + * + * @return array|string + */ + public function getAlert(string $username, string $repository, int $alertNumber) + { + return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/secret-scanning/alerts/'.$alertNumber); + } + + /** + * @link https://docs.github.com/en/enterprise-server@3.5/rest/secret-scanning#update-a-secret-scanning-alert + * + * @param string $username + * @param string $repository + * @param int $alertNumber + * @param array $params + * + * @return array|string + */ + public function updateAlert(string $username, string $repository, int $alertNumber, array $params = []) + { + return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/secret-scanning/alerts/'.$alertNumber, $params); + } + + /** + * @link https://docs.github.com/en/enterprise-server@3.5/rest/secret-scanning#list-locations-for-a-secret-scanning-alert + * + * @param string $username + * @param string $repository + * @param int $alertNumber + * @param array $params + * + * @return array|string + */ + public function locations(string $username, string $repository, int $alertNumber, array $params = []) + { + return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/secret-scanning/alerts/'.$alertNumber.'/locations', $params); + } +} diff --git a/test/Github/Tests/Api/Enterprise/SecretScanningTest.php b/test/Github/Tests/Api/Enterprise/SecretScanningTest.php new file mode 100644 index 00000000000..cc5b14b6547 --- /dev/null +++ b/test/Github/Tests/Api/Enterprise/SecretScanningTest.php @@ -0,0 +1,41 @@ + 1, 'state' => 'resolved', 'resolution' => 'false_positive'], + ['number' => 2, 'state' => 'open', 'resolution' => null], + ['number' => 3, 'state' => 'resolved', 'resolution' => 'wont_fix'], + ['number' => 4, 'state' => 'resolved', 'resolution' => 'revoked'], + ]; + + /** @var SecretScanning|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('get') + ->with('/enterprises/KnpLabs/secret-scanning/alerts') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->alerts('KnpLabs', [ + 'state' => 'all', + ])); + } + + protected function getApiClass() + { + return \Github\Api\Enterprise\SecretScanning::class; + } +} diff --git a/test/Github/Tests/Api/Organization/SecretScanningTest.php b/test/Github/Tests/Api/Organization/SecretScanningTest.php new file mode 100644 index 00000000000..01b8f844007 --- /dev/null +++ b/test/Github/Tests/Api/Organization/SecretScanningTest.php @@ -0,0 +1,41 @@ + 1, 'state' => 'resolved', 'resolution' => 'false_positive'], + ['number' => 2, 'state' => 'open', 'resolution' => null], + ['number' => 3, 'state' => 'resolved', 'resolution' => 'wont_fix'], + ['number' => 4, 'state' => 'resolved', 'resolution' => 'revoked'], + ]; + + /** @var SecretScanning|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('get') + ->with('/orgs/KnpLabs/secret-scanning/alerts') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->alerts('KnpLabs', [ + 'state' => 'all', + ])); + } + + protected function getApiClass() + { + return \Github\Api\Organization\SecretScanning::class; + } +} diff --git a/test/Github/Tests/Api/Repository/SecretScanningTest.php b/test/Github/Tests/Api/Repository/SecretScanningTest.php new file mode 100644 index 00000000000..e2e98dfa879 --- /dev/null +++ b/test/Github/Tests/Api/Repository/SecretScanningTest.php @@ -0,0 +1,132 @@ + 1, 'state' => 'resolved', 'resolution' => 'false_positive'], + ['number' => 2, 'state' => 'open', 'resolution' => null], + ['number' => 3, 'state' => 'resolved', 'resolution' => 'wont_fix'], + ['number' => 4, 'state' => 'resolved', 'resolution' => 'revoked'], + ]; + + /** @var SecretScanning|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('get') + ->with('/repos/KnpLabs/php-github-api/secret-scanning/alerts') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->alerts('KnpLabs', 'php-github-api', [ + 'state' => 'all', + ])); + } + + /** + * @test + */ + public function shouldGetAlert() + { + $expectedArray = ['number' => 1, 'state' => 'resolved', 'resolution' => 'false_positive']; + + /** @var SecretScanning|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('get') + ->with('/repos/KnpLabs/php-github-api/secret-scanning/alerts/1') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->getAlert('KnpLabs', 'php-github-api', 1)); + } + + /** + * @test + */ + public function shouldUpdateAlert() + { + $expectedArray = ['number' => 1, 'state' => 'resolved', 'resolution' => 'false_positive']; + + /** @var SecretScanning|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('patch') + ->with('/repos/KnpLabs/php-github-api/secret-scanning/alerts/2') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->updateAlert('KnpLabs', 'php-github-api', 2, [ + 'state' => 'resolved', + 'resolution' => 'false_positive', + ])); + } + + /** + * @test + */ + public function shouldGetLocations() + { + $expectedArray = [ + [ + 'type' => 'commit', + 'details' => [ + 'path' => '/example/secrets.txt', + 'start_line' => 1, + 'end_line' => 1, + 'start_column' => 1, + 'end_column' => 64, + 'blob_sha' => 'af5626b4a114abcb82d63db7c8082c3c4756e51b', + 'blob_url' => 'https://HOSTNAME/repos/octocat/hello-world/git/blobs/af5626b4a114abcb82d63db7c8082c3c4756e51b', + 'commit_sha' => 'f14d7debf9775f957cf4f1e8176da0786431f72b', + 'commit_url' => 'https://HOSTNAME/repos/octocat/hello-world/git/commits/f14d7debf9775f957cf4f1e8176da0786431f72b', + ], + ], + [ + 'type' => 'commit', + 'details' => [ + 'path' => '/example/secrets.txt', + 'start_line' => 5, + 'end_line' => 5, + 'start_column' => 1, + 'end_column' => 64, + 'blob_sha' => '9def38117ab2d8355b982429aa924e268b4b0065', + 'blob_url' => 'https://HOSTNAME/repos/octocat/hello-world/git/blobs/9def38117ab2d8355b982429aa924e268b4b0065', + 'commit_sha' => '588483b99a46342501d99e3f10630cfc1219ea32', + 'commit_url' => 'https://HOSTNAME/repos/octocat/hello-world/git/commits/588483b99a46342501d99e3f10630cfc1219ea32', + ], + ], + ]; + + /** @var SecretScanning|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('get') + ->with('/repos/KnpLabs/php-github-api/secret-scanning/alerts/2/locations') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->locations('KnpLabs', 'php-github-api', 2, [ + 'per_page' => 10, + ])); + } + + protected function getApiClass() + { + return \Github\Api\Repository\SecretScanning::class; + } +} From 14e8eed991e82eed591395188f8ac39f4019c63f Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Tue, 17 Oct 2023 22:33:22 +0200 Subject: [PATCH 74/98] Switch roave bc-checker from docker to local setup --- .github/workflows/backwards-compatibility.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/backwards-compatibility.yml b/.github/workflows/backwards-compatibility.yml index af330f06daa..e6418f67a84 100644 --- a/.github/workflows/backwards-compatibility.yml +++ b/.github/workflows/backwards-compatibility.yml @@ -12,7 +12,13 @@ jobs: with: fetch-depth: 0 - - name: Roave BC Check - uses: docker://nyholm/roave-bc-check-ga + - name: Install PHP + uses: shivammathur/setup-php@v2 with: - args: --from=${{ github.event.pull_request.base.sha }} + php-version: '8.2' + + - name: Install roave/backward-compatibility-check + run: composer require --dev roave/backward-compatibility-check + + - name: Run roave/backward-compatibility-check + run: vendor/bin/roave-backward-compatibility-check --from=${{ github.event.pull_request.base.sha }} --format=github-actions From 10080cd18df0bda1f20dead87a025415ce1889af Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Tue, 17 Oct 2023 22:34:46 +0200 Subject: [PATCH 75/98] Apply style-ci fixes --- lib/Github/Api/CurrentUser/Watchers.php | 1 + lib/Github/HttpClient/Plugin/GithubExceptionThrower.php | 1 - test/Github/Tests/Api/Enterprise/StatsTest.php | 1 + test/Github/Tests/Api/Repository/AssetsTest.php | 1 + test/Github/Tests/Api/Repository/ContentsTest.php | 1 + test/Github/Tests/ClientTest.php | 3 +++ test/Github/Tests/Integration/IssueCommentTest.php | 3 +++ test/Github/Tests/Integration/RepoCommentTest.php | 3 +++ 8 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/Github/Api/CurrentUser/Watchers.php b/lib/Github/Api/CurrentUser/Watchers.php index 1ef35972c3f..79c04b5df36 100644 --- a/lib/Github/Api/CurrentUser/Watchers.php +++ b/lib/Github/Api/CurrentUser/Watchers.php @@ -8,6 +8,7 @@ * @link https://developer.github.com/v3/activity/watching/ * * @author Joseph Bielawski + * * @revised Felipe Valtl de Mello */ class Watchers extends AbstractApi diff --git a/lib/Github/HttpClient/Plugin/GithubExceptionThrower.php b/lib/Github/HttpClient/Plugin/GithubExceptionThrower.php index 78628c6740f..773c88501f2 100644 --- a/lib/Github/HttpClient/Plugin/GithubExceptionThrower.php +++ b/lib/Github/HttpClient/Plugin/GithubExceptionThrower.php @@ -88,7 +88,6 @@ public function handleRequest(RequestInterface $request, callable $next, callabl $errors[] = $error['message']; } break; - } } diff --git a/test/Github/Tests/Api/Enterprise/StatsTest.php b/test/Github/Tests/Api/Enterprise/StatsTest.php index d3a8a89883a..f97060e0a14 100644 --- a/test/Github/Tests/Api/Enterprise/StatsTest.php +++ b/test/Github/Tests/Api/Enterprise/StatsTest.php @@ -24,6 +24,7 @@ public function shouldShowStats() /** * @test + * * @dataProvider getTypes */ public function shouldShowStatsByType($type) diff --git a/test/Github/Tests/Api/Repository/AssetsTest.php b/test/Github/Tests/Api/Repository/AssetsTest.php index 029c10a380f..6cea75fe975 100644 --- a/test/Github/Tests/Api/Repository/AssetsTest.php +++ b/test/Github/Tests/Api/Repository/AssetsTest.php @@ -43,6 +43,7 @@ public function shouldGetSingleReleaseAsset() /** * @test + * * @requires PHP 5.3.4 */ public function shouldCreateReleaseAsset() diff --git a/test/Github/Tests/Api/Repository/ContentsTest.php b/test/Github/Tests/Api/Repository/ContentsTest.php index 1cc828c370d..ff89ffda8ac 100644 --- a/test/Github/Tests/Api/Repository/ContentsTest.php +++ b/test/Github/Tests/Api/Repository/ContentsTest.php @@ -71,6 +71,7 @@ public function getFailureStubsForExistsTest() * @param \PHPUnit_Framework_MockObject_Stub|\PHPUnit\Framework\MockObject\Stub\Exception * * @test + * * @dataProvider getFailureStubsForExistsTest */ public function shouldReturnFalseWhenFileIsNotFound($failureStub) diff --git a/test/Github/Tests/ClientTest.php b/test/Github/Tests/ClientTest.php index 74255c9a9f3..e5992284404 100644 --- a/test/Github/Tests/ClientTest.php +++ b/test/Github/Tests/ClientTest.php @@ -40,6 +40,7 @@ public function shouldPassHttpClientInterfaceToConstructor() /** * @test + * * @dataProvider getAuthenticationFullData */ public function shouldAuthenticateUsingAllGivenParameters($login, $password, $method) @@ -115,6 +116,7 @@ public function shouldThrowExceptionWhenAuthenticatingWithoutMethodSet() /** * @test + * * @dataProvider getApiClassesProvider */ public function shouldGetApiInstance($apiName, $class) @@ -126,6 +128,7 @@ public function shouldGetApiInstance($apiName, $class) /** * @test + * * @dataProvider getApiClassesProvider */ public function shouldGetMagicApiInstance($apiName, $class) diff --git a/test/Github/Tests/Integration/IssueCommentTest.php b/test/Github/Tests/Integration/IssueCommentTest.php index 3db9ce8bb46..0cb39a1f8e3 100644 --- a/test/Github/Tests/Integration/IssueCommentTest.php +++ b/test/Github/Tests/Integration/IssueCommentTest.php @@ -31,6 +31,7 @@ public function shouldRetrieveCommentsForIssue() /** * @test + * * @depends shouldRetrieveCommentsForIssue */ public function shouldRetrieveSingleComment($commentId) @@ -72,6 +73,7 @@ public function shouldCreateCommentForIssue() /** * @test + * * @depends shouldCreateCommentForIssue */ public function shouldUpdateCommentByCommentId($commentId) @@ -94,6 +96,7 @@ public function shouldUpdateCommentByCommentId($commentId) /** * @test + * * @depends shouldUpdateCommentByCommentId */ public function shouldRemoveCommentByCommentId($commentId) diff --git a/test/Github/Tests/Integration/RepoCommentTest.php b/test/Github/Tests/Integration/RepoCommentTest.php index b2d5dec528a..352dac4b7ff 100644 --- a/test/Github/Tests/Integration/RepoCommentTest.php +++ b/test/Github/Tests/Integration/RepoCommentTest.php @@ -70,6 +70,7 @@ public function shouldCreateCommentForCommit() /** * @test + * * @depends shouldCreateCommentForCommit */ public function shouldShowCommentByCommentId($commentId) @@ -91,6 +92,7 @@ public function shouldShowCommentByCommentId($commentId) /** * @test + * * @depends shouldShowCommentByCommentId */ public function shouldUpdateCommentByCommentId($commentId) @@ -113,6 +115,7 @@ public function shouldUpdateCommentByCommentId($commentId) /** * @test + * * @depends shouldUpdateCommentByCommentId */ public function shouldRemoveCommentByCommentId($commentId) From 67398b01830751871c3268711e821deeda6e5184 Mon Sep 17 00:00:00 2001 From: Hari Darshan Gorana Date: Wed, 18 Oct 2023 02:18:49 +0530 Subject: [PATCH 76/98] feature #1115 feat: User Migration (haridarshan) This PR was squashed before being merged into the 3.12-dev branch. Discussion ---------- Feature: - User Migrations Doc: - User Migrations doc Closes #795 Commits ------- 394817408ae5cc542815e181d6ee82f66c874740 feat: Add User Migrations Api fc5a76cd166cf3e3d42298383d8fca34faf8367b docs: Add migration list example with `ResultPager` and remove `per_page` 5389602c78e918781d8a3850de600244c87dea51 perf: remove `$params['repositories']` validation check 1bec9eb3ac20e46bece11563255bf9b35fa0370d test: remove `shouldNotStartMigration` test-case 69fc86460f80e3ca5db8181ffcaca7e2c27d550f chore(styleci): apply styleci patch --- doc/README.md | 1 + doc/user/migration.md | 79 ++++++++ lib/Github/Api/User.php | 10 + lib/Github/Api/User/Migration.php | 83 +++++++++ test/Github/Tests/Api/User/MigrationTest.php | 186 +++++++++++++++++++ 5 files changed, 359 insertions(+) create mode 100644 doc/user/migration.md create mode 100644 lib/Github/Api/User/Migration.php create mode 100644 test/Github/Tests/Api/User/MigrationTest.php diff --git a/doc/README.md b/doc/README.md index 37838e126a1..35929c2afc3 100644 --- a/doc/README.md +++ b/doc/README.md @@ -79,6 +79,7 @@ v3 APIs: * [Secret Scanning Alert](repo/secret-scanning.md) * [Search](search.md) * [Users](users.md) + * [Migrations](user/migration.md) Additional features: diff --git a/doc/user/migration.md b/doc/user/migration.md new file mode 100644 index 00000000000..a2c3eb14c5e --- /dev/null +++ b/doc/user/migration.md @@ -0,0 +1,79 @@ +## User / Migrations API +[Back to the "Users API"](../../users.md) | [Back to the navigation](../../README.md) + +# List user migrations + +https://docs.github.com/en/rest/migrations/users?apiVersion=2022-11-28#list-user-migrations + +```php +$api = $github->api('user')->migration(); +$paginator = new Github\ResultPager($github); +$parameters = []; +$migrations = $paginator->fetchAll($api, 'list', $parameters); + +do { + foreach ($migrations as $migration) { + // do something + } + $migrations = $paginator->fetchNext(); +} +while($paginator->hasNext()); +``` + +# Start a User Migration + +https://docs.github.com/en/rest/migrations/users?apiVersion=2022-11-28#start-a-user-migration + +```php +$client->users()->migration()->start([ + 'repositories' => [ + 'KnpLabs/php-github-api' + ], + 'lock_repositories' => true, + 'exclude_metadata' => false, + 'exclude_git_data' => false, + 'exclude_attachments' => true, + 'exclude_releases' => false, + 'exclude_owner_projects' => true, + 'org_metadata_only' => false, + 'exclude' => [ + 'Exclude attributes from the API response to improve performance' + ] +]); +``` + +# Get a User Migration Status + +https://docs.github.com/en/rest/migrations/users?apiVersion=2022-11-28#get-a-user-migration-status + +```php +$status = $client->user()->migration()->status(12, [ + 'exclude' => [ + 'exclude attributes' + ] +]); +``` + +# Delete a User Migration Archive + +https://docs.github.com/en/rest/migrations/users?apiVersion=2022-11-28#delete-a-user-migration-archive + +```php +$client->user()->migration()->deleteArchive(12); +``` + +# Unlock a User Repository + +https://docs.github.com/en/rest/migrations/users?apiVersion=2022-11-28#unlock-a-user-repository + +```php +$client->user()->migration()->unlockRepo(12, 'php-github-api'); +``` + +# List repositories for a User Migration + +https://docs.github.com/en/rest/migrations/users?apiVersion=2022-11-28#list-repositories-for-a-user-migration + +```php +$repos = $client->user()->migration()->repos(2); +``` diff --git a/lib/Github/Api/User.php b/lib/Github/Api/User.php index c1ccc89e8c1..d436a2b835e 100644 --- a/lib/Github/Api/User.php +++ b/lib/Github/Api/User.php @@ -2,6 +2,8 @@ namespace Github\Api; +use Github\Api\User\Migration; + /** * Searching users, getting user information. * @@ -246,4 +248,12 @@ public function events(string $username) { return $this->get('/users/'.rawurlencode($username).'/events'); } + + /** + * @return Migration + */ + public function migration(): Migration + { + return new Migration($this->getClient()); + } } diff --git a/lib/Github/Api/User/Migration.php b/lib/Github/Api/User/Migration.php new file mode 100644 index 00000000000..4e1b61ca244 --- /dev/null +++ b/lib/Github/Api/User/Migration.php @@ -0,0 +1,83 @@ +get('/user/migrations', $params); + } + + /** + * @link https://docs.github.com/en/rest/migrations/users?apiVersion=2022-11-28#start-a-user-migration + * + * @param array $params + * + * @return array|string + */ + public function start(array $params) + { + return $this->post('/user/migrations', $params); + } + + /** + * @link https://docs.github.com/en/rest/migrations/users?apiVersion=2022-11-28#get-a-user-migration-status + * + * @param int $migrationId + * @param array $params + * + * @return array|string + */ + public function status(int $migrationId, array $params = []) + { + return $this->get('/user/migrations/'.$migrationId, $params); + } + + /** + * @link https://docs.github.com/en/rest/migrations/users?apiVersion=2022-11-28#delete-a-user-migration-archive + * + * @param int $migrationId + * + * @return array|string + */ + public function deleteArchive(int $migrationId) + { + return $this->delete('/user/migrations/'.$migrationId.'/archive'); + } + + /** + * @link https://docs.github.com/en/rest/migrations/users?apiVersion=2022-11-28#unlock-a-user-repository + * + * @param int $migrationId + * @param string $repository + * + * @return array|string + */ + public function unlockRepo(int $migrationId, string $repository) + { + return $this->delete('/user/migrations/'.$migrationId.'/repos/'.rawurlencode($repository).'/lock'); + } + + /** + * @link https://docs.github.com/en/rest/migrations/users?apiVersion=2022-11-28#list-repositories-for-a-user-migration + * + * @param int $migrationId + * @param array $params + * + * @return array|string + */ + public function repos(int $migrationId, array $params = []) + { + return $this->get('/user/migrations/'.$migrationId.'/repositories', $params); + } +} diff --git a/test/Github/Tests/Api/User/MigrationTest.php b/test/Github/Tests/Api/User/MigrationTest.php new file mode 100644 index 00000000000..3ee1620a3ae --- /dev/null +++ b/test/Github/Tests/Api/User/MigrationTest.php @@ -0,0 +1,186 @@ + 79, + 'state' => 'pending', + 'lock_repositories' => true, + 'repositories' => [ + [ + 'id' => 1296269, + 'name' => 'Hello-World', + 'full_name' => 'octocat/Hello-World', + ], + ], + ], + [ + 'id' => 2, + 'name' => 'pending', + 'lock_repositories' => false, + 'repositories' => [ + [ + 'id' => 123, + 'name' => 'php-github-api', + 'full_name' => 'KnpLabs/php-github-api', + ], + ], + ], + ]; + + /** @var Migration|MockObject $api */ + $api = $this->getApiMock(); + + $api + ->expects($this->once()) + ->method('get') + ->with('/user/migrations') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->list()); + } + + /** + * @test + */ + public function shouldStartMigration() + { + $expectedArray = [ + 'id' => 79, + 'state' => 'pending', + 'lock_repositories' => true, + 'repositories' => [ + [ + 'id' => 1296269, + 'name' => 'Hello-World', + 'full_name' => 'octocat/Hello-World', + ], + ], + ]; + + /** @var Migration|MockObject $api */ + $api = $this->getApiMock(); + + $api->expects($this->once()) + ->method('post') + ->with('/user/migrations') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->start([ + 'lock_repositories' => true, + 'repositories' => [ + 'KnpLabs/php-github-api', + ], + ])); + } + + /** + * @test + */ + public function shouldGetMigrationStatus() + { + $expectedArray = [ + 'id' => 79, + 'state' => 'exported', + 'lock_repositories' => true, + 'repositories' => [ + [ + 'id' => 1296269, + 'name' => 'Hello-World', + 'full_name' => 'octocat/Hello-World', + ], + ], + ]; + + /** @var Migration|MockObject $api */ + $api = $this->getApiMock(); + + $api->expects($this->once()) + ->method('get') + ->with('/user/migrations/79') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->status(79)); + } + + /** + * @test + */ + public function shouldDeleteMigrationArchive() + { + /** @var Migration|MockObject $api */ + $api = $this->getApiMock(); + + $api->expects($this->once()) + ->method('delete') + ->with('/user/migrations/79/archive') + ->will($this->returnValue(204)); + + $this->assertEquals(204, $api->deleteArchive(79)); + } + + /** + * @test + */ + public function shouldUnlockUserRepo() + { + /** @var Migration|MockObject $api */ + $api = $this->getApiMock(); + + $api->expects($this->once()) + ->method('delete') + ->with('/user/migrations/79/repos/php-github-api/lock') + ->will($this->returnValue(204)); + + $this->assertEquals(204, $api->unlockRepo(79, 'php-github-api')); + } + + /** + * @test + */ + public function shouldListRepos() + { + $expectedArray = [ + [ + 'id' => 1296269, + 'name' => 'Hello-World', + 'full_name' => 'test/Hello-World', + ], + [ + 'id' => 234324, + 'name' => 'Hello-World2', + 'full_name' => 'test/Hello-World2', + ], + ]; + + /** @var Migration|MockObject $api */ + $api = $this->getApiMock(); + + $api->expects($this->once()) + ->method('get') + ->with('/user/migrations/79/repositories') + ->will($this->returnValue($expectedArray)); + + $this->assertEquals($expectedArray, $api->repos(79)); + } + + /** + * @return string + */ + protected function getApiClass() + { + return \Github\Api\User\Migration::class; + } +} From 9d19af334fb3baa2e1ae54c6ec0dcf09c6e5ab61 Mon Sep 17 00:00:00 2001 From: Mathieu De Zutter Date: Sun, 19 Nov 2023 21:54:17 +0100 Subject: [PATCH 77/98] bug #1126 Fix detection of secondary rate limit (mathieudz) This PR was squashed before being merged into the 3.12-dev branch. Discussion ---------- Actual error message is "You have exceeded a secondary rate limit and have been temporarily blocked from content creation. Please retry your request again later. If you reach out to GitHub Support for help, please include the request ID [...]" Commits ------- 661fccba2042061a3d9e27da72a4abb110070db1 Fix detection of secondary rate limit 7d8aeb65be07542af91763f5a0dcede351390929 Update secondary rate limit test with new message --- lib/Github/HttpClient/Plugin/GithubExceptionThrower.php | 2 +- .../Tests/HttpClient/Plugin/GithubExceptionThrowerTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Github/HttpClient/Plugin/GithubExceptionThrower.php b/lib/Github/HttpClient/Plugin/GithubExceptionThrower.php index 773c88501f2..9479aaaf2be 100644 --- a/lib/Github/HttpClient/Plugin/GithubExceptionThrower.php +++ b/lib/Github/HttpClient/Plugin/GithubExceptionThrower.php @@ -128,7 +128,7 @@ public function handleRequest(RequestInterface $request, callable $next, callabl } $reset = (int) ResponseMediator::getHeader($response, 'X-RateLimit-Reset'); - if ((403 === $response->getStatusCode()) && 0 < $reset && isset($content['message']) && (0 === strpos($content['message'], 'You have exceeded a secondary rate limit.'))) { + if ((403 === $response->getStatusCode()) && 0 < $reset && isset($content['message']) && (0 === strpos($content['message'], 'You have exceeded a secondary rate limit'))) { $limit = (int) ResponseMediator::getHeader($response, 'X-RateLimit-Limit'); throw new ApiLimitExceedException($limit, $reset); diff --git a/test/Github/Tests/HttpClient/Plugin/GithubExceptionThrowerTest.php b/test/Github/Tests/HttpClient/Plugin/GithubExceptionThrowerTest.php index f8090ef622c..b2541ec0942 100644 --- a/test/Github/Tests/HttpClient/Plugin/GithubExceptionThrowerTest.php +++ b/test/Github/Tests/HttpClient/Plugin/GithubExceptionThrowerTest.php @@ -103,7 +103,7 @@ public static function responseProvider() ], json_encode( [ - 'message' => 'You have exceeded a secondary rate limit. Please wait a few minutes before you try again.', + 'message' => 'You have exceeded a secondary rate limit and have been temporarily blocked from content creation. Please retry your request again later. If you reach out to GitHub Support for help, please include the request ID #xxxxxxx.', ] ) ), From 47024f3483520c0fafdfc5c10d2a20d87b4c7ceb Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Sun, 19 Nov 2023 22:08:19 +0100 Subject: [PATCH 78/98] Update changelog for 3.13.0 release --- CHANGELOG-3.X.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG-3.X.md b/CHANGELOG-3.X.md index a0cfebd17d8..b396856bca9 100644 --- a/CHANGELOG-3.X.md +++ b/CHANGELOG-3.X.md @@ -1,5 +1,18 @@ # Changelog +## 3.13.0 + +### Added +- Test against php 8.3 ([sergiy-petrov](https://github.com/sergiy-petrov)) [#1124](https://github.com/KnpLabs/php-github-api/issues/1124) +- feat: Secret Scanning Alerts ([haridarshan](https://github.com/haridarshan)) [#1114](https://github.com/KnpLabs/php-github-api/issues/1114) +- feat: User Migration ([haridarshan](https://github.com/haridarshan)) [#1115](https://github.com/KnpLabs/php-github-api/issues/1115) + +### Changed +- General chores ([acrobat](https://github.com/acrobat)) [#1125](https://github.com/KnpLabs/php-github-api/issues/1125) + +### Fixed +- Fix detection of secondary rate limit ([mathieudz](https://github.com/mathieudz)) [#1126](https://github.com/KnpLabs/php-github-api/issues/1126) + ## 3.12.0 ### Added From 9afaf87f99c6c2acde80b6925d1b97a70ece8cb5 Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Sun, 19 Nov 2023 22:08:24 +0100 Subject: [PATCH 79/98] Update composer branch-alias --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 4145268c86a..957eedad381 100644 --- a/composer.json +++ b/composer.json @@ -52,7 +52,7 @@ "extra": { "branch-alias": { "dev-2.x": "2.20.x-dev", - "dev-master": "3.12-dev" + "dev-master": "3.13-dev" } }, "config": { From 6f5b61de47696fea572cb00a776484821ebf8e62 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 02:47:59 +0000 Subject: [PATCH 80/98] Bump ramsey/composer-install from 2 to 3 Bumps [ramsey/composer-install](https://github.com/ramsey/composer-install) from 2 to 3. - [Release notes](https://github.com/ramsey/composer-install/releases) - [Commits](https://github.com/ramsey/composer-install/compare/v2...v3) --- updated-dependencies: - dependency-name: ramsey/composer-install dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c1569cc97bf..923f2ce49c9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: coverage: none - name: Install Composer Dependencies - uses: ramsey/composer-install@v2 + uses: ramsey/composer-install@v3 - name: Run phpunit run: vendor/bin/phpunit --verbose @@ -41,7 +41,7 @@ jobs: coverage: none - name: Install Composer Dependencies - uses: ramsey/composer-install@v2 + uses: ramsey/composer-install@v3 - name: Run phpstan run: vendor/bin/phpstan analyse --no-progress From 680eea2ce37588cc4e5776131e4b170d53da74b8 Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Sun, 17 Mar 2024 20:56:20 +0000 Subject: [PATCH 81/98] Allow php-http/cache-plugin v2 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 957eedad381..826e15c49b8 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "require": { "php": "^7.2.5 || ^8.0", "ext-json": "*", - "php-http/cache-plugin": "^1.7.1", + "php-http/cache-plugin": "^1.7.1|^2.0", "php-http/client-common": "^2.3", "php-http/discovery": "^1.12", "php-http/httplug": "^2.2", From 16235d0eaffe5100492e6c788c58346100b2d734 Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Tue, 19 Mar 2024 15:52:45 +0100 Subject: [PATCH 82/98] Update changelog for 3.14.0 release --- CHANGELOG-3.X.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG-3.X.md b/CHANGELOG-3.X.md index b396856bca9..44afe4fc8cb 100644 --- a/CHANGELOG-3.X.md +++ b/CHANGELOG-3.X.md @@ -1,5 +1,10 @@ # Changelog +## 3.14.0 + +### Added +- Allow php-http/cache-plugin v2 ([GrahamCampbell](https://github.com/GrahamCampbell)) [#1134](https://github.com/KnpLabs/php-github-api/issues/1134) + ## 3.13.0 ### Added From 4fca25fb5d5be992178b99a0ee8e4395030e89e4 Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Tue, 19 Mar 2024 15:52:51 +0100 Subject: [PATCH 83/98] Update composer branch-alias --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 826e15c49b8..f3d598d6940 100644 --- a/composer.json +++ b/composer.json @@ -52,7 +52,7 @@ "extra": { "branch-alias": { "dev-2.x": "2.20.x-dev", - "dev-master": "3.13-dev" + "dev-master": "3.14-dev" } }, "config": { From 4afaaf9936c05f82016fa68e3ebec1e2dff65a47 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Sun, 24 Mar 2024 14:10:30 +0000 Subject: [PATCH 84/98] Apply fixes from StyleCI --- lib/Github/Api/Issue/Labels.php | 2 +- lib/Github/Api/Issue/Milestones.php | 6 +- lib/Github/Api/Repo.php | 14 ++--- lib/Github/Api/Repository/Contents.php | 4 +- .../Tests/Api/CurrentUser/MembershipsTest.php | 18 +++--- test/Github/Tests/Api/GistsTest.php | 4 +- test/Github/Tests/Api/GitData/TreesTest.php | 10 ++-- test/Github/Tests/Api/GraphQLTest.php | 4 +- test/Github/Tests/Api/IssueTest.php | 10 ++-- test/Github/Tests/Api/PullRequestTest.php | 28 ++++----- test/Github/Tests/Api/RepoTest.php | 60 +++++++++---------- .../Tests/Api/Repository/ContentsTest.php | 20 +++---- .../Github/Tests/Api/Repository/PagesTest.php | 2 +- test/Github/Tests/Functional/CacheTest.php | 4 +- .../Message/ResponseMediatorTest.php | 8 +-- test/Github/Tests/Mock/PaginatedResponse.php | 2 +- test/Github/Tests/ResultPagerTest.php | 2 +- 17 files changed, 99 insertions(+), 99 deletions(-) diff --git a/lib/Github/Api/Issue/Labels.php b/lib/Github/Api/Issue/Labels.php index d719578d943..3cfad23d5b0 100644 --- a/lib/Github/Api/Issue/Labels.php +++ b/lib/Github/Api/Issue/Labels.php @@ -108,7 +108,7 @@ public function deleteLabel($username, $repository, $label) public function update($username, $repository, $label, $newName, $color) { $params = [ - 'name' => $newName, + 'name' => $newName, 'color' => $color, ]; diff --git a/lib/Github/Api/Issue/Milestones.php b/lib/Github/Api/Issue/Milestones.php index 4cf2a3d5518..fe9f2296dd6 100644 --- a/lib/Github/Api/Issue/Milestones.php +++ b/lib/Github/Api/Issue/Milestones.php @@ -36,9 +36,9 @@ public function all($username, $repository, array $params = []) } return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/milestones', array_merge([ - 'page' => 1, - 'state' => 'open', - 'sort' => 'due_date', + 'page' => 1, + 'state' => 'open', + 'sort' => 'due_date', 'direction' => 'asc', ], $params)); } diff --git a/lib/Github/Api/Repo.php b/lib/Github/Api/Repo.php index d362830c2a7..5653ae4c152 100644 --- a/lib/Github/Api/Repo.php +++ b/lib/Github/Api/Repo.php @@ -204,14 +204,14 @@ public function create( $path = null !== $organization ? '/orgs/'.$organization.'/repos' : '/user/repos'; $parameters = [ - 'name' => $name, - 'description' => $description, - 'homepage' => $homepage, - 'private' => ($visibility ?? ($public ? 'public' : 'private')) === 'private', - 'has_issues' => $hasIssues, - 'has_wiki' => $hasWiki, + 'name' => $name, + 'description' => $description, + 'homepage' => $homepage, + 'private' => ($visibility ?? ($public ? 'public' : 'private')) === 'private', + 'has_issues' => $hasIssues, + 'has_wiki' => $hasWiki, 'has_downloads' => $hasDownloads, - 'auto_init' => $autoInit, + 'auto_init' => $autoInit, 'has_projects' => $hasProjects, ]; diff --git a/lib/Github/Api/Repository/Contents.php b/lib/Github/Api/Repository/Contents.php index 4f9693dcbe1..b6e170ebce0 100644 --- a/lib/Github/Api/Repository/Contents.php +++ b/lib/Github/Api/Repository/Contents.php @@ -181,7 +181,7 @@ public function update($username, $repository, $path, $content, $message, $sha, $parameters = [ 'content' => base64_encode($content), 'message' => $message, - 'sha' => $sha, + 'sha' => $sha, ]; if (null !== $branch) { @@ -221,7 +221,7 @@ public function rm($username, $repository, $path, $message, $sha, $branch = null $parameters = [ 'message' => $message, - 'sha' => $sha, + 'sha' => $sha, ]; if (null !== $branch) { diff --git a/test/Github/Tests/Api/CurrentUser/MembershipsTest.php b/test/Github/Tests/Api/CurrentUser/MembershipsTest.php index d3d8e1cbc77..aef9f374c23 100644 --- a/test/Github/Tests/Api/CurrentUser/MembershipsTest.php +++ b/test/Github/Tests/Api/CurrentUser/MembershipsTest.php @@ -15,21 +15,21 @@ public function shouldGetMemberships() [ 'organization' => [ 'login' => 'octocat', - 'id' => 1, + 'id' => 1, ], - 'user' => [ + 'user' => [ 'login' => 'defunkt', - 'id' => 3, + 'id' => 3, ], ], [ 'organization' => [ 'login' => 'invitocat', - 'id' => 2, + 'id' => 2, ], - 'user' => [ + 'user' => [ 'login' => 'defunkt', - 'id' => 3, + 'id' => 3, ], ], ]; @@ -51,11 +51,11 @@ public function shouldGetMembershipsForOrganization() $expectedValue = [ 'organization' => [ 'login' => 'invitocat', - 'id' => 2, + 'id' => 2, ], - 'user' => [ + 'user' => [ 'login' => 'defunkt', - 'id' => 3, + 'id' => 3, ], ]; diff --git a/test/Github/Tests/Api/GistsTest.php b/test/Github/Tests/Api/GistsTest.php index 093af712911..ff4673e4082 100644 --- a/test/Github/Tests/Api/GistsTest.php +++ b/test/Github/Tests/Api/GistsTest.php @@ -227,10 +227,10 @@ public function shouldUpdateGist() 'files' => [ 'filename.txt' => [ 'filename' => 'new_name.txt', - 'content' => 'content', + 'content' => 'content', ], 'filename_new.txt' => [ - 'content' => 'content new', + 'content' => 'content new', ], ], ]; diff --git a/test/Github/Tests/Api/GitData/TreesTest.php b/test/Github/Tests/Api/GitData/TreesTest.php index 901af559e24..0b415f1fb1c 100644 --- a/test/Github/Tests/Api/GitData/TreesTest.php +++ b/test/Github/Tests/Api/GitData/TreesTest.php @@ -35,13 +35,13 @@ public function shouldCreateTreeUsingSha() 'path' => 'path', 'mode' => 'mode', 'type' => 'type', - 'sha' => '1234', + 'sha' => '1234', ], [ 'path' => 'htap', 'mode' => 'edom', 'type' => 'epyt', - 'sha' => '4321', + 'sha' => '4321', ], ], ]; @@ -118,7 +118,7 @@ public function shouldNotCreateTreeWithoutPathParam() 'tree' => [ 'mode' => 'mode', 'type' => 'type', - 'content' => 'content', + 'content' => 'content', ], ]; @@ -139,7 +139,7 @@ public function shouldNotCreateTreeWithoutModeParam() 'tree' => [ 'path' => 'path', 'type' => 'type', - 'content' => 'content', + 'content' => 'content', ], ]; @@ -160,7 +160,7 @@ public function shouldNotCreateTreeWithoutTypeParam() 'tree' => [ 'path' => 'path', 'mode' => 'mode', - 'content' => 'content', + 'content' => 'content', ], ]; diff --git a/test/Github/Tests/Api/GraphQLTest.php b/test/Github/Tests/Api/GraphQLTest.php index 042cb014a50..b241cc5ae90 100644 --- a/test/Github/Tests/Api/GraphQLTest.php +++ b/test/Github/Tests/Api/GraphQLTest.php @@ -13,7 +13,7 @@ public function shouldTestGraphQL() $api->expects($this->once()) ->method('post') - ->with($this->equalTo('/graphql'), $this->equalTo(['query'=>'bar'])) + ->with($this->equalTo('/graphql'), $this->equalTo(['query' => 'bar'])) ->will($this->returnValue('foo')); $result = $api->execute('bar'); @@ -44,7 +44,7 @@ public function shouldJSONEncodeGraphQLVariables() $api->expects($this->once()) ->method('post') ->with('/graphql', $this->equalTo([ - 'query'=>'bar', + 'query' => 'bar', 'variables' => '{"variable":"foo"}', ])); diff --git a/test/Github/Tests/Api/IssueTest.php b/test/Github/Tests/Api/IssueTest.php index bc8b80fdf5e..a151076ce1f 100644 --- a/test/Github/Tests/Api/IssueTest.php +++ b/test/Github/Tests/Api/IssueTest.php @@ -35,10 +35,10 @@ public function shouldGetIssuesUsingAdditionalParameters() $data = [ 'state' => 'open', 'milestone' => '*', - 'assignee' => 'l3l0', + 'assignee' => 'l3l0', 'mentioned' => 'l3l0', - 'labels' => 'bug,@high', - 'sort' => 'created', + 'labels' => 'bug,@high', + 'sort' => 'created', 'direction' => 'asc', ]; $sentData = $data + [ @@ -77,7 +77,7 @@ public function shouldCreateIssue() { $data = [ 'title' => 'some title', - 'body' => 'some body', + 'body' => 'some body', ]; $api = $this->getApiMock(); @@ -95,7 +95,7 @@ public function shouldNotCreateIssueWithoutTitle() { $this->expectException(MissingArgumentException::class); $data = [ - 'body' => 'some body', + 'body' => 'some body', ]; $api = $this->getApiMock(); diff --git a/test/Github/Tests/Api/PullRequestTest.php b/test/Github/Tests/Api/PullRequestTest.php index fe5b87c9d6d..54cc34f55e0 100644 --- a/test/Github/Tests/Api/PullRequestTest.php +++ b/test/Github/Tests/Api/PullRequestTest.php @@ -243,10 +243,10 @@ public function shouldMergePullRequestWithMergeMethod() public function shouldCreatePullRequestUsingTitle() { $data = [ - 'base' => 'master', - 'head' => 'virtualtestbranch', + 'base' => 'master', + 'head' => 'virtualtestbranch', 'title' => 'TITLE: Testing pull-request creation from PHP Github API', - 'body' => 'BODY: Testing pull-request creation from PHP Github API', + 'body' => 'BODY: Testing pull-request creation from PHP Github API', ]; $api = $this->getApiMock(); @@ -263,8 +263,8 @@ public function shouldCreatePullRequestUsingTitle() public function shouldCreatePullRequestUsingIssueId() { $data = [ - 'base' => 'master', - 'head' => 'virtualtestbranch', + 'base' => 'master', + 'head' => 'virtualtestbranch', 'issue' => 25, ]; @@ -282,10 +282,10 @@ public function shouldCreatePullRequestUsingIssueId() public function shouldCreateDraftPullRequest() { $data = [ - 'base' => 'master', - 'head' => 'virtualtestbranch', + 'base' => 'master', + 'head' => 'virtualtestbranch', 'title' => 'TITLE: Testing draft pull-request creation from PHP Github API', - 'body' => 'BODY: Testing draft pull-request creation from PHP Github API', + 'body' => 'BODY: Testing draft pull-request creation from PHP Github API', 'draft' => 'true', ]; @@ -304,9 +304,9 @@ public function shouldNotCreatePullRequestWithoutBase() { $this->expectException(MissingArgumentException::class); $data = [ - 'head' => 'virtualtestbranch', + 'head' => 'virtualtestbranch', 'title' => 'TITLE: Testing pull-request creation from PHP Github API', - 'body' => 'BODY: Testing pull-request creation from PHP Github API', + 'body' => 'BODY: Testing pull-request creation from PHP Github API', ]; $api = $this->getApiMock(); @@ -323,9 +323,9 @@ public function shouldNotCreatePullRequestWithoutHead() { $this->expectException(MissingArgumentException::class); $data = [ - 'base' => 'master', + 'base' => 'master', 'title' => 'TITLE: Testing pull-request creation from PHP Github API', - 'body' => 'BODY: Testing pull-request creation from PHP Github API', + 'body' => 'BODY: Testing pull-request creation from PHP Github API', ]; $api = $this->getApiMock(); @@ -342,8 +342,8 @@ public function shouldNotCreatePullRequestUsingTitleButWithoutBody() { $this->expectException(MissingArgumentException::class); $data = [ - 'base' => 'master', - 'head' => 'virtualtestbranch', + 'base' => 'master', + 'head' => 'virtualtestbranch', 'title' => 'TITLE: Testing pull-request creation from PHP Github API', ]; diff --git a/test/Github/Tests/Api/RepoTest.php b/test/Github/Tests/Api/RepoTest.php index 7b84a6b52ac..786c27d97b5 100644 --- a/test/Github/Tests/Api/RepoTest.php +++ b/test/Github/Tests/Api/RepoTest.php @@ -92,14 +92,14 @@ public function shouldCreateRepositoryUsingNameOnly() $api->expects($this->once()) ->method('post') ->with('/user/repos', [ - 'name' => 'l3l0Repo', - 'description' => '', - 'homepage' => '', - 'private' => false, - 'has_issues' => false, - 'has_wiki' => false, + 'name' => 'l3l0Repo', + 'description' => '', + 'homepage' => '', + 'private' => false, + 'has_issues' => false, + 'has_wiki' => false, 'has_downloads' => false, - 'auto_init' => false, + 'auto_init' => false, 'has_projects' => true, ]) ->will($this->returnValue($expectedArray)); @@ -118,14 +118,14 @@ public function shouldCreateRepositoryForOrganization() $api->expects($this->once()) ->method('post') ->with('/orgs/KnpLabs/repos', [ - 'name' => 'KnpLabsRepo', - 'description' => '', - 'homepage' => '', - 'private' => false, - 'has_issues' => false, - 'has_wiki' => false, + 'name' => 'KnpLabsRepo', + 'description' => '', + 'homepage' => '', + 'private' => false, + 'has_issues' => false, + 'has_wiki' => false, 'has_downloads' => false, - 'auto_init' => false, + 'auto_init' => false, 'has_projects' => true, ]) ->will($this->returnValue($expectedArray)); @@ -144,16 +144,16 @@ public function shouldCreateRepositoryWithInternalVisibility() $api->expects($this->once()) ->method('post') ->with('/user/repos', [ - 'name' => 'KnpLabsRepo', - 'description' => '', - 'homepage' => '', - 'has_issues' => false, - 'has_wiki' => false, + 'name' => 'KnpLabsRepo', + 'description' => '', + 'homepage' => '', + 'has_issues' => false, + 'has_wiki' => false, 'has_downloads' => false, - 'auto_init' => false, - 'has_projects' => true, - 'visibility' => 'internal', - 'private' => false, + 'auto_init' => false, + 'has_projects' => true, + 'visibility' => 'internal', + 'private' => false, ]) ->will($this->returnValue($expectedArray)); @@ -389,14 +389,14 @@ public function shouldCreateUsingAllParams() $api->expects($this->once()) ->method('post') ->with('/user/repos', [ - 'name' => 'l3l0Repo', - 'description' => 'test', - 'homepage' => 'http://l3l0.eu', - 'private' => true, - 'has_issues' => false, - 'has_wiki' => false, + 'name' => 'l3l0Repo', + 'description' => 'test', + 'homepage' => 'http://l3l0.eu', + 'private' => true, + 'has_issues' => false, + 'has_wiki' => false, 'has_downloads' => false, - 'auto_init' => false, + 'auto_init' => false, 'has_projects' => true, ]) ->will($this->returnValue($expectedArray)); diff --git a/test/Github/Tests/Api/Repository/ContentsTest.php b/test/Github/Tests/Api/Repository/ContentsTest.php index ff89ffda8ac..81a79db64fa 100644 --- a/test/Github/Tests/Api/Repository/ContentsTest.php +++ b/test/Github/Tests/Api/Repository/ContentsTest.php @@ -111,10 +111,10 @@ public function shouldCreateNewFile() $branch = 'master'; $committer = ['name' => 'committer name', 'email' => 'email@example.com']; $parameters = [ - 'content' => base64_encode($content), - 'message' => $message, + 'content' => base64_encode($content), + 'message' => $message, 'committer' => $committer, - 'branch' => $branch, + 'branch' => $branch, ]; $api = $this->getApiMock(); @@ -150,11 +150,11 @@ public function shouldUpdateFile() $branch = 'master'; $committer = ['name' => 'committer name', 'email' => 'email@example.com']; $parameters = [ - 'content' => base64_encode($content), - 'message' => $message, + 'content' => base64_encode($content), + 'message' => $message, 'committer' => $committer, - 'branch' => $branch, - 'sha' => $sha, + 'branch' => $branch, + 'sha' => $sha, ]; $api = $this->getApiMock(); @@ -189,10 +189,10 @@ public function shouldDeleteFile() $branch = 'master'; $committer = ['name' => 'committer name', 'email' => 'email@example.com']; $parameters = [ - 'message' => $message, + 'message' => $message, 'committer' => $committer, - 'branch' => $branch, - 'sha' => $sha, + 'branch' => $branch, + 'sha' => $sha, ]; $api = $this->getApiMock(); diff --git a/test/Github/Tests/Api/Repository/PagesTest.php b/test/Github/Tests/Api/Repository/PagesTest.php index c6b34cbc8b3..2fde0df1622 100644 --- a/test/Github/Tests/Api/Repository/PagesTest.php +++ b/test/Github/Tests/Api/Repository/PagesTest.php @@ -37,7 +37,7 @@ public function shouldEnablePages() $params = [ 'source' => [ 'branch' => 'master', - 'path' => '/path', + 'path' => '/path', ], ]; diff --git a/test/Github/Tests/Functional/CacheTest.php b/test/Github/Tests/Functional/CacheTest.php index ec9be6b12e0..eef379e61d5 100644 --- a/test/Github/Tests/Functional/CacheTest.php +++ b/test/Github/Tests/Functional/CacheTest.php @@ -24,7 +24,7 @@ public function shouldServeCachedResponse() $mockClient->addResponse($this->getCurrentUserResponse('octocat')); $github = Client::createWithHttpClient($mockClient); - $github->addCache(new ArrayAdapter(), ['default_ttl'=>600]); + $github->addCache(new ArrayAdapter(), ['default_ttl' => 600]); $github->authenticate('fake_token_aaa', AuthMethod::ACCESS_TOKEN); $userA = $github->currentUser()->show(); @@ -44,7 +44,7 @@ public function shouldVaryOnAuthorization() $mockClient->addResponse($this->getCurrentUserResponse('octocat')); $github = Client::createWithHttpClient($mockClient); - $github->addCache(new ArrayAdapter(), ['default_ttl'=>600]); + $github->addCache(new ArrayAdapter(), ['default_ttl' => 600]); $github->authenticate('fake_token_aaa', AuthMethod::ACCESS_TOKEN); $userA = $github->currentUser()->show(); diff --git a/test/Github/Tests/HttpClient/Message/ResponseMediatorTest.php b/test/Github/Tests/HttpClient/Message/ResponseMediatorTest.php index 8c1bfd29243..5171ab0bac8 100644 --- a/test/Github/Tests/HttpClient/Message/ResponseMediatorTest.php +++ b/test/Github/Tests/HttpClient/Message/ResponseMediatorTest.php @@ -15,7 +15,7 @@ public function testGetContent() $body = ['foo' => 'bar']; $response = new Response( 200, - ['Content-Type'=>'application/json'], + ['Content-Type' => 'application/json'], \GuzzleHttp\Psr7\stream_for(json_encode($body)) ); @@ -45,7 +45,7 @@ public function testGetContentInvalidJson() $body = 'foobar'; $response = new Response( 200, - ['Content-Type'=>'application/json'], + ['Content-Type' => 'application/json'], \GuzzleHttp\Psr7\stream_for($body) ); @@ -64,7 +64,7 @@ public function testGetPagination() ]; // response mock - $response = new Response(200, ['link'=>$header]); + $response = new Response(200, ['link' => $header]); $result = ResponseMediator::getPagination($response); $this->assertEquals($pagination, $result); @@ -75,7 +75,7 @@ public function testGetHeader() $header = 'application/json'; $response = new Response( 200, - ['Content-Type'=> $header] + ['Content-Type' => $header] ); $this->assertEquals($header, ResponseMediator::getHeader($response, 'content-type')); diff --git a/test/Github/Tests/Mock/PaginatedResponse.php b/test/Github/Tests/Mock/PaginatedResponse.php index 4586de402ec..9d67b9f42be 100644 --- a/test/Github/Tests/Mock/PaginatedResponse.php +++ b/test/Github/Tests/Mock/PaginatedResponse.php @@ -18,7 +18,7 @@ public function __construct($loopCount, array $content = []) $this->loopCount = $loopCount; $this->content = $content; - parent::__construct(200, ['Content-Type'=>'application/json'], \GuzzleHttp\Psr7\stream_for(json_encode($content))); + parent::__construct(200, ['Content-Type' => 'application/json'], \GuzzleHttp\Psr7\stream_for(json_encode($content))); } public function getHeader($header) diff --git a/test/Github/Tests/ResultPagerTest.php b/test/Github/Tests/ResultPagerTest.php index 2839e16f3df..264fd42ef75 100644 --- a/test/Github/Tests/ResultPagerTest.php +++ b/test/Github/Tests/ResultPagerTest.php @@ -152,7 +152,7 @@ public function testFetchAllPreserveKeys() 'sha' => '43068834af7e501778708ed13106de95f782328c', ]; - $response = new Response(200, ['Content-Type'=>'application/json'], Utils::streamFor(json_encode($content))); + $response = new Response(200, ['Content-Type' => 'application/json'], Utils::streamFor(json_encode($content))); // httpClient mock $httpClientMock = $this->getMockBuilder(HttpClient::class) From 61b478ab7246348bba876bf694e3f0e23a665e2d Mon Sep 17 00:00:00 2001 From: Thomas Corbett Date: Sun, 24 Mar 2024 14:20:24 -0400 Subject: [PATCH 85/98] bug #1135 Handle case of GitHub returning 204 No Content in some scenarios (tomcorbett) This PR was squashed before being merged into the 3.14-dev branch. Discussion ---------- ResultPager breaks because no array is returned (it's an empty string) - issue ResultPager::get() can return string #1091 Commits ------- 8a3f154b49c308ad8cc748caf842b7759132ea34 Handle case of GitHub returning 204 No Content in some scenarios which breaks ResultPager because no array is returned (it's an empty string) - issue ResultPager::get() can return string #1091 4fff55583e3c345cb835ecd6ba04db6dd70b7762 fix style issue raised by continuous-integration/styleci/pr eaa7993f2cda2754dbd00f8b6190c0a738eefbb8 Added unit test for case of GitHub API returning 204 empty content in ResultPager #1091 08c3d7a918fb4123b444085f9ae4e6d4ef2639bd Updated based on feedback from continuous-integration/styleci/pr a3d2fb821c49a83a65f27f4b8999e3d44532eed7 Another change requested by continuous-integration/styleci/pr (but not for my changed code) --- lib/Github/ResultPager.php | 4 ++ test/Github/Tests/ResultPagerTest.php | 63 +++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/lib/Github/ResultPager.php b/lib/Github/ResultPager.php index cfd1d605e4f..a1d94785ca6 100644 --- a/lib/Github/ResultPager.php +++ b/lib/Github/ResultPager.php @@ -86,6 +86,10 @@ public function fetch(AbstractApi $api, string $method, array $parameters = []): $api = $closure($api); $result = $api->$method(...$parameters); + if ($result === '' && $this->client->getLastResponse()->getStatusCode() === 204) { + $result = []; + } + $this->postFetch(true); return $result; diff --git a/test/Github/Tests/ResultPagerTest.php b/test/Github/Tests/ResultPagerTest.php index 264fd42ef75..3df610ee250 100644 --- a/test/Github/Tests/ResultPagerTest.php +++ b/test/Github/Tests/ResultPagerTest.php @@ -4,6 +4,7 @@ use Github\Api\Issue; use Github\Api\Organization\Members; +use Github\Api\Repo; use Github\Api\Repository\Statuses; use Github\Api\Search; use Github\Client; @@ -116,6 +117,40 @@ public function shouldGetAllSearchResults() $this->assertCount($amountLoops * count($content['items']), $result); } + /** + * @test + */ + public function shouldHandleEmptyContributorListWith204Header() + { + // Set up a 204 response with an empty body + $response = new Response(204, [], ''); + $username = 'testuser'; + $reponame = 'testrepo'; + + // Mock the HttpClient to return the empty response + $httpClientMock = $this->getMockBuilder(HttpClient::class) + ->onlyMethods(['sendRequest']) + ->getMock(); + $httpClientMock + ->method('sendRequest') + ->willReturn($response); + + $client = Client::createWithHttpClient($httpClientMock); + + $repoApi = new Repo($client); + + $paginator = $this->getMockBuilder(ResultPager::class) + ->setConstructorArgs([$client]) // Pass the Client in the constructor + ->onlyMethods(['fetchAll']) + ->getMock(); + $paginator->expects($this->once()) + ->method('fetchAll') + ->with($repoApi, 'contributors', [$username, $reponame]) + ->willReturn([]); + + $this->assertEquals([], $paginator->fetchAll($repoApi, 'contributors', [$username, $reponame])); + } + public function testFetch() { $result = ['foo']; @@ -201,6 +236,34 @@ public function testFetchAllWithoutKeys() $this->assertCount(9, $result); } + public function testFetchAll() + { + $content = [ + ['title' => 'issue 1'], + ['title' => 'issue 2'], + ['title' => 'issue 3'], + ]; + + $response = new PaginatedResponse(3, $content); + + // httpClient mock + $httpClientMock = $this->getMockBuilder(HttpClient::class) + ->onlyMethods(['sendRequest']) + ->getMock(); + $httpClientMock + ->expects($this->exactly(3)) + ->method('sendRequest') + ->willReturn($response); + + $client = Client::createWithHttpClient($httpClientMock); + + $api = new Issue($client); + $paginator = new ResultPager($client); + $result = $paginator->fetchAll($api, 'all', ['knplabs', 'php-github-api']); + + $this->assertCount(9, $result); + } + /** * @group legacy */ From 71fec50e228737ec23c0b69801b85bf596fbdaca Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Sun, 24 Mar 2024 19:21:15 +0100 Subject: [PATCH 86/98] Update changelog for 3.14.1 release --- CHANGELOG-3.X.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG-3.X.md b/CHANGELOG-3.X.md index 44afe4fc8cb..d94de7504b2 100644 --- a/CHANGELOG-3.X.md +++ b/CHANGELOG-3.X.md @@ -1,5 +1,10 @@ # Changelog +## 3.14.1 + +### Fixed +- Handle case of GitHub returning 204 No Content in some scenarios ([tomcorbett](https://github.com/tomcorbett)) [#1135](https://github.com/KnpLabs/php-github-api/issues/1135) + ## 3.14.0 ### Added From 773747a72f4aad5248d05f109f40291bf8543baf Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Mon, 25 Mar 2024 09:25:55 +0000 Subject: [PATCH 87/98] Fix type error in ResultPager::fetch When using etags, the reply from github may be empty and the underlying APIs will return an empty string. We need to flip those to empty arrays. e.g.: ``` $github_builder ->addPlugin(new Http\Client\Common\Plugin\HeaderSetPlugin([ 'If-None-Match' => $etag, ])); $api = $github_client->user('user'); $paginator = new \Github\ResultPager($github_client); $data = $paginator->fetch($api, 'events', [$username]); // $data should be [] if $etag is the latest ``` --- lib/Github/ResultPager.php | 2 +- test/Github/Tests/ResultPagerTest.php | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/Github/ResultPager.php b/lib/Github/ResultPager.php index a1d94785ca6..f23b6c6f418 100644 --- a/lib/Github/ResultPager.php +++ b/lib/Github/ResultPager.php @@ -86,7 +86,7 @@ public function fetch(AbstractApi $api, string $method, array $parameters = []): $api = $closure($api); $result = $api->$method(...$parameters); - if ($result === '' && $this->client->getLastResponse()->getStatusCode() === 204) { + if ($result === '') { $result = []; } diff --git a/test/Github/Tests/ResultPagerTest.php b/test/Github/Tests/ResultPagerTest.php index 3df610ee250..b898528483b 100644 --- a/test/Github/Tests/ResultPagerTest.php +++ b/test/Github/Tests/ResultPagerTest.php @@ -7,6 +7,7 @@ use Github\Api\Repo; use Github\Api\Repository\Statuses; use Github\Api\Search; +use Github\Api\User; use Github\Client; use Github\ResultPager; use Github\Tests\Mock\PaginatedResponse; @@ -176,6 +177,29 @@ public function testFetch() $this->assertEquals($result, $paginator->fetch($api, $method, $parameters)); } + public function testEmptyFetch() + { + $parameters = ['username']; + $api = $this->getMockBuilder(User::class) + ->disableOriginalConstructor() + ->onlyMethods(['events']) + ->getMock(); + $api->expects($this->once()) + ->method('events') + ->with(...$parameters) + ->willReturn(''); + + $paginator = $this->getMockBuilder(ResultPager::class) + ->disableOriginalConstructor() + ->onlyMethods(['postFetch']) + ->getMock(); + + $paginator->expects($this->once()) + ->method('postFetch'); + + $this->assertEquals([], $paginator->fetch($api, 'events', $parameters)); + } + public function testFetchAllPreserveKeys() { $content = [ From 1f77a93c3a28e6b0f95c3cb7bbb7cb0b7853fd2b Mon Sep 17 00:00:00 2001 From: Stephan Vock Date: Mon, 16 Sep 2024 14:23:51 +0100 Subject: [PATCH 88/98] Add API endpoints to interact with organiztion roles --- doc/README.md | 1 + doc/organization/organization-roles.md | 108 ++++++++++ lib/Github/Api/Organization.php | 6 + .../Api/Organization/OrganizationRoles.php | 61 ++++++ .../Organization/OrganizationRolesTest.php | 187 ++++++++++++++++++ 5 files changed, 363 insertions(+) create mode 100644 doc/organization/organization-roles.md create mode 100644 lib/Github/Api/Organization/OrganizationRoles.php create mode 100644 test/Github/Tests/Api/Organization/OrganizationRolesTest.php diff --git a/doc/README.md b/doc/README.md index 35929c2afc3..17c3604dc35 100644 --- a/doc/README.md +++ b/doc/README.md @@ -44,6 +44,7 @@ v3 APIs: * [Secrets](organization/actions/secrets.md) * [Variables](organization/actions/variables.md) * [Secret Scanning Alert](organization/secret-scanning.md) + * [Organization Roles](organization/organization-roles.md) * [Projects](project/projects.md) * [Columns](project/columns.md) * [Cards](project/cards.md) diff --git a/doc/organization/organization-roles.md b/doc/organization/organization-roles.md new file mode 100644 index 00000000000..a320b6eb047 --- /dev/null +++ b/doc/organization/organization-roles.md @@ -0,0 +1,108 @@ +## Organization / Webhooks API +[Back to the navigation](../README.md) + +Listing, showing, assigning, and removing orgniazationroles. +Wraps [GitHub Organization Roles API](https://docs.github.com/en/rest/orgs/organization-roles). + +Additional APIs: +* [Organization](../doc/organization) + +### List all organizaton roles in an organization + +> Requires [authentication](../security.md). + +```php +$roles = $client->organization()->organizationRoles()->all('acme'); +``` + +Returns a counter and a list of organization roles in the organization. + +### Get an organization role in an organization + +> Requires [authentication](../security.md). + +```php +$role = $client->organization()->organizationRoles()->show('acme', 123); +``` + +Returns a single organization role in the organization. + +### List all teams with role assigned in an organization + +> Requires [authentication](../security.md). + +```php +$users = $client->organization()->organizationRoles()->listTeamsWithRole('acme', 1); +``` + +Returns a list of teams with the role assigned to them. + +### Assign a single role to a team in an organization + +> Requires [authentication](../security.md). + +```php +$client->organization()->organizationRoles()->assignRoleToTeam('acme', 1, 'admin-user'); +``` + +No content is returned. + +### Remove a single role from a team in an organization + +> Requires [authentication](../security.md). + +```php +$client->organization()->organizationRoles()->removeRoleFromTeam('acme', 1, 'admin-team'); +``` + +No content is returned. + +### Remove all roles from a team in an organization + +> Requires [authentication](../security.md). + +```php +$client->organization()->organizationRoles()->removeAllRolesFromTeam('acme', 'admin-team'); +``` + +No content is returned. + +### List all users with role assigned in an organization + +> Requires [authentication](../security.md). + +```php +$users = $client->organization()->organizationRoles()->listUsersWithRole('acme', 1); +``` + +Returns a list of users with the role assigned to them. + +### Assign a single role to a user in an organization + +> Requires [authentication](../security.md). + +```php +$client->organization()->organizationRoles()->assignRoleToUser('acme', 1, 'admin-user'); +``` + +No content is returned. + +### Remove a single role from a user in an organization + +> Requires [authentication](../security.md). + +```php +$client->organization()->organizationRoles()->removeRoleFromUser('acme', 1, 'admin-user'); +``` + +No content is returned. + +### Remove all roles from a user in an organization + +> Requires [authentication](../security.md). + +```php +$client->organization()->organizationRoles()->removeAllRolesFromUser('acme', 'admin-user'); +``` + +No content is returned. diff --git a/lib/Github/Api/Organization.php b/lib/Github/Api/Organization.php index ada7e66836d..0e1210c95b6 100644 --- a/lib/Github/Api/Organization.php +++ b/lib/Github/Api/Organization.php @@ -7,6 +7,7 @@ use Github\Api\Organization\Actions\Variables; use Github\Api\Organization\Hooks; use Github\Api\Organization\Members; +use Github\Api\Organization\OrganizationRoles; use Github\Api\Organization\OutsideCollaborators; use Github\Api\Organization\SecretScanning; use Github\Api\Organization\Teams; @@ -158,4 +159,9 @@ public function secretScanning(): SecretScanning { return new SecretScanning($this->getClient()); } + + public function organizationRoles(): OrganizationRoles + { + return new OrganizationRoles($this->getClient()); + } } diff --git a/lib/Github/Api/Organization/OrganizationRoles.php b/lib/Github/Api/Organization/OrganizationRoles.php new file mode 100644 index 00000000000..dd44fceceaf --- /dev/null +++ b/lib/Github/Api/Organization/OrganizationRoles.php @@ -0,0 +1,61 @@ +get('/orgs/'.rawurlencode($organization).'/organization-roles'); + } + + public function show(string $organization, int $roleId) + { + return $this->get('/orgs/'.rawurlencode($organization).'/organization-roles/'.$roleId); + } + + public function listTeamsWithRole(string $organization, int $roleId) + { + return $this->get('/orgs/'.rawurlencode($organization).'/organization-roles/'.$roleId.'/teams'); + } + + public function assignRoleToTeam(string $organization, int $roleId, string $teamSlug): void + { + $this->put('/orgs/'.rawurlencode($organization).'/organization-roles/teams/'.rawurlencode($teamSlug).'/'.$roleId); + } + + public function removeRoleFromTeam(string $organization, int $roleId, string $teamSlug): void + { + $this->delete('/orgs/'.rawurlencode($organization).'/organization-roles/teams/'.rawurlencode($teamSlug).'/'.$roleId); + } + + public function removeAllRolesFromTeam(string $organization, string $teamSlug): void + { + $this->delete('/orgs/'.rawurlencode($organization).'/organization-roles/teams/'.rawurlencode($teamSlug)); + } + + public function listUsersWithRole(string $organization, int $roleId): array + { + return $this->get('/orgs/'.rawurlencode($organization).'/organization-roles/'.$roleId.'/users'); + } + + public function assignRoleToUser(string $organization, int $roleId, string $username): void + { + $this->put('/orgs/'.rawurlencode($organization).'/organization-roles/users/'.rawurlencode($username).'/'.$roleId); + } + + public function removeRoleFromUser(string $organization, int $roleId, string $username): void + { + $this->delete('/orgs/'.rawurlencode($organization).'/organization-roles/users/'.rawurlencode($username).'/'.$roleId); + } + + public function removeAllRolesFromUser(string $organization, string $username): void + { + $this->delete('/orgs/'.rawurlencode($organization).'/organization-roles/users/'.rawurlencode($username)); + } +} diff --git a/test/Github/Tests/Api/Organization/OrganizationRolesTest.php b/test/Github/Tests/Api/Organization/OrganizationRolesTest.php new file mode 100644 index 00000000000..f2d801afceb --- /dev/null +++ b/test/Github/Tests/Api/Organization/OrganizationRolesTest.php @@ -0,0 +1,187 @@ + 1, + 'roles' => [[ + 'id' => 1, + 'name' => 'all_repo_admin', + 'description' => 'Grants admin access to all repositories in the organization.', + 'permissions' => [], + 'organization' => null, + 'created_at' => '2023-01-01T00:00:00Z', + 'updated_at' => '2023-01-01T00:00:00Z', + 'source' => 'Predefined', + 'base_role' => 'admin', + ]], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/orgs/acme/organization-roles') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->all('acme')); + } + + /** + * @test + */ + public function shouldShowSingleOrganizationRole() + { + $expectedValue = [ + 'id' => 1, + 'name' => 'all_repo_admin', + 'description' => 'Grants admin access to all repositories in the organization.', + 'permissions' => [], + 'organization' => null, + 'created_at' => '2023-01-01T00:00:00Z', + 'updated_at' => '2023-01-01T00:00:00Z', + 'source' => 'Predefined', + 'base_role' => 'admin', + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/orgs/acme/organization-roles/1') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->show('acme', 1)); + } + + /** + * @test + */ + public function shouldGetAllTeamsWithRole() + { + $expectedValue = [['name' => 'Acme Admins']]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/orgs/acme/organization-roles/1/teams') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->listTeamsWithRole('acme', 1)); + } + + /** + * @test + */ + public function shouldAssignRoleToTeam() + { + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('put') + ->with('/orgs/acme/organization-roles/teams/acme-admins/1') + ->will($this->returnValue('')); + + $api->assignRoleToTeam('acme', 1, 'acme-admins'); + } + + /** + * @test + */ + public function shouldRemoveRoleFromTeam() + { + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('/orgs/acme/organization-roles/teams/acme-admins/1') + ->will($this->returnValue('')); + + $api->removeRoleFromTeam('acme', 1, 'acme-admins'); + } + + /** + * @test + */ + public function shouldRemoveAllRolesFromTeam() + { + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('/orgs/acme/organization-roles/teams/acme-admins') + ->will($this->returnValue('')); + + $api->removeAllRolesFromTeam('acme', 'acme-admins'); + } + + /** + * @test + */ + public function shouldGetAllUsersWithRole() + { + $expectedValue = [['username' => 'Admin']]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/orgs/acme/organization-roles/1/users') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->listUsersWithRole('acme', 1)); + } + + /** + * @test + */ + public function shouldAssignRoleToUser() + { + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('put') + ->with('/orgs/acme/organization-roles/users/admin/1') + ->will($this->returnValue('')); + + $api->assignRoleToUser('acme', 1, 'admin'); + } + + /** + * @test + */ + public function shouldRemoveRoleFromUser() + { + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('/orgs/acme/organization-roles/users/admin/1') + ->will($this->returnValue('')); + + $api->removeRoleFromUser('acme', 1, 'admin'); + } + + /** + * @test + */ + public function shouldRemoveAllRolesFromUser() + { + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('/orgs/acme/organization-roles/users/admin') + ->will($this->returnValue('')); + + $api->removeAllRolesFromUser('acme', 'admin'); + } + + protected function getApiClass(): string + { + return OrganizationRoles::class; + } +} From 00ab97b4cfce9cc9f07a860ae38f573a40f9d763 Mon Sep 17 00:00:00 2001 From: Eirik Stanghelle Morland Date: Mon, 23 Sep 2024 20:46:31 +0200 Subject: [PATCH 89/98] feature #1144 Fix implicit nullable types to avoid PHP 8.4 warnings (eiriksm, acrobat) This PR was squashed before being merged into the 3.14-dev branch. Discussion ---------- Commits ------- 9bd8e00fe8063bba2aff831c150a2b4b54302f22 Fix implicit nullable types to avoid PHP 8.4 warnings ad84a65147b6c54036a90798b14e23b39461c310 Fix a param that was not supposed to be nullable a35a8295e33d8757ddec2fdcaeca74075cb904ca Update ci.yml 297f04e3c7665fcb1b74cf662fafa2c8d469f631 Fixes with phpcbf 1b635980ac3f1ee264b65196188340a6240be800 Fix implicit nullable case in tests 6d145f54832ea5e7d1c8c488149c9d39c38dd56d Fix upstream deprecation warnings --- .github/workflows/ci.yml | 4 +++- composer.json | 2 +- lib/Github/Api/Notification.php | 4 ++-- lib/Github/Api/Repository/Actions/Workflows.php | 2 +- lib/Github/Api/Repository/Contents.php | 6 +++--- lib/Github/Client.php | 2 +- lib/Github/Exception/ApiLimitExceedException.php | 2 +- lib/Github/Exception/MissingArgumentException.php | 2 +- lib/Github/Exception/SsoRequiredException.php | 2 +- .../Exception/TwoFactorAuthenticationRequiredException.php | 2 +- lib/Github/HttpClient/Builder.php | 6 +++--- lib/Github/ResultPager.php | 2 +- test/Github/Tests/Api/AbstractApiTest.php | 3 ++- test/Github/Tests/Functional/CacheTest.php | 3 ++- .../Tests/HttpClient/Message/ResponseMediatorTest.php | 7 ++++--- .../Tests/HttpClient/Plugin/GithubExceptionThrowerTest.php | 2 +- test/Github/Tests/Mock/PaginatedResponse.php | 7 ++++--- 17 files changed, 32 insertions(+), 26 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 923f2ce49c9..9c46d891719 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3'] + php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] steps: - uses: actions/checkout@v4 @@ -27,6 +27,8 @@ jobs: - name: Run phpunit run: vendor/bin/phpunit --verbose + env: + SYMFONY_DEPRECATIONS_HELPER: 'max[self]=0' phpstan: name: PHPStan diff --git a/composer.json b/composer.json index f3d598d6940..c1da1aefbca 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,7 @@ }, "require-dev": { "symfony/cache": "^5.1.8", - "guzzlehttp/psr7": "^1.7", + "guzzlehttp/psr7": "^2.7", "http-interop/http-factory-guzzle": "^1.0", "guzzlehttp/guzzle": "^7.2", "php-http/mock-client": "^1.4.1", diff --git a/lib/Github/Api/Notification.php b/lib/Github/Api/Notification.php index e8c9b246a11..f720ad0c88c 100644 --- a/lib/Github/Api/Notification.php +++ b/lib/Github/Api/Notification.php @@ -27,7 +27,7 @@ class Notification extends AbstractApi * * @return array array of notifications */ - public function all($includingRead = false, $participating = false, DateTime $since = null, DateTime $before = null) + public function all($includingRead = false, $participating = false, ?DateTime $since = null, ?DateTime $before = null) { $parameters = [ 'all' => $includingRead, @@ -54,7 +54,7 @@ public function all($includingRead = false, $participating = false, DateTime $si * * @param DateTime|null $since */ - public function markRead(DateTime $since = null) + public function markRead(?DateTime $since = null) { $parameters = []; diff --git a/lib/Github/Api/Repository/Actions/Workflows.php b/lib/Github/Api/Repository/Actions/Workflows.php index e425f9d2651..9a1c9e31c7b 100644 --- a/lib/Github/Api/Repository/Actions/Workflows.php +++ b/lib/Github/Api/Repository/Actions/Workflows.php @@ -70,7 +70,7 @@ public function usage(string $username, string $repository, $workflow) * * @return array|string empty */ - public function dispatches(string $username, string $repository, $workflow, string $ref, array $inputs = null) + public function dispatches(string $username, string $repository, $workflow, string $ref, ?array $inputs = null) { if (is_string($workflow)) { $workflow = rawurlencode($workflow); diff --git a/lib/Github/Api/Repository/Contents.php b/lib/Github/Api/Repository/Contents.php index b6e170ebce0..a3cc1a3ea0e 100644 --- a/lib/Github/Api/Repository/Contents.php +++ b/lib/Github/Api/Repository/Contents.php @@ -98,7 +98,7 @@ public function show($username, $repository, $path = null, $reference = null, $r * * @return array information about the new file */ - public function create($username, $repository, $path, $content, $message, $branch = null, array $committer = null) + public function create($username, $repository, $path, $content, $message, $branch = null, ?array $committer = null) { $url = '/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/contents/'.rawurlencode($path); @@ -174,7 +174,7 @@ public function exists($username, $repository, $path, $reference = null) * * @return array information about the updated file */ - public function update($username, $repository, $path, $content, $message, $sha, $branch = null, array $committer = null) + public function update($username, $repository, $path, $content, $message, $sha, $branch = null, ?array $committer = null) { $url = '/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/contents/'.rawurlencode($path); @@ -215,7 +215,7 @@ public function update($username, $repository, $path, $content, $message, $sha, * * @return array information about the updated file */ - public function rm($username, $repository, $path, $message, $sha, $branch = null, array $committer = null) + public function rm($username, $repository, $path, $message, $sha, $branch = null, ?array $committer = null) { $url = '/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/contents/'.rawurlencode($path); diff --git a/lib/Github/Client.php b/lib/Github/Client.php index 56d68d59cec..77fcc7b71a2 100644 --- a/lib/Github/Client.php +++ b/lib/Github/Client.php @@ -123,7 +123,7 @@ class Client * @param string|null $apiVersion * @param string|null $enterpriseUrl */ - public function __construct(Builder $httpClientBuilder = null, $apiVersion = null, $enterpriseUrl = null) + public function __construct(?Builder $httpClientBuilder = null, $apiVersion = null, $enterpriseUrl = null) { $this->responseHistory = new History(); $this->httpClientBuilder = $builder = $httpClientBuilder ?? new Builder(); diff --git a/lib/Github/Exception/ApiLimitExceedException.php b/lib/Github/Exception/ApiLimitExceedException.php index 5c1dd4d8a17..c21f5c2729e 100644 --- a/lib/Github/Exception/ApiLimitExceedException.php +++ b/lib/Github/Exception/ApiLimitExceedException.php @@ -20,7 +20,7 @@ class ApiLimitExceedException extends RuntimeException * @param int $code * @param Throwable|null $previous */ - public function __construct(int $limit = 5000, int $reset = 1800, int $code = 0, Throwable $previous = null) + public function __construct(int $limit = 5000, int $reset = 1800, int $code = 0, ?Throwable $previous = null) { $this->limit = (int) $limit; $this->reset = (int) $reset; diff --git a/lib/Github/Exception/MissingArgumentException.php b/lib/Github/Exception/MissingArgumentException.php index 4cd3aeca81d..742cdc5ac7f 100644 --- a/lib/Github/Exception/MissingArgumentException.php +++ b/lib/Github/Exception/MissingArgumentException.php @@ -14,7 +14,7 @@ class MissingArgumentException extends ErrorException * @param int $code * @param Throwable|null $previous */ - public function __construct($required, int $code = 0, Throwable $previous = null) + public function __construct($required, int $code = 0, ?Throwable $previous = null) { if (is_string($required)) { $required = [$required]; diff --git a/lib/Github/Exception/SsoRequiredException.php b/lib/Github/Exception/SsoRequiredException.php index 1725270a036..09b9d63db08 100644 --- a/lib/Github/Exception/SsoRequiredException.php +++ b/lib/Github/Exception/SsoRequiredException.php @@ -14,7 +14,7 @@ class SsoRequiredException extends RuntimeException * @param int $code * @param Throwable|null $previous */ - public function __construct(string $url, int $code = 0, Throwable $previous = null) + public function __construct(string $url, int $code = 0, ?Throwable $previous = null) { $this->url = $url; diff --git a/lib/Github/Exception/TwoFactorAuthenticationRequiredException.php b/lib/Github/Exception/TwoFactorAuthenticationRequiredException.php index c57e67b8e1d..139033dff5b 100644 --- a/lib/Github/Exception/TwoFactorAuthenticationRequiredException.php +++ b/lib/Github/Exception/TwoFactorAuthenticationRequiredException.php @@ -14,7 +14,7 @@ class TwoFactorAuthenticationRequiredException extends RuntimeException * @param int $code * @param Throwable|null $previous */ - public function __construct(string $type, int $code = 0, Throwable $previous = null) + public function __construct(string $type, int $code = 0, ?Throwable $previous = null) { $this->type = $type; parent::__construct('Two factor authentication is enabled on this account', $code, $previous); diff --git a/lib/Github/HttpClient/Builder.php b/lib/Github/HttpClient/Builder.php index a8713de13bc..c77f1ac83d8 100644 --- a/lib/Github/HttpClient/Builder.php +++ b/lib/Github/HttpClient/Builder.php @@ -78,9 +78,9 @@ class Builder * @param StreamFactoryInterface|null $streamFactory */ public function __construct( - ClientInterface $httpClient = null, - RequestFactoryInterface $requestFactory = null, - StreamFactoryInterface $streamFactory = null + ?ClientInterface $httpClient = null, + ?RequestFactoryInterface $requestFactory = null, + ?StreamFactoryInterface $streamFactory = null ) { $this->httpClient = $httpClient ?? Psr18ClientDiscovery::find(); $this->requestFactory = $requestFactory ?? Psr17FactoryDiscovery::findRequestFactory(); diff --git a/lib/Github/ResultPager.php b/lib/Github/ResultPager.php index a1d94785ca6..4583e5e1268 100644 --- a/lib/Github/ResultPager.php +++ b/lib/Github/ResultPager.php @@ -59,7 +59,7 @@ class ResultPager implements ResultPagerInterface * * @return void */ - public function __construct(Client $client, int $perPage = null) + public function __construct(Client $client, ?int $perPage = null) { if (null !== $perPage && ($perPage < 1 || $perPage > 100)) { throw new ValueError(sprintf('%s::__construct(): Argument #2 ($perPage) must be between 1 and 100, or null', self::class)); diff --git a/test/Github/Tests/Api/AbstractApiTest.php b/test/Github/Tests/Api/AbstractApiTest.php index 428ece12cf3..53e0eb6970a 100644 --- a/test/Github/Tests/Api/AbstractApiTest.php +++ b/test/Github/Tests/Api/AbstractApiTest.php @@ -4,6 +4,7 @@ use Github\Api\AbstractApi; use GuzzleHttp\Psr7\Response; +use GuzzleHttp\Psr7\Utils; use Http\Client\Common\HttpMethodsClientInterface; class AbstractApiTest extends TestCase @@ -232,7 +233,7 @@ private function getPSR7Response($expectedArray) return new Response( 200, ['Content-Type' => 'application/json'], - \GuzzleHttp\Psr7\stream_for(json_encode($expectedArray)) + Utils::streamFor(json_encode($expectedArray)) ); } } diff --git a/test/Github/Tests/Functional/CacheTest.php b/test/Github/Tests/Functional/CacheTest.php index eef379e61d5..bd217dc5dc2 100644 --- a/test/Github/Tests/Functional/CacheTest.php +++ b/test/Github/Tests/Functional/CacheTest.php @@ -5,6 +5,7 @@ use Github\AuthMethod; use Github\Client; use GuzzleHttp\Psr7\Response; +use GuzzleHttp\Psr7\Utils; use Symfony\Component\Cache\Adapter\ArrayAdapter; /** @@ -61,7 +62,7 @@ private function getCurrentUserResponse($username) 'Content-Type' => 'application/json', ]; - $body = \GuzzleHttp\Psr7\stream_for(json_encode([ + $body = Utils::streamFor(json_encode([ 'login' => $username, ])); diff --git a/test/Github/Tests/HttpClient/Message/ResponseMediatorTest.php b/test/Github/Tests/HttpClient/Message/ResponseMediatorTest.php index 5171ab0bac8..b6216d57044 100644 --- a/test/Github/Tests/HttpClient/Message/ResponseMediatorTest.php +++ b/test/Github/Tests/HttpClient/Message/ResponseMediatorTest.php @@ -4,6 +4,7 @@ use Github\HttpClient\Message\ResponseMediator; use GuzzleHttp\Psr7\Response; +use GuzzleHttp\Psr7\Utils; /** * @author Tobias Nyholm @@ -16,7 +17,7 @@ public function testGetContent() $response = new Response( 200, ['Content-Type' => 'application/json'], - \GuzzleHttp\Psr7\stream_for(json_encode($body)) + Utils::streamFor(json_encode($body)) ); $this->assertEquals($body, ResponseMediator::getContent($response)); @@ -31,7 +32,7 @@ public function testGetContentNotJson() $response = new Response( 200, [], - \GuzzleHttp\Psr7\stream_for($body) + Utils::streamFor($body) ); $this->assertEquals($body, ResponseMediator::getContent($response)); @@ -46,7 +47,7 @@ public function testGetContentInvalidJson() $response = new Response( 200, ['Content-Type' => 'application/json'], - \GuzzleHttp\Psr7\stream_for($body) + Utils::streamFor($body) ); $this->assertEquals($body, ResponseMediator::getContent($response)); diff --git a/test/Github/Tests/HttpClient/Plugin/GithubExceptionThrowerTest.php b/test/Github/Tests/HttpClient/Plugin/GithubExceptionThrowerTest.php index b2541ec0942..7cb7dfe33a8 100644 --- a/test/Github/Tests/HttpClient/Plugin/GithubExceptionThrowerTest.php +++ b/test/Github/Tests/HttpClient/Plugin/GithubExceptionThrowerTest.php @@ -20,7 +20,7 @@ class GithubExceptionThrowerTest extends TestCase /** * @dataProvider responseProvider */ - public function testHandleRequest(ResponseInterface $response, ExceptionInterface $exception = null): void + public function testHandleRequest(ResponseInterface $response, ?ExceptionInterface $exception = null): void { $request = new Request('GET', 'https://api.github.com/issues'); diff --git a/test/Github/Tests/Mock/PaginatedResponse.php b/test/Github/Tests/Mock/PaginatedResponse.php index 9d67b9f42be..296adf86457 100644 --- a/test/Github/Tests/Mock/PaginatedResponse.php +++ b/test/Github/Tests/Mock/PaginatedResponse.php @@ -3,6 +3,7 @@ namespace Github\Tests\Mock; use GuzzleHttp\Psr7\Response; +use GuzzleHttp\Psr7\Utils; /** * @author Tobias Nyholm @@ -18,10 +19,10 @@ public function __construct($loopCount, array $content = []) $this->loopCount = $loopCount; $this->content = $content; - parent::__construct(200, ['Content-Type' => 'application/json'], \GuzzleHttp\Psr7\stream_for(json_encode($content))); + parent::__construct(200, ['Content-Type' => 'application/json'], Utils::streamFor(json_encode($content))); } - public function getHeader($header) + public function getHeader($header): array { if ($header === 'Link') { if ($this->loopCount > 1) { @@ -38,7 +39,7 @@ public function getHeader($header) return parent::getHeader($header); } - public function hasHeader($header) + public function hasHeader($header): bool { if ($header === 'Link') { return true; From a6f0f4f46be78a047d48ff3f6ae024c065664177 Mon Sep 17 00:00:00 2001 From: anthony-webart <43772613+anthony-webart@users.noreply.github.com> Date: Tue, 24 Sep 2024 02:49:11 +0800 Subject: [PATCH 90/98] feature #1142 Copilot Usage Endpoints (anthony-webart) This PR was squashed before being merged into the 3.14-dev branch. Discussion ---------- Commits ------- f4e822eceede81d302f63cf96e580a816e345824 Add Copilot usage endpoints e16a14c94cc1dbabe4bc4b57e328cef24061d40d Reformat code 3698933a3246ecc363a986151cbed483c84b7999 Fix incorrect team urls 956fe9eb4d7596765710fd5914020fa2cf0068ac Add Copilot Usage API Documentation detailing endpoints for retrieving usage summaries. --- doc/copilot/usage.md | 80 +++++++++++++++++++++ lib/Github/Api/Copilot/Usage.php | 34 +++++++++ lib/Github/Client.php | 5 ++ test/Github/Tests/Api/Copilot/UsageTest.php | 78 ++++++++++++++++++++ 4 files changed, 197 insertions(+) create mode 100644 doc/copilot/usage.md create mode 100644 lib/Github/Api/Copilot/Usage.php create mode 100644 test/Github/Tests/Api/Copilot/UsageTest.php diff --git a/doc/copilot/usage.md b/doc/copilot/usage.md new file mode 100644 index 00000000000..6005adc1600 --- /dev/null +++ b/doc/copilot/usage.md @@ -0,0 +1,80 @@ +# Copilot Usage API Documentation +[Back to the navigation](../README.md) + +## Overview + +The Copilot Usage API provides endpoints to retrieve usage summaries for organizations and enterprises. + +**Note**: This endpoint is in beta and is subject to change. + +## Endpoints + +### Organization Usage Summary + +Retrieve the usage summary for a specific organization. + +**Method:** `GET` + +**Endpoint:** `/orgs/{organization}/copilot/usage` + +**Parameters:** +- `organization` (string): The name of the organization. +- `params` (array, optional): Additional query parameters. + +**Example:** +```php +$usage = $client->api('copilotUsage')->orgUsageSummary('KnpLabs'); +``` + +### Organization Team Usage Summary + +Retrieve the usage summary for a specific team within an organization. + +**Method:** `GET` + +**Endpoint:** `/orgs/{organization}/team/{team}/copilot/usage` + +**Parameters:** +- `organization` (string): The name of the organization. +- `team` (string): The name of the team. +- `params` (array, optional): Additional query parameters. + +**Example:** +```php +$usage = $client->api('copilotUsage')->orgTeamUsageSummary('KnpLabs', 'developers'); +``` + +### Enterprise Usage Summary + +Retrieve the usage summary for a specific enterprise. + +**Method:** `GET` + +**Endpoint:** `/enterprises/{enterprise}/copilot/usage` + +**Parameters:** +- `enterprise` (string): The name of the enterprise. +- `params` (array, optional): Additional query parameters. + +**Example:** +```php +$usage = $client->api('copilotUsage')->enterpriseUsageSummary('KnpLabs'); +``` + +### Enterprise Team Usage Summary + +Retrieve the usage summary for a specific team within an enterprise. + +**Method:** `GET` + +**Endpoint:** `/enterprises/{enterprise}/team/{team}/copilot/usage` + +**Parameters:** +- `enterprise` (string): The name of the enterprise. +- `team` (string): The name of the team. +- `params` (array, optional): Additional query parameters. + +**Example:** +```php +$usage = $client->api('copilotUsage')->enterpriseTeamUsageSummary('KnpLabs', 'developers'); +``` diff --git a/lib/Github/Api/Copilot/Usage.php b/lib/Github/Api/Copilot/Usage.php new file mode 100644 index 00000000000..0110a58bb40 --- /dev/null +++ b/lib/Github/Api/Copilot/Usage.php @@ -0,0 +1,34 @@ +get('/orgs/'.rawurlencode($organization).'/copilot/usage', $params); + } + + public function orgTeamUsageSummary(string $organization, string $teamSlug, array $params = []): array + { + return $this->get( + '/orgs/'.rawurlencode($organization).'/team/'.rawurlencode($teamSlug).'/copilot/usage', + $params + ); + } + + public function enterpriseUsageSummary(string $enterprise, array $params = []): array + { + return $this->get('/enterprises/'.rawurlencode($enterprise).'/copilot/usage', $params); + } + + public function enterpriseTeamUsageSummary(string $enterprise, string $teamSlug, array $params = []): array + { + return $this->get( + '/enterprises/'.rawurlencode($enterprise).'/team/'.rawurlencode($teamSlug).'/copilot/usage', + $params + ); + } +} diff --git a/lib/Github/Client.php b/lib/Github/Client.php index 77fcc7b71a2..49ff9e1a9bc 100644 --- a/lib/Github/Client.php +++ b/lib/Github/Client.php @@ -301,6 +301,11 @@ public function api($name): AbstractApi $api = new Api\Organization\OutsideCollaborators($this); break; + case 'copilotUsage': + case 'copilot_usage': + $api = new Api\Copilot\Usage($this); + break; + default: throw new InvalidArgumentException(sprintf('Undefined api instance called: "%s"', $name)); } diff --git a/test/Github/Tests/Api/Copilot/UsageTest.php b/test/Github/Tests/Api/Copilot/UsageTest.php new file mode 100644 index 00000000000..c14c3e3ffa8 --- /dev/null +++ b/test/Github/Tests/Api/Copilot/UsageTest.php @@ -0,0 +1,78 @@ +getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/orgs/KnpLabs/copilot/usage', []) + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->orgUsageSummary('KnpLabs')); + } + + /** + * @test + */ + public function shouldGetOrgTeamUsageSummary(): void + { + $expectedValue = ['usage1', 'usage2']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/orgs/KnpLabs/team/php-github-api/copilot/usage', []) + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->orgTeamUsageSummary('KnpLabs', 'php-github-api')); + } + + /** + * @test + */ + public function shouldGetEnterpriseUsageSummary(): void + { + $expectedValue = ['usage1', 'usage2']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/enterprises/KnpLabs/copilot/usage', []) + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->enterpriseUsageSummary('KnpLabs')); + } + + /** + * @test + */ + public function shouldGetEnterpriseTeamUsageSummary(): void + { + $expectedValue = ['usage1', 'usage2']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/enterprises/KnpLabs/team/php-github-api/copilot/usage', []) + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->enterpriseTeamUsageSummary('KnpLabs', 'php-github-api')); + } + + protected function getApiClass(): string + { + return Usage::class; + } +} From d4b7a1c00e22c1ca32408ecdd4e33c674196b1bc Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Mon, 23 Sep 2024 21:00:43 +0200 Subject: [PATCH 91/98] Update changelog for 3.15.0 release --- CHANGELOG-3.X.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG-3.X.md b/CHANGELOG-3.X.md index d94de7504b2..f892d41eaac 100644 --- a/CHANGELOG-3.X.md +++ b/CHANGELOG-3.X.md @@ -1,5 +1,13 @@ # Changelog +## 3.15.0 + +### Added +- Fix implicit nullable types to avoid PHP 8.4 warnings ([eiriksm](https://github.com/eiriksm), [acrobat](https://github.com/acrobat)) [#1144](https://github.com/KnpLabs/php-github-api/issues/1144) +- Add API endpoints to interact with organization roles ([glaubinix](https://github.com/glaubinix)) [#1143](https://github.com/KnpLabs/php-github-api/issues/1143) +- Copilot Usage Endpoints ([anthony-webart](https://github.com/anthony-webart)) [#1142](https://github.com/KnpLabs/php-github-api/issues/1142) +- Fix type error in ResultPager::fetch ([nunoplopes](https://github.com/nunoplopes)) [#1132](https://github.com/KnpLabs/php-github-api/issues/1132) + ## 3.14.1 ### Fixed From 845545b0686e0dbbafe0972a8b5b9f86be856976 Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Mon, 23 Sep 2024 21:00:48 +0200 Subject: [PATCH 92/98] Update composer branch-alias --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index c1da1aefbca..a797918fc07 100644 --- a/composer.json +++ b/composer.json @@ -52,7 +52,7 @@ "extra": { "branch-alias": { "dev-2.x": "2.20.x-dev", - "dev-master": "3.14-dev" + "dev-master": "3.15-dev" } }, "config": { From 48e025e19dcd3d7a0a8d1a48d5df077a52454ac0 Mon Sep 17 00:00:00 2001 From: Martin Parsiegla Date: Sat, 17 Aug 2024 19:05:16 +0200 Subject: [PATCH 93/98] Add API to rerequest a check run This change adds a new method to rerequest a check run (see also https://docs.github.com/en/rest/checks/runs?apiVersion=2022-11-28#rerequest-a-check-run). --- doc/repo/check_runs.md | 6 +++++- lib/Github/Api/Repository/Checks/CheckRuns.php | 10 ++++++++++ .../Tests/Api/Repository/Checks/CheckRunsTest.php | 14 ++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/doc/repo/check_runs.md b/doc/repo/check_runs.md index b0aa4926691..3b7b69b8f86 100644 --- a/doc/repo/check_runs.md +++ b/doc/repo/check_runs.md @@ -62,6 +62,10 @@ $params = [/*...*/]; $checks = $client->api('repo')->checkRuns()->allForReference('KnpLabs', 'php-github-api', $reference, $params); ``` +### Rerequest a check run +https://docs.github.com/en/rest/reference/checks#rerequest-a-check-run - +```php +$checks = $client->api('repo')->checkRuns()->rerequest('KnpLabs', 'php-github-api', $checkRunId); +``` diff --git a/lib/Github/Api/Repository/Checks/CheckRuns.php b/lib/Github/Api/Repository/Checks/CheckRuns.php index 37968a01816..1ddee3770c8 100644 --- a/lib/Github/Api/Repository/Checks/CheckRuns.php +++ b/lib/Github/Api/Repository/Checks/CheckRuns.php @@ -83,4 +83,14 @@ public function allForReference(string $username, string $repository, string $re return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/commits/'.rawurlencode($ref).'/check-runs', $params); } + + /** + * @link https://docs.github.com/en/rest/reference/checks#rerequest-a-check-run + * + * @return array + */ + public function rerequest(string $username, string $repository, int $checkRunId) + { + return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/check-runs/'.$checkRunId.'/rerequest'); + } } diff --git a/test/Github/Tests/Api/Repository/Checks/CheckRunsTest.php b/test/Github/Tests/Api/Repository/Checks/CheckRunsTest.php index 4b7ff086ec5..66bb5277c4b 100644 --- a/test/Github/Tests/Api/Repository/Checks/CheckRunsTest.php +++ b/test/Github/Tests/Api/Repository/Checks/CheckRunsTest.php @@ -102,6 +102,20 @@ public function shouldGetAllChecksForReference() $api->allForReference('KnpLabs', 'php-github-api', 'cb4abc15424c0015b4468d73df55efb8b60a4a3d', $params); } + /** + * @test + */ + public function shouldRerequestCheckRun() + { + /** @var CheckRuns|MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('/repos/KnpLabs/php-github-api/check-runs/123/rerequest'); + + $api->rerequest('KnpLabs', 'php-github-api', 123); + } + protected function getApiClass(): string { return CheckRuns::class; From d72323c433b3b1ee78cbb29689872c526ec6a36e Mon Sep 17 00:00:00 2001 From: Luke Spencer Date: Thu, 7 Nov 2024 19:34:12 +0000 Subject: [PATCH 94/98] feature #1146 List pull requests associated with a commit (lmjhs) This PR was squashed before being merged into the 3.15-dev branch. Discussion ---------- Added missing `pulls` method to repository commits to allow fetching of pull requests for a commit sha. [List pull requests associated with a commit](https://docs.github.com/en/rest/commits/commits?apiVersion=2022-11-28#list-pull-requests-associated-with-a-commit) Commits ------- 46c18965fec4ca72d3e78769f760580926cf766c Commit Pulls 5727a4327e30301e448820750d8a98841e1ad866 Update tests c0a48e2196b8e77cc65fa71af69d7d284ecd8123 Added documentation --- doc/commits.md | 8 ++++++++ lib/Github/Api/Repository/Commits.php | 5 +++++ .../Tests/Api/Repository/CommitsTest.php | 19 +++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/doc/commits.md b/doc/commits.md index 741af0713a2..165d71ecae2 100644 --- a/doc/commits.md +++ b/doc/commits.md @@ -35,3 +35,11 @@ $commit = $client->api('repo')->commits()->compare('KnpLabs', 'php-github-api', ``` Returns an array of commits. + +### List pull requests associated with a commit + +```php +$commit = $client->api('repo')->commits()->pulls('KnpLabs', 'php-github-api', '839e5185da9434753db47959bee16642bb4f2ce4'); +``` + +Returns an array of pull requests. \ No newline at end of file diff --git a/lib/Github/Api/Repository/Commits.php b/lib/Github/Api/Repository/Commits.php index 383905d28f2..0bc5598cbff 100644 --- a/lib/Github/Api/Repository/Commits.php +++ b/lib/Github/Api/Repository/Commits.php @@ -30,4 +30,9 @@ public function show($username, $repository, $sha) { return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/commits/'.rawurlencode($sha)); } + + public function pulls($username, $repository, $sha, array $params = []) + { + return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/commits/'.rawurlencode($sha).'/pulls', $params); + } } diff --git a/test/Github/Tests/Api/Repository/CommitsTest.php b/test/Github/Tests/Api/Repository/CommitsTest.php index 25ef2536a1c..9d1b3288afe 100644 --- a/test/Github/Tests/Api/Repository/CommitsTest.php +++ b/test/Github/Tests/Api/Repository/CommitsTest.php @@ -55,6 +55,25 @@ public function shouldShowCommitUsingSha() $this->assertEquals($expectedValue, $api->show('KnpLabs', 'php-github-api', 123)); } + /** + * @test + */ + public function shouldGetAllPullRequestsUsingSha() + { + $expectedValue = [ + ['number' => '1', 'title' => 'My first PR'], + ['number' => '2', 'title' => 'Another PR'], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/repos/KnpLabs/php-github-api/commits/123/pulls') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->pulls('KnpLabs', 'php-github-api', 123)); + } + /** * @return string */ From 25d7bafd6b0dd088d4850aef7fcc74dc4fba8b28 Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Thu, 7 Nov 2024 20:35:30 +0100 Subject: [PATCH 95/98] Update changelog for 3.16.0 release --- CHANGELOG-3.X.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG-3.X.md b/CHANGELOG-3.X.md index f892d41eaac..f26bcc96430 100644 --- a/CHANGELOG-3.X.md +++ b/CHANGELOG-3.X.md @@ -1,5 +1,11 @@ # Changelog +## 3.16.0 + +### Added +- Add API to rerequest a check run ([Spea](https://github.com/Spea)) [#1141](https://github.com/KnpLabs/php-github-api/issues/1141) +- List pull requests associated with a commit ([lmjhs](https://github.com/lmjhs)) [#1146](https://github.com/KnpLabs/php-github-api/issues/1146) + ## 3.15.0 ### Added From 663af584732bb385df7bc6b2a9daba8cc1032418 Mon Sep 17 00:00:00 2001 From: Jeroen Thora Date: Thu, 7 Nov 2024 20:35:35 +0100 Subject: [PATCH 96/98] Update composer branch-alias --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index a797918fc07..da450bc019d 100644 --- a/composer.json +++ b/composer.json @@ -52,7 +52,7 @@ "extra": { "branch-alias": { "dev-2.x": "2.20.x-dev", - "dev-master": "3.15-dev" + "dev-master": "3.16-dev" } }, "config": { From e01e2af5eb761b4498347a9e43ee93df2bdb8646 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 03:26:59 +0000 Subject: [PATCH 97/98] Bump actions/checkout from 4 to 5 Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/backwards-compatibility.yml | 2 +- .github/workflows/ci.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/backwards-compatibility.yml b/.github/workflows/backwards-compatibility.yml index e6418f67a84..93dd8cc62cc 100644 --- a/.github/workflows/backwards-compatibility.yml +++ b/.github/workflows/backwards-compatibility.yml @@ -8,7 +8,7 @@ jobs: name: "Roave BC check" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 0 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9c46d891719..c8448f615c9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -35,7 +35,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: shivammathur/setup-php@v2 with: From 9a251633179586d739ea2152fe5bad28e6df6a43 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 02:03:56 +0000 Subject: [PATCH 98/98] Bump actions/checkout from 5 to 6 Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/backwards-compatibility.yml | 2 +- .github/workflows/ci.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/backwards-compatibility.yml b/.github/workflows/backwards-compatibility.yml index 93dd8cc62cc..8d13b2d512e 100644 --- a/.github/workflows/backwards-compatibility.yml +++ b/.github/workflows/backwards-compatibility.yml @@ -8,7 +8,7 @@ jobs: name: "Roave BC check" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: fetch-depth: 0 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c8448f615c9..26fa98818e2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -35,7 +35,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: shivammathur/setup-php@v2 with: