diff --git a/README.md b/README.md index ab5e798..c2d61dc 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,9 @@ * [Delete a package](#delete-a-package) * [List all dependents of a package](#list-all-dependents-of-a-package) * [List all customers with access to a package](#list-all-customers-with-access-to-a-package) + * [Create an artifact package file](#create-an-artifact-package-file) + * [Create an artifact package](#create-an-artifact-package) + * [Update artifact files of a package](#update-artifact-files-of-a-package) * [Credential](#credential) * [List an organization's credentials](#list-an-organizations-credentials) * [Show a credential](#show-a-credential) @@ -95,7 +98,7 @@ * [Validate incoming webhook payloads](#validate-incoming-webhook-payloads) * [License](#license) - + @@ -575,6 +578,30 @@ $client->packages()->listCustomers('acme-website/package'); ``` Returns a list of customers with access to the package. +#### Create an artifact package file + +```php +$fileName = 'package1.zip'; // your package archive artifact containing a valid composer.json in root directory +$file = file_get_contents($fileName); +$client->packages()->artifacts()->create($file, 'application/zip', $fileName); +``` + +#### Create an artifact package + +```php +$fileName = 'package1.zip'; +$file = file_get_contents($fileName); +$response = $client->packages()->artifacts()->create($file, 'application/zip', $fileName); +$artifactId = $response['id']; +$client->packages()->createArtifactPackage([$artifactId]); +``` +#### Update artifact files of a package + +```php +$result = $client->packages()->packages()->artifacts()->showPackageArtifacts('acme-website/package'); // get artifact files details for a package +$artifactFileIds = [42, 43]; +$client->packages()->editArtifactPackage('acme-website/package', $artifactFileIds); +``` ### Credential #### List an organization's credentials diff --git a/src/Api/AbstractApi.php b/src/Api/AbstractApi.php index 69de313..f0c16e7 100644 --- a/src/Api/AbstractApi.php +++ b/src/Api/AbstractApi.php @@ -67,6 +67,19 @@ protected function post($path, array $parameters = [], array $headers = []) return $this->responseMediator->getContent($response); } + protected function postFile($path, $rawFileContent, array $headers = []) + { + $response = $this->client->getHttpClient()->post( + $path, + array_merge($headers, [ + 'Accept' => 'application/json', + ]), + $rawFileContent + ); + + return $this->responseMediator->getContent($response); + } + /** * @param string $path * @param array $parameters diff --git a/src/Api/Packages.php b/src/Api/Packages.php index d9962c6..6735717 100644 --- a/src/Api/Packages.php +++ b/src/Api/Packages.php @@ -9,6 +9,7 @@ namespace PrivatePackagist\ApiClient\Api; +use PrivatePackagist\ApiClient\Api\Packages\Artifacts; use PrivatePackagist\ApiClient\Exception\InvalidArgumentException; class Packages extends AbstractApi @@ -67,6 +68,11 @@ public function createCustomPackage($customJson, $credentialId = null) return $this->post('/packages/', ['repoType' => 'package', 'repoConfig' => $customJson, 'credentials' => $credentialId]); } + + public function createArtifactPackage(array $artifactPackageFileIds) + { + return $this->post('/packages/', ['repoType' => 'artifact', 'artifactIds' => $artifactPackageFileIds]); + } /** * @deprecated Use editVcsPackage instead @@ -81,6 +87,11 @@ public function editVcsPackage($packageName, $url, $credentialId = null, $type = return $this->put(sprintf('/packages/%s/', $packageName), ['repoType' => $type, 'repoUrl' => $url, 'credentials' => $credentialId]); } + public function editArtifactPackage($packageName, array $artifactPackageFileIds) + { + return $this->put(sprintf('/packages/%s/', $packageName), ['repoType' => 'artifact', 'artifactIds' => $artifactPackageFileIds]); + } + /** * @deprecated Use editCustomPackage instead */ @@ -108,4 +119,9 @@ public function listDependents($packageName) { return $this->get(sprintf('/packages/%s/dependents/', $packageName)); } + + public function artifacts() + { + return new Artifacts($this->client, $this->client->getResponseMediator()); + } } diff --git a/src/Api/Packages/Artifacts.php b/src/Api/Packages/Artifacts.php new file mode 100644 index 0000000..0502d9a --- /dev/null +++ b/src/Api/Packages/Artifacts.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PrivatePackagist\ApiClient\Api\Packages; + +use PrivatePackagist\ApiClient\Api\AbstractApi; + +class Artifacts extends AbstractApi +{ + public function create($file, $contentType, $fileName) + { + return $this->postFile('/packages/artifacts/', $file, array_filter([ + 'Content-Type' => $contentType, + 'X-FILENAME' => $fileName + ])); + } + + public function show($artifactId) + { + return $this->get(sprintf('/packages/artifacts/%s/', $artifactId)); + } + + public function showPackageArtifacts($packageName) + { + return $this->get(sprintf('/packages/%s/artifacts/', $packageName)); + } +} diff --git a/src/Client.php b/src/Client.php index 5741e48..2962c15 100644 --- a/src/Client.php +++ b/src/Client.php @@ -103,6 +103,11 @@ public function getHttpClient() return $this->getHttpClientBuilder()->getHttpClient(); } + public function getResponseMediator() + { + return $this->responseMediator; + } + protected function getHttpClientBuilder() { return $this->httpClientBuilder; diff --git a/tests/Api/ApiTestCase.php b/tests/Api/ApiTestCase.php index f66f695..c42e0fd 100644 --- a/tests/Api/ApiTestCase.php +++ b/tests/Api/ApiTestCase.php @@ -38,7 +38,7 @@ protected function getApiMock() $client = new Client(new HttpPluginClientBuilder($httpClient)); return $this->getMockBuilder($this->getApiClass()) - ->setMethods(['get', 'post', 'patch', 'delete', 'put', 'head']) + ->setMethods(['get', 'post', 'postFile', 'patch', 'delete', 'put', 'head']) ->setConstructorArgs([$client]) ->getMock(); } diff --git a/tests/Api/Packages/ArtifactsTest.php b/tests/Api/Packages/ArtifactsTest.php new file mode 100644 index 0000000..2a3c338 --- /dev/null +++ b/tests/Api/Packages/ArtifactsTest.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PrivatePackagist\ApiClient\Api\Packages; + +use PrivatePackagist\ApiClient\Api\ApiTestCase; + +class ArtifactsTest extends ApiTestCase +{ + public function testCreate() + { + $expected = [ + 'id' => 1, + ]; + $rawFileContent = 'foobar'; + $headers = [ + 'Content-Type' => 'application/zip', + 'X-FILENAME' => 'file.zip' + ]; + + /** @var Artifacts&\PHPUnit_Framework_MockObject_MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('postFile') + ->with($this->equalTo('/packages/artifacts/'), $rawFileContent, $headers) + ->willReturn($expected); + + + $this->assertSame($expected, $api->create($rawFileContent, $headers['Content-Type'], $headers['X-FILENAME'])); + } + + public function testShow() + { + $expected = [ + 'repoType' => 'artifact', + 'artifactPackageFileIds' =>[1, 2], + ]; + + /** @var Artifacts&\PHPUnit_Framework_MockObject_MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with($this->equalTo('/packages/artifacts/1/')) + ->willReturn($expected); + + $this->assertSame($expected, $api->show('1')); + } + + public function testShowPackageArtifacts() + { + $expected = [ + 'name' => 'acme-website/package', + 'repoType' => 'artifact', + 'artifactFiles' => 'artifact', + ]; + + /** @var Artifacts&\PHPUnit_Framework_MockObject_MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with($this->equalTo('/packages/acme-website/package/artifacts/')) + ->willReturn($expected); + + $this->assertSame($expected, $api->showPackageArtifacts('acme-website/package')); + } + + /** + * @return string + */ + protected function getApiClass() + { + return Artifacts::class; + } +} diff --git a/tests/Api/PackagesTest.php b/tests/Api/PackagesTest.php index 584787e..d89e9b1 100644 --- a/tests/Api/PackagesTest.php +++ b/tests/Api/PackagesTest.php @@ -124,6 +124,23 @@ public function testCreateCustomPackage($customJson) $this->assertSame($expected, $api->createCustomPackage($customJson)); } + public function testCreateArtifactPackage() + { + $expected = [ + 'id' => 'job-id', + 'status' => 'queued', + ]; + + /** @var Packages&\PHPUnit_Framework_MockObject_MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with($this->equalTo('/packages/'), $this->equalTo(['repoType' => 'artifact', 'artifactIds' => [42]])) + ->willReturn($expected); + + $this->assertSame($expected, $api->createArtifactPackage([42])); + } + public function customProvider() { return [ @@ -166,6 +183,23 @@ public function testEditCustomPackage() $this->assertSame($expected, $api->editCustomPackage('acme-website/package', '{}')); } + public function testEditArtifactPackage() + { + $expected = [ + 'id' => 'job-id', + 'status' => 'queued', + ]; + + /** @var Packages&\PHPUnit_Framework_MockObject_MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('put') + ->with($this->equalTo('/packages/acme-website/package/'), $this->equalTo(['repoType' => 'artifact', 'artifactIds' => [1, 3]])) + ->willReturn($expected); + + $this->assertSame($expected, $api->editArtifactPackage('acme-website/package', [1, 3])); + } + public function testRemove() { $expected = [];