From 0005d74ae5b9f07b8af02d429cd1170380974606 Mon Sep 17 00:00:00 2001 From: Matthew Simo Date: Fri, 23 Aug 2013 17:43:33 -0500 Subject: [PATCH 1/4] Add Class for releases. --- lib/Github/Api/Repo.php | 12 ++++++ lib/Github/Api/Repository/Releases.php | 52 ++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 lib/Github/Api/Repository/Releases.php diff --git a/lib/Github/Api/Repo.php b/lib/Github/Api/Repo.php index e61c9c6c02b..71cd726f380 100644 --- a/lib/Github/Api/Repo.php +++ b/lib/Github/Api/Repo.php @@ -8,6 +8,7 @@ use Github\Api\Repository\Contents; use Github\Api\Repository\DeployKeys; use Github\Api\Repository\Downloads; +use Github\Api\Repository\Releases; use Github\Api\Repository\Forks; use Github\Api\Repository\Hooks; use Github\Api\Repository\Labels; @@ -156,6 +157,17 @@ public function downloads() return new Downloads($this->client); } + /** + * Manage the releases of a repository (Currently Undocumented) + * @link http://developer.github.com/v3/repos/ + * + * @return Releases + */ + public function releases() + { + return new Releases($this->client); + } + /** * Manage the deploy keys of a repository * @link http://developer.github.com/v3/repos/keys/ diff --git a/lib/Github/Api/Repository/Releases.php b/lib/Github/Api/Repository/Releases.php new file mode 100644 index 00000000000..f027d3194e0 --- /dev/null +++ b/lib/Github/Api/Repository/Releases.php @@ -0,0 +1,52 @@ + + */ +class Releases extends AbstractApi +{ + /** + * List releases in selected repository + * + * @param string $username the user who owns the repo + * @param string $repository the name of the repo + * + * @return array + */ + public function all($username, $repository) + { + return $this->get('repos/'.urlencode($username).'/'.urlencode($repository).'/releases'); + } + + /** + * Get a release in selected repository + * + * @param string $username the user who owns the repo + * @param string $repository the name of the repo + * @param integer $id the id of the release + * + * @return array + */ + public function show($username, $repository, $id) + { + return $this->get('repos/'.urlencode($username).'/'.urlencode($repository).'/releases/'.urlencode($id)); + } + + /** + * Delete a download in selected repository + * + * @param string $username the user who owns the repo + * @param string $repository the name of the repo + * @param integer $id the id of the release + * + * @return array + */ + public function remove($username, $repository, $id) + { + return $this->delete('repos/'.urlencode($username).'/'.urlencode($repository).'/releases/'.urlencode($id)); + } +} From 08e7c7c9e86014526340c031f96bd361ac11caaa Mon Sep 17 00:00:00 2001 From: Matthew Simo Date: Fri, 23 Aug 2013 18:23:29 -0500 Subject: [PATCH 2/4] Docs & a comment --- doc/index.md | 1 + doc/repo/releases.md | 25 +++++++++++++++++++++++++ lib/Github/Api/Repository/Releases.php | 2 +- 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 doc/repo/releases.md diff --git a/doc/index.md b/doc/index.md index 45d6622d1c1..68d1540707e 100644 --- a/doc/index.md +++ b/doc/index.md @@ -13,6 +13,7 @@ APIs: * [Pull Requests](pull_requests.md) * [Comments](pull_request/comments.md) * [Repositories](repos.md) + * [Releases](repo/releases.md) * [Users](users.md) Additional features: diff --git a/doc/repo/releases.md b/doc/repo/releases.md new file mode 100644 index 00000000000..63a4241a0b4 --- /dev/null +++ b/doc/repo/releases.md @@ -0,0 +1,25 @@ +## Repo / Releases API +[Back to the "Repos API"](../repos.md) | [Back to the navigation](../index.md) + +This Github API Endpoint is currently undocumented because it's new, but works just fine. + + +### List all releases + +```php +$releases = $client->api('repo')->releases()->all('twbs', 'bootstrap'); +``` + +### List one release + +```php +$release = $client->api('repo')->releases()->show('twbs', 'bootstrap', $id); +``` + +### Remove a release + +This works, but isn't thoroughly tested, use at your own risk. + +```php +$response = $client->api('repo')->releases()->remove('twbs', 'bootstrap', $id); +``` diff --git a/lib/Github/Api/Repository/Releases.php b/lib/Github/Api/Repository/Releases.php index f027d3194e0..3def47b154f 100644 --- a/lib/Github/Api/Repository/Releases.php +++ b/lib/Github/Api/Repository/Releases.php @@ -37,7 +37,7 @@ public function show($username, $repository, $id) } /** - * Delete a download in selected repository + * Delete a download in selected repository (Not thoroughly tested!) * * @param string $username the user who owns the repo * @param string $repository the name of the repo From 5bae94f348bed5464e308e780fb3b897d15f44d6 Mon Sep 17 00:00:00 2001 From: Evgeniy Guseletov Date: Thu, 17 Oct 2013 17:18:05 +0300 Subject: [PATCH 3/4] Add tests, add more release apis, add assets api, update docs --- composer.json | 3 + doc/index.md | 1 + doc/repo/assets.md | 30 +++++ doc/repo/releases.md | 10 ++ lib/Github/Api/Repository/Assets.php | 80 ++++++++++++ lib/Github/Api/Repository/Releases.php | 56 +++++++- test/Github/Tests/Api/RepoTest.php | 10 ++ .../Tests/Api/Repository/AssetsTest.php | 98 ++++++++++++++ .../Tests/Api/Repository/ReleasesTest.php | 123 ++++++++++++++++++ 9 files changed, 406 insertions(+), 5 deletions(-) create mode 100644 doc/repo/assets.md create mode 100644 lib/Github/Api/Repository/Assets.php create mode 100644 test/Github/Tests/Api/Repository/AssetsTest.php create mode 100644 test/Github/Tests/Api/Repository/ReleasesTest.php diff --git a/composer.json b/composer.json index 1f0c1c9f266..d3471164d68 100644 --- a/composer.json +++ b/composer.json @@ -21,6 +21,9 @@ "ext-curl": "*", "kriswallsmith/buzz": ">=0.7" }, + "require-dev": { + "phpunit/phpunit": ">=3.6.0" + }, "autoload": { "psr-0": { "Github\\": "lib/" } }, diff --git a/doc/index.md b/doc/index.md index cd98aaac896..1f447d6e457 100644 --- a/doc/index.md +++ b/doc/index.md @@ -15,6 +15,7 @@ APIs: * [Comments](pull_request/comments.md) * [Repositories](repos.md) * [Releases](repo/releases.md) + * [Assets](repo/assets.md) * [Users](users.md) Additional features: diff --git a/doc/repo/assets.md b/doc/repo/assets.md new file mode 100644 index 00000000000..05a6d9e04e7 --- /dev/null +++ b/doc/repo/assets.md @@ -0,0 +1,30 @@ +## Repo / Releases API +[Back to the "Repos API"](../repos.md) | [Back to the navigation](../index.md) + +### List all assets by release + +```php +$assets = $client->api('repo')->releases()->assets()->all('twbs', 'bootstrap', $releaseId); +``` + +### List one asset + +```php +$asset = $client->api('repo')->releases()->assets()->show('twbs', 'bootstrap', $assetId); +``` + +### Create an asset + +This feature is not implemented because require usage of `uploads.github.com` subdomain. + +### Edit an asset + +```php +$asset = $client->api('repo')->releases()->assets()->edit('twbs', 'bootstrap', $assetId, array('name' => 'New name')); +``` + +### Remove an asset + +```php +$asset = $client->api('repo')->releases()->assets()->remove('twbs', 'bootstrap', $assetId); +``` diff --git a/doc/repo/releases.md b/doc/repo/releases.md index 63a4241a0b4..cfbf5721338 100644 --- a/doc/repo/releases.md +++ b/doc/repo/releases.md @@ -16,6 +16,16 @@ $releases = $client->api('repo')->releases()->all('twbs', 'bootstrap'); $release = $client->api('repo')->releases()->show('twbs', 'bootstrap', $id); ``` +### Create a release +```php +$release = $client->api('repo')->releases()->create('twbs', 'bootstrap', array('tag_name' => 'v1.1')); +``` + +### Edit a release +```php +$release = $client->api('repo')->releases()->edit('twbs', 'bootstrap', $id, array('name' => 'New release name')); +``` + ### Remove a release This works, but isn't thoroughly tested, use at your own risk. diff --git a/lib/Github/Api/Repository/Assets.php b/lib/Github/Api/Repository/Assets.php new file mode 100644 index 00000000000..5a1137b35d6 --- /dev/null +++ b/lib/Github/Api/Repository/Assets.php @@ -0,0 +1,80 @@ + + */ +class Assets extends AbstractApi +{ + /** + * Get all release's assets in selected repository + * GET /repos/:owner/:repo/releases/:id/assets + * + * @param string $username the user who owns the repo + * @param string $repository the name of the repo + * @param integer $id the id of the release + * + * @return array + */ + public function all($username, $repository, $id) + { + return $this->get('repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/'.rawurlencode($id).'/assets'); + } + + /** + * Get an asset in selected repository's release + * GET /repos/:owner/:repo/releases/assets/:id + * + * @param string $username the user who owns the repo + * @param string $repository the name of the repo + * @param integer $id the id of the asset + * + * @return array + */ + public function show($username, $repository, $id) + { + return $this->get('repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/assets/'.rawurlencode($id)); + } + + /** + * Edit an asset in selected repository's release + * PATCH /repos/:owner/:repo/releases/assets/:id + * + * @param string $username the user who owns the repo + * @param string $repository the name of the repo + * @param integer $id the id of the asset + * @param array $params request parameters + * + * @throws MissingArgumentException + * + * @return array + */ + public function edit($username, $repository, $id, array $params) + { + if (!isset($params['name'])) { + throw new MissingArgumentException('name'); + } + + return $this->patch('repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/assets/'.rawurlencode($id), $params); + } + + /** + * Delete an asset in selected repository's release + * DELETE /repos/:owner/:repo/releases/assets/:id + * + * @param string $username the user who owns the repo + * @param string $repository the name of the repo + * @param integer $id the id of the asset + * + * @return array + */ + public function remove($username, $repository, $id) + { + return $this->delete('repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/assets/'.rawurlencode($id)); + } +} diff --git a/lib/Github/Api/Repository/Releases.php b/lib/Github/Api/Repository/Releases.php index 3def47b154f..a2ee5201ffe 100644 --- a/lib/Github/Api/Repository/Releases.php +++ b/lib/Github/Api/Repository/Releases.php @@ -3,9 +3,12 @@ namespace Github\Api\Repository; use Github\Api\AbstractApi; +use Github\Exception\MissingArgumentException; /** + * @link http://developer.github.com/v3/repos/releases/ * @author Matthew Simo + * @author Evgeniy Guseletov */ class Releases extends AbstractApi { @@ -19,7 +22,7 @@ class Releases extends AbstractApi */ public function all($username, $repository) { - return $this->get('repos/'.urlencode($username).'/'.urlencode($repository).'/releases'); + return $this->get('repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases'); } /** @@ -27,17 +30,52 @@ public function all($username, $repository) * * @param string $username the user who owns the repo * @param string $repository the name of the repo - * @param integer $id the id of the release + * @param integer $id the id of the release * * @return array */ public function show($username, $repository, $id) { - return $this->get('repos/'.urlencode($username).'/'.urlencode($repository).'/releases/'.urlencode($id)); + return $this->get('repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/'.rawurlencode($id)); + } + + /** + * Create new release in selected repository + * + * @param string $username + * @param string $repository + * @param array $params + * + * @throws MissingArgumentException + * + * @return array + */ + public function create($username, $repository, array $params) + { + if (!isset($params['tag_name'])) { + throw new MissingArgumentException('tag_name'); + } + + return $this->post('repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases', $params); + } + + /** + * Edit release in selected repository + * + * @param string $username + * @param string $repository + * @param integer $id + * @param array $params + * + * @return array + */ + public function edit($username, $repository, $id, array $params) + { + return $this->patch('repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/'.rawurlencode($id), $params); } /** - * Delete a download in selected repository (Not thoroughly tested!) + * Delete a release in selected repository (Not thoroughly tested!) * * @param string $username the user who owns the repo * @param string $repository the name of the repo @@ -47,6 +85,14 @@ public function show($username, $repository, $id) */ public function remove($username, $repository, $id) { - return $this->delete('repos/'.urlencode($username).'/'.urlencode($repository).'/releases/'.urlencode($id)); + return $this->delete('repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/'.rawurlencode($id)); + } + + /** + * @return Assets + */ + public function assets() + { + return new Assets($this->client); } } diff --git a/test/Github/Tests/Api/RepoTest.php b/test/Github/Tests/Api/RepoTest.php index 44b1a25f2d5..db125a72622 100644 --- a/test/Github/Tests/Api/RepoTest.php +++ b/test/Github/Tests/Api/RepoTest.php @@ -407,6 +407,16 @@ public function shouldGetStatusesApiObject() $this->assertInstanceOf('Github\Api\Repository\Statuses', $api->statuses()); } + /** + * @test + */ + public function shouldGetReleasesApiObject() + { + $api = $this->getApiMock(); + + $this->assertInstanceOf('Github\Api\Repository\Releases', $api->releases()); + } + protected function getApiClass() { return 'Github\Api\Repo'; diff --git a/test/Github/Tests/Api/Repository/AssetsTest.php b/test/Github/Tests/Api/Repository/AssetsTest.php new file mode 100644 index 00000000000..52347a4ec72 --- /dev/null +++ b/test/Github/Tests/Api/Repository/AssetsTest.php @@ -0,0 +1,98 @@ +getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('repos/KnpLabs/php-github-api/releases/'.$id.'/assets') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->all('KnpLabs', 'php-github-api', $id)); + } + + /** + * @test + */ + public function shouldGetSingleReleaseAsset() + { + $expectedValue = array('assetData'); + $assetId = 2; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('repos/KnpLabs/php-github-api/releases/assets/'.$assetId) + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->show('KnpLabs', 'php-github-api', $assetId)); + } + + /** + * @test + */ + public function shouldEditReleaseAsset() + { + $expectedValue = array('assetUpdatedData'); + $assetId = 5; + $data = array('name' => 'asset111_name_qweqwe'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('patch') + ->with('repos/KnpLabs/php-github-api/releases/assets/'.$assetId) + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->edit('KnpLabs', 'php-github-api', $assetId, $data)); + } + + /** + * @test + * @expectedException Github\Exception\MissingArgumentException + */ + public function shouldNotEditReleaseAssetWithoutName() + { + $assetId = 5; + $data = array('not_a_name' => 'just a value'); + + $api = $this->getApiMock(); + $api->expects($this->never()) + ->method('patch'); + + $api->edit('KnpLabs', 'php-github-api', $assetId, $data); + } + + /** + * @test + */ + public function shouldRemoveReleaseAsset() + { + $expectedValue = array('assetUpdatedData'); + $assetId = 5; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('repos/KnpLabs/php-github-api/releases/assets/'.$assetId) + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->remove('KnpLabs', 'php-github-api', $assetId)); + } + + protected function getApiClass() + { + return 'Github\Api\Repository\Assets'; + } +} diff --git a/test/Github/Tests/Api/Repository/ReleasesTest.php b/test/Github/Tests/Api/Repository/ReleasesTest.php new file mode 100644 index 00000000000..c9fac0a0f80 --- /dev/null +++ b/test/Github/Tests/Api/Repository/ReleasesTest.php @@ -0,0 +1,123 @@ +getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('repos/KnpLabs/php-github-api/releases') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->all('KnpLabs', 'php-github-api')); + } + + /** + * @test + */ + public function shouldGetSingleRepositoryRelease() + { + $expectedValue = array('releaseData'); + $id = 331; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('repos/KnpLabs/php-github-api/releases/'.$id) + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->show('KnpLabs', 'php-github-api', $id)); + } + + /** + * @test + */ + public function shouldCreateRepositoryRelease() + { + $expectedValue = array('newReleaseData'); + $data = array('tag_name' => '1.1'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('repos/KnpLabs/php-github-api/releases') + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->create('KnpLabs', 'php-github-api', $data)); + } + + /** + * @test + * @expectedException Github\Exception\MissingArgumentException + */ + public function shouldNotCreateRepositoryReleaseWithoutTagName() + { + $data = array('not_a_tag_name' => '1.1'); + + $api = $this->getApiMock(); + $api->expects($this->never()) + ->method('post'); + + $api->create('KnpLabs', 'php-github-api', $data); + } + + /** + * @test + */ + public function shouldEditRepositoryRelease() + { + $expectedValue = array('updatedData'); + $id = 332; + $data = array('some' => 'thing'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('patch') + ->with('repos/KnpLabs/php-github-api/releases/'.$id) + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->edit('KnpLabs', 'php-github-api', $id, $data)); + } + + /** + * @test + */ + public function shouldRemoveRepositoryRelease() + { + $expectedValue = array('deleted'); + $id = 333; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('repos/KnpLabs/php-github-api/releases/'.$id) + ->will($this->returnValue($expectedValue)); + + $this->assertEquals($expectedValue, $api->remove('KnpLabs', 'php-github-api', $id)); + } + + /** + * @test + */ + public function shouldGetAssetsApiObject() + { + $api = $this->getApiMock(); + + $this->assertInstanceOf('Github\Api\Repository\Assets', $api->assets()); + } + + protected function getApiClass() + { + return 'Github\Api\Repository\Releases'; + } +} From 111ac7754b989c059614b70a41c2c3992e97cd19 Mon Sep 17 00:00:00 2001 From: Evgeniy Guseletov Date: Tue, 22 Oct 2013 18:35:28 +0300 Subject: [PATCH 4/4] Add manifold preview media type --- lib/Github/Api/Repository/Assets.php | 10 ++++++++++ lib/Github/Api/Repository/Releases.php | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/lib/Github/Api/Repository/Assets.php b/lib/Github/Api/Repository/Assets.php index 5a1137b35d6..a39f4057c7d 100644 --- a/lib/Github/Api/Repository/Assets.php +++ b/lib/Github/Api/Repository/Assets.php @@ -11,6 +11,16 @@ */ class Assets extends AbstractApi { + /** + * @deprecated Will be removed as soon as gh releases api gets stable + */ + public function configure() + { + $this->client->setHeaders(array( + 'Accept: application/vnd.github.manifold-preview' + )); + } + /** * Get all release's assets in selected repository * GET /repos/:owner/:repo/releases/:id/assets diff --git a/lib/Github/Api/Repository/Releases.php b/lib/Github/Api/Repository/Releases.php index a2ee5201ffe..d276084d75d 100644 --- a/lib/Github/Api/Repository/Releases.php +++ b/lib/Github/Api/Repository/Releases.php @@ -12,6 +12,16 @@ */ class Releases extends AbstractApi { + /** + * @deprecated Will be removed as soon as gh releases api gets stable + */ + public function configure() + { + $this->client->setHeaders(array( + 'Accept: application/vnd.github.manifold-preview' + )); + } + /** * List releases in selected repository *