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/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..62a6bdc9a5d --- /dev/null +++ b/lib/Github/Api/Repository/CustomProperties.php @@ -0,0 +1,63 @@ + + */ +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. + * + * @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)) { + 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 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 new file mode 100644 index 00000000000..18b31f0f45e --- /dev/null +++ b/test/Github/Tests/Api/Repository/CustomPropertiesTest.php @@ -0,0 +1,88 @@ + '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(); + $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(); + $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 testUpdate() + { + $params = [ + 'property1' => 'newValue1', + 'property2' => 42, + ]; + + $expectedResponse = [ + 'property1' => 'newValue1', + 'property2' => 42, + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('patch') + ->with('/repos/owner/repo/properties/values', $params) + ->willReturn($expectedResponse); + + $this->assertEquals($expectedResponse, $api->update('owner', 'repo', $params)); + } + + protected function getApiClass() + { + return CustomProperties::class; + } +}