diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f39d234..e14ab8b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Add support for project integrations endpoints * Add support for `Projects::updateDeployKey` * Add support for project push rules +* Add support for additional parameters in `Projects::fork` * Add support for group hook endpoints * Add support for `job_inputs` and `job_variables_attributes` in `Jobs::play` * Add support for `inputs` in `Projects::createPipeline` diff --git a/src/Api/Projects.php b/src/Api/Projects.php index 4a3dcc35..88b2c5fc 100644 --- a/src/Api/Projects.php +++ b/src/Api/Projects.php @@ -945,19 +945,52 @@ public function forks(int|string $project_id, array $parameters = []): mixed /** * @param array $parameters { * - * @var string $namespace The ID or path of the namespace that the project will be forked to - * @var string $path The path of the forked project (optional) - * @var string $name The name of the forked project (optional) + * @var string $branches Branches to fork (empty for all branches) + * @var string $description The description assigned to the resultant project after forking + * @var bool $mr_default_target_self For forked projects, target merge requests to this project + * @var string $name The name assigned to the resultant project after forking + * @var int $namespace_id The ID of the namespace that the project is forked to + * @var string $namespace_path The path of the namespace that the project is forked to + * @var int|string $namespace deprecated; use namespace_id or namespace_path instead + * @var string $path The path assigned to the resultant project after forking + * @var string $visibility The visibility level assigned to the resultant project after forking * } + * + * @throws UndefinedOptionsException If an option name is undefined + * @throws InvalidOptionsException If an option doesn't fulfill the specified validation rules */ public function fork(int|string $project_id, array $parameters = []): mixed { $resolver = new OptionsResolver(); - $resolver->setDefined(['namespace', 'path', 'name']); - - $resolved = $resolver->resolve($parameters); + $resolver->setDefined('branches') + ->setAllowedTypes('branches', 'string') + ; + $resolver->setDefined('description') + ->setAllowedTypes('description', 'string') + ; + $resolver->setDefined('mr_default_target_self') + ->setAllowedTypes('mr_default_target_self', 'bool') + ; + $resolver->setDefined('name') + ->setAllowedTypes('name', 'string') + ; + $resolver->setDefined('namespace_id') + ->setAllowedTypes('namespace_id', 'int') + ; + $resolver->setDefined('namespace_path') + ->setAllowedTypes('namespace_path', 'string') + ; + $resolver->setDefined('namespace') + ->setAllowedTypes('namespace', ['int', 'string']) + ; + $resolver->setDefined('path') + ->setAllowedTypes('path', 'string') + ; + $resolver->setDefined('visibility') + ->setAllowedValues('visibility', ['public', 'internal', 'private']) + ; - return $this->post($this->getProjectPath($project_id, 'fork'), $resolved); + return $this->post($this->getProjectPath($project_id, 'fork'), $resolver->resolve($parameters)); } public function createForkRelation(int|string $project_id, int|string $forked_project_id): mixed diff --git a/tests/Api/ProjectsTest.php b/tests/Api/ProjectsTest.php index f341613b..4d6297c3 100644 --- a/tests/Api/ProjectsTest.php +++ b/tests/Api/ProjectsTest.php @@ -1936,6 +1936,42 @@ public function shouldForkWithNamespace(): void ])); } + #[Test] + public function shouldForkWithIntegerNamespace(): void + { + $expectedArray = [ + 'namespace' => 123, + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('projects/1/fork', $expectedArray) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->fork(1, [ + 'namespace' => 123, + ])); + } + + #[Test] + public function shouldForkWithNamespaceId(): void + { + $expectedArray = [ + 'namespace_id' => 7, + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('projects/1/fork', $expectedArray) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->fork(1, [ + 'namespace_id' => 7, + ])); + } + #[Test] public function shouldForkWithNamespaceAndPath(): void { @@ -1978,6 +2014,32 @@ public function shouldForkWithNamespaceAndPathAndName(): void ])); } + #[Test] + public function shouldForkWithNamespacePathAndAdditionalParameters(): void + { + $expectedArray = [ + 'namespace_path' => 'group/subgroup', + 'branches' => 'main', + 'description' => 'Fork description', + 'mr_default_target_self' => true, + 'visibility' => 'private', + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('projects/1/fork', $expectedArray) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->fork(1, [ + 'namespace_path' => 'group/subgroup', + 'branches' => 'main', + 'description' => 'Fork description', + 'mr_default_target_self' => true, + 'visibility' => 'private', + ])); + } + #[Test] public function shouldCreateForkRelation(): void {