From 5d678fd561435a6c99adc1a222f877271250aa38 Mon Sep 17 00:00:00 2001 From: SmithCZE Date: Tue, 7 Jan 2025 19:38:14 +0100 Subject: [PATCH 1/4] Add support custom properties --- lib/Github/Api/Repo.php | 13 +++ .../Api/Repository/CustomProperties.php | 60 +++++++++++++ .../Api/Repository/CustomPropertiesTest.php | 84 +++++++++++++++++++ 3 files changed, 157 insertions(+) create mode 100644 lib/Github/Api/Repository/CustomProperties.php create mode 100644 test/Github/Tests/Api/Repository/CustomPropertiesTest.php diff --git a/lib/Github/Api/Repo.php b/lib/Github/Api/Repo.php index 5653ae4c152..6c65514e3a4 100644 --- a/lib/Github/Api/Repo.php +++ b/lib/Github/Api/Repo.php @@ -15,6 +15,7 @@ use Github\Api\Repository\Comments; use Github\Api\Repository\Commits; use Github\Api\Repository\Contents; +use Github\Api\Repository\CustomProperties; use Github\Api\Repository\DeployKeys; use Github\Api\Repository\Downloads; use Github\Api\Repository\Forks; @@ -523,6 +524,18 @@ public function statuses() return new Statuses($this->getClient()); } + /** + * Manage the custom properties of a repository. + * + * @link https://docs.github.com/en/rest/repos/custom-properties + * + * @return CustomProperties + */ + public function customProperties() + { + return new CustomProperties($this->getClient()); + } + /** * Get the branch(es) of a repository. * diff --git a/lib/Github/Api/Repository/CustomProperties.php b/lib/Github/Api/Repository/CustomProperties.php new file mode 100644 index 00000000000..132f3cb4872 --- /dev/null +++ b/lib/Github/Api/Repository/CustomProperties.php @@ -0,0 +1,60 @@ + + */ +class CustomProperties extends AbstractApi +{ + /** + * @param string $owner The account owner of the repository. + * @param string $repository The name of the repository. + * @return array|string + */ + public function all(string $owner, string $repository) + { + return $this->get('/repos/' . rawurlencode($owner) . '/' . rawurlencode($repository) . '/properties/values'); + } + + /** + * @param string $owner The account owner of the repository. + * @param string $repository The name of the repository. + * @param string $propertyName The name of the property to retrieve. + * @return array + * @throws RuntimeException if the property is not found. + */ + public function show(string $owner, string $repository, string $propertyName) + { + $allProperties = $this->all($owner, $repository); + + if(!is_array($allProperties)) { + throw new RuntimeException('Unexpected response from GitHub API.'); + } + + foreach ($allProperties as $property => $value) { + if ($property === $propertyName) { + return ['property_name' => $property, 'value' => $value]; + } + } + + throw new RuntimeException("Property '{$propertyName}' not found."); + } + + /** + * @param string $owner The account owner of the repository. + * @param string $repository The name of the repository. + * @param array $params + * @return array|string + */ + public function createOrUpdate(string $owner, string $repository, array $params) + { + return $this->patch('/repos/' . rawurlencode($owner) . '/' . rawurlencode($repository) . '/properties/values', $params); + } + +} diff --git a/test/Github/Tests/Api/Repository/CustomPropertiesTest.php b/test/Github/Tests/Api/Repository/CustomPropertiesTest.php new file mode 100644 index 00000000000..d3827eeda31 --- /dev/null +++ b/test/Github/Tests/Api/Repository/CustomPropertiesTest.php @@ -0,0 +1,84 @@ + 'value1', 'property2' => 'value2']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('/repos/owner/repo/properties/values') + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->all('owner', 'repo')); + } + + public function testShowPropertyExists() + { + $allProperties = [ + 'property1' => 'value1', + 'property2' => 'value2', + ]; + + $api = $this->getApiMock(CustomProperties::class); + $api->expects($this->once()) + ->method('get') + ->with('/repos/owner/repo/properties/values') + ->willReturn($allProperties); + + $expectedResult = ['property_name' =>'property2', 'value' => 'value2']; + $this->assertEquals($expectedResult, $api->show('owner', 'repo', 'property2')); + } + + public function testShowPropertyDoesNotExist() + { + $allProperties = [ + 'property1' => 'value1', + 'property2' => 'value2', + ]; + + $api = $this->getApiMock(CustomProperties::class); + $api->expects($this->once()) + ->method('get') + ->with('/repos/owner/repo/properties/values') + ->willReturn($allProperties); + + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage("Property 'property3' not found."); + + $api->show('owner', 'repo', 'property3'); + } + + public function testCreateOrUpdate() + { + $params = [ + 'property1' => 'newValue1', + 'property2' => 42, + ]; + + $expectedResponse = [ + 'property1' => 'newValue1', + 'property2' => 42, + ]; + + $api = $this->getApiMock(CustomProperties::class); + $api->expects($this->once()) + ->method('patch') + ->with('/repos/owner/repo/properties/values', $params) + ->willReturn($expectedResponse); + + $this->assertEquals($expectedResponse, $api->createOrUpdate('owner', 'repo', $params)); + } + + protected function getApiClass() + { + return CustomProperties::class; + } +} From dcd8ded4975334b34073a9ef94118773736b5b1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Nykl=C3=AD=C4=8Dek?= <60318239+ONyklicek@users.noreply.github.com> Date: Tue, 7 Jan 2025 22:26:59 +0100 Subject: [PATCH 2/4] Adding API endpoints to interact with custom properties --- doc/repo/custom_properties.md | 28 +++++++++++++++++++ .../Api/Repository/CustomProperties.php | 9 +++--- .../Api/Repository/CustomPropertiesTest.php | 12 ++++---- 3 files changed, 38 insertions(+), 11 deletions(-) create mode 100644 doc/repo/custom_properties.md diff --git a/doc/repo/custom_properties.md b/doc/repo/custom_properties.md new file mode 100644 index 00000000000..bc987c4da20 --- /dev/null +++ b/doc/repo/custom_properties.md @@ -0,0 +1,28 @@ +## Repo / Custom Properties 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#custom-properties-for-a-repository) + +### List custom properties for a repository + +```php +$properties = $client->api('repo')->properties()->all('twbs', 'bootstrap'); +``` + +### Get a custom property for a repository + +```php +$property = $client->api('repo')->properties()->show('twbs', 'bootstrap', $propertyName); +``` + + +### Update a custom property for a repository + +```php +$parameters = [ + 'property_name' => 'foo', + 'value' => 'bar' +] + +$property = $client->api('repo')->properties()->update('twbs', 'bootstrap', $params); +``` diff --git a/lib/Github/Api/Repository/CustomProperties.php b/lib/Github/Api/Repository/CustomProperties.php index 132f3cb4872..3d98c5f102d 100644 --- a/lib/Github/Api/Repository/CustomProperties.php +++ b/lib/Github/Api/Repository/CustomProperties.php @@ -29,7 +29,7 @@ public function all(string $owner, string $repository) * @return array * @throws RuntimeException if the property is not found. */ - public function show(string $owner, string $repository, string $propertyName) + public function show(string $owner, string $repository, string $propertyName): array { $allProperties = $this->all($owner, $repository); @@ -43,18 +43,17 @@ public function show(string $owner, string $repository, string $propertyName) } } - throw new RuntimeException("Property '{$propertyName}' not found."); + throw new RuntimeException("Property [$propertyName] not found."); } /** * @param string $owner The account owner of the repository. * @param string $repository The name of the repository. - * @param array $params + * @param array $params * @return array|string */ - public function createOrUpdate(string $owner, string $repository, array $params) + public function update(string $owner, string $repository, array $params) { return $this->patch('/repos/' . rawurlencode($owner) . '/' . rawurlencode($repository) . '/properties/values', $params); } - } diff --git a/test/Github/Tests/Api/Repository/CustomPropertiesTest.php b/test/Github/Tests/Api/Repository/CustomPropertiesTest.php index d3827eeda31..3676764b13c 100644 --- a/test/Github/Tests/Api/Repository/CustomPropertiesTest.php +++ b/test/Github/Tests/Api/Repository/CustomPropertiesTest.php @@ -27,7 +27,7 @@ public function testShowPropertyExists() 'property2' => 'value2', ]; - $api = $this->getApiMock(CustomProperties::class); + $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') ->with('/repos/owner/repo/properties/values') @@ -44,19 +44,19 @@ public function testShowPropertyDoesNotExist() 'property2' => 'value2', ]; - $api = $this->getApiMock(CustomProperties::class); + $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') ->with('/repos/owner/repo/properties/values') ->willReturn($allProperties); $this->expectException(\RuntimeException::class); - $this->expectExceptionMessage("Property 'property3' not found."); + $this->expectExceptionMessage("Property [property3] not found."); $api->show('owner', 'repo', 'property3'); } - public function testCreateOrUpdate() + public function testUpdate() { $params = [ 'property1' => 'newValue1', @@ -68,13 +68,13 @@ public function testCreateOrUpdate() 'property2' => 42, ]; - $api = $this->getApiMock(CustomProperties::class); + $api = $this->getApiMock(); $api->expects($this->once()) ->method('patch') ->with('/repos/owner/repo/properties/values', $params) ->willReturn($expectedResponse); - $this->assertEquals($expectedResponse, $api->createOrUpdate('owner', 'repo', $params)); + $this->assertEquals($expectedResponse, $api->update('owner', 'repo', $params)); } protected function getApiClass() From 82fc88a44d04818752e1e8896f6ea53fb6582a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Nykl=C3=AD=C4=8Dek?= <60318239+ONyklicek@users.noreply.github.com> Date: Tue, 7 Jan 2025 22:39:33 +0100 Subject: [PATCH 3/4] Adding API endpoints to interact with custom properties --- .../Api/Repository/CustomProperties.php | 20 ++++++++++--------- .../Api/Repository/CustomPropertiesTest.php | 8 ++++++-- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/lib/Github/Api/Repository/CustomProperties.php b/lib/Github/Api/Repository/CustomProperties.php index 3d98c5f102d..83531103064 100644 --- a/lib/Github/Api/Repository/CustomProperties.php +++ b/lib/Github/Api/Repository/CustomProperties.php @@ -13,27 +13,29 @@ class CustomProperties extends AbstractApi { /** - * @param string $owner The account owner of the repository. + * @param string $owner The account owner of the repository. * @param string $repository The name of the repository. * @return array|string */ public function all(string $owner, string $repository) { - return $this->get('/repos/' . rawurlencode($owner) . '/' . rawurlencode($repository) . '/properties/values'); + return $this->get('/repos/'.rawurlencode($owner).'/'.rawurlencode($repository).'/properties/values'); } /** - * @param string $owner The account owner of the repository. - * @param string $repository The name of the repository. + * @param string $owner The account owner of the repository. + * @param string $repository The name of the repository. * @param string $propertyName The name of the property to retrieve. - * @return array + * * @throws RuntimeException if the property is not found. + * + * @return array */ public function show(string $owner, string $repository, string $propertyName): array { $allProperties = $this->all($owner, $repository); - if(!is_array($allProperties)) { + if (!is_array($allProperties)) { throw new RuntimeException('Unexpected response from GitHub API.'); } @@ -47,13 +49,13 @@ public function show(string $owner, string $repository, string $propertyName): a } /** - * @param string $owner The account owner of the repository. - * @param string $repository The name of the repository. + * @param string $owner The account owner of the repository. + * @param string $repository The name of the repository. * @param array $params * @return array|string */ public function update(string $owner, string $repository, array $params) { - return $this->patch('/repos/' . rawurlencode($owner) . '/' . rawurlencode($repository) . '/properties/values', $params); + return $this->patch('/repos/'.rawurlencode($owner).'/'.rawurlencode($repository).'/properties/values', $params); } } diff --git a/test/Github/Tests/Api/Repository/CustomPropertiesTest.php b/test/Github/Tests/Api/Repository/CustomPropertiesTest.php index 3676764b13c..b77de94895e 100644 --- a/test/Github/Tests/Api/Repository/CustomPropertiesTest.php +++ b/test/Github/Tests/Api/Repository/CustomPropertiesTest.php @@ -33,7 +33,11 @@ public function testShowPropertyExists() ->with('/repos/owner/repo/properties/values') ->willReturn($allProperties); - $expectedResult = ['property_name' =>'property2', 'value' => 'value2']; + $expectedResult = [ + 'property_name' => 'property2', + 'value' => 'value2' + ]; + $this->assertEquals($expectedResult, $api->show('owner', 'repo', 'property2')); } @@ -51,7 +55,7 @@ public function testShowPropertyDoesNotExist() ->willReturn($allProperties); $this->expectException(\RuntimeException::class); - $this->expectExceptionMessage("Property [property3] not found."); + $this->expectExceptionMessage('Property [property3] not found.'); $api->show('owner', 'repo', 'property3'); } From 3d1100e45b7d3675e96b0d535c8d989dd6decde7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Nykl=C3=AD=C4=8Dek?= <60318239+ONyklicek@users.noreply.github.com> Date: Tue, 7 Jan 2025 22:41:12 +0100 Subject: [PATCH 4/4] Adding API endpoints to interact with custom properties --- lib/Github/Api/Repository/CustomProperties.php | 2 ++ test/Github/Tests/Api/Repository/CustomPropertiesTest.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/Github/Api/Repository/CustomProperties.php b/lib/Github/Api/Repository/CustomProperties.php index 83531103064..62a6bdc9a5d 100644 --- a/lib/Github/Api/Repository/CustomProperties.php +++ b/lib/Github/Api/Repository/CustomProperties.php @@ -15,6 +15,7 @@ class CustomProperties extends AbstractApi /** * @param string $owner The account owner of the repository. * @param string $repository The name of the repository. + * * @return array|string */ public function all(string $owner, string $repository) @@ -52,6 +53,7 @@ public function show(string $owner, string $repository, string $propertyName): a * @param string $owner The account owner of the repository. * @param string $repository The name of the repository. * @param array $params + * * @return array|string */ public function update(string $owner, string $repository, array $params) diff --git a/test/Github/Tests/Api/Repository/CustomPropertiesTest.php b/test/Github/Tests/Api/Repository/CustomPropertiesTest.php index b77de94895e..18b31f0f45e 100644 --- a/test/Github/Tests/Api/Repository/CustomPropertiesTest.php +++ b/test/Github/Tests/Api/Repository/CustomPropertiesTest.php @@ -35,7 +35,7 @@ public function testShowPropertyExists() $expectedResult = [ 'property_name' => 'property2', - 'value' => 'value2' + 'value' => 'value2', ]; $this->assertEquals($expectedResult, $api->show('owner', 'repo', 'property2'));