Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
47 changes: 40 additions & 7 deletions src/Api/Projects.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
62 changes: 62 additions & 0 deletions tests/Api/ProjectsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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
{
Expand Down