From 33a3c2ff45fe33b997d5b6df412b1af9602efcf0 Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Wed, 6 May 2026 12:18:51 +0100 Subject: [PATCH 1/2] Add permanent project removal and restore Co-authored-by: Philipp Kolmann <2240760+pkolmann@users.noreply.github.com> --- CHANGELOG.md | 1 + src/Api/Projects.php | 24 +++++++++++++++++-- tests/Api/ProjectsTest.php | 48 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d0a836e3..31fadf60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Add support for listing merge requests associated with a deployment * Add support for `with_custom_attributes` and `with_projects` in `Groups::show` * Add support for project remote mirror read endpoints +* Add support for permanent project removal and project restoration ## [12.0.0] - 2025-02-23 diff --git a/src/Api/Projects.php b/src/Api/Projects.php index 92f5ecfa..f0b77a56 100644 --- a/src/Api/Projects.php +++ b/src/Api/Projects.php @@ -194,9 +194,29 @@ public function update(int|string $project_id, array $parameters): mixed return $this->put('projects/'.self::encodePath($project_id), $parameters); } - public function remove(int|string $project_id): mixed + /** + * @param array $parameters { + * + * @var string $full_path Full path of project to use with permanently_remove. + * @var bool|string $permanently_remove Immediately delete a project that is already marked for deletion. + * } + */ + public function remove(int|string $project_id, array $parameters = []): mixed + { + $resolver = new OptionsResolver(); + $resolver->setDefined('full_path') + ->setAllowedTypes('full_path', 'string') + ; + $resolver->setDefined('permanently_remove') + ->setAllowedTypes('permanently_remove', ['bool', 'string']) + ; + + return $this->delete('projects/'.self::encodePath($project_id), $resolver->resolve($parameters)); + } + + public function restore(int|string $project_id): mixed { - return $this->delete('projects/'.self::encodePath($project_id)); + return $this->post('projects/'.self::encodePath($project_id).'/restore'); } public function archive(int|string $project_id): mixed diff --git a/tests/Api/ProjectsTest.php b/tests/Api/ProjectsTest.php index a2ba2602..fc314eaa 100644 --- a/tests/Api/ProjectsTest.php +++ b/tests/Api/ProjectsTest.php @@ -345,6 +345,54 @@ public function shouldRemoveProject(): void $this->assertEquals($expectedBool, $api->remove(1)); } + #[Test] + public function shouldRemoveProjectPermanently(): void + { + $expectedBool = true; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('projects/1', ['full_path' => 'group/project', 'permanently_remove' => true]) + ->willReturn($expectedBool); + + $this->assertEquals($expectedBool, $api->remove(1, [ + 'full_path' => 'group/project', + 'permanently_remove' => true, + ])); + } + + #[Test] + public function shouldRemoveProjectPermanentlyWithStringParameter(): void + { + $expectedBool = true; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('projects/1', ['full_path' => 'group/project', 'permanently_remove' => 'true']) + ->willReturn($expectedBool); + + $this->assertEquals($expectedBool, $api->remove(1, [ + 'full_path' => 'group/project', + 'permanently_remove' => 'true', + ])); + } + + #[Test] + public function shouldRestoreProject(): void + { + $expectedArray = ['id' => 1, 'name' => 'Project Name']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('projects/1/restore') + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->restore(1)); + } + #[Test] public function shouldGetPipelines(): void { From 4229b86db7575405d4b9317f62e9b1a23e46caf8 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Wed, 6 May 2026 11:19:39 +0000 Subject: [PATCH 2/2] Apply fixes from StyleCI --- src/Api/Projects.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Api/Projects.php b/src/Api/Projects.php index f0b77a56..e0aa69fb 100644 --- a/src/Api/Projects.php +++ b/src/Api/Projects.php @@ -197,7 +197,7 @@ public function update(int|string $project_id, array $parameters): mixed /** * @param array $parameters { * - * @var string $full_path Full path of project to use with permanently_remove. + * @var string $full_path full path of project to use with permanently_remove * @var bool|string $permanently_remove Immediately delete a project that is already marked for deletion. * } */