From f97b9b6ddf54b8f09ba6a69910811f51fac07316 Mon Sep 17 00:00:00 2001 From: Stephan Vock Date: Thu, 16 Jul 2026 09:36:35 +0100 Subject: [PATCH 1/2] Projects: add hook events endpoint --- src/Api/Projects.php | 21 +++++++++++++++++++++ tests/Api/ProjectsTest.php | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/src/Api/Projects.php b/src/Api/Projects.php index 080d7278..0c0789e9 100644 --- a/src/Api/Projects.php +++ b/src/Api/Projects.php @@ -512,6 +512,27 @@ public function hook(int|string $project_id, int $hook_id): mixed return $this->get($this->getProjectPath($project_id, 'hooks/'.self::encodePath($hook_id))); } + /** + * List all events for a specified project webhook in the past 7 days from the start date. + * + * See https://docs.gitlab.com/api/project_webhooks/#list-project-webhook-events for more info. + * + * @param array $parameters { + * + * @var int|string $status Response status code, for example 200 or 500, or a category of status + * codes: successful, client_failure, or server_failure. + * } + */ + public function hookEvents(int|string $project_id, int $hook_id, array $parameters = []): mixed + { + $resolver = $this->createOptionsResolver(); + $resolver->setDefined('status') + ->setAllowedTypes('status', ['int', 'string']) + ; + + return $this->get($this->getProjectPath($project_id, 'hooks/'.self::encodePath($hook_id).'/events'), $resolver->resolve($parameters)); + } + /** * Get project users. * diff --git a/tests/Api/ProjectsTest.php b/tests/Api/ProjectsTest.php index 3f77081c..20049552 100644 --- a/tests/Api/ProjectsTest.php +++ b/tests/Api/ProjectsTest.php @@ -1325,6 +1325,39 @@ public function shouldGetHook(): void $this->assertEquals($expectedArray, $api->hook(1, 2)); } + #[Test] + public function shouldGetHookEvents(): void + { + $expectedArray = [ + ['id' => 1, 'url' => 'http://example.com', 'response_status' => 200], + ['id' => 2, 'url' => 'http://example.com', 'response_status' => 500], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/hooks/2/events') + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->hookEvents(1, 2)); + } + + #[Test] + public function shouldGetHookEventsWithStatusFilter(): void + { + $expectedArray = [ + ['id' => 2, 'url' => 'http://example.com', 'response_status' => 500], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/hooks/2/events', ['status' => 'server_failure']) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->hookEvents(1, 2, ['status' => 'server_failure'])); + } + #[Test] public function shouldAddHook(): void { From 1cbc6ba14d267ea23678ca97a4736c5b4bcc633d Mon Sep 17 00:00:00 2001 From: Stephan Vock Date: Thu, 16 Jul 2026 09:48:18 +0100 Subject: [PATCH 2/2] Projects: add support for testHook and resetHookEvent --- src/Api/Projects.php | 16 ++++++++++++++++ tests/Api/ProjectsTest.php | 28 ++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/Api/Projects.php b/src/Api/Projects.php index 0c0789e9..fb781466 100644 --- a/src/Api/Projects.php +++ b/src/Api/Projects.php @@ -533,6 +533,22 @@ public function hookEvents(int|string $project_id, int $hook_id, array $paramete return $this->get($this->getProjectPath($project_id, 'hooks/'.self::encodePath($hook_id).'/events'), $resolver->resolve($parameters)); } + /** + * See https://docs.gitlab.com/api/project_webhooks/#resend-a-project-webhook-event for more info. + */ + public function resendHookEvent(int|string $project_id, int $hook_id, int $hook_event_id): mixed + { + return $this->post($this->getProjectPath($project_id, 'hooks/'.self::encodePath($hook_id).'/events/'.self::encodePath($hook_event_id).'/resend')); + } + + /** + * See https://docs.gitlab.com/api/project_webhooks/#trigger-a-test-project-webhook for more info. + */ + public function testHook(int|string $project_id, int $hook_id, string $trigger): mixed + { + return $this->post($this->getProjectPath($project_id, 'hooks/'.self::encodePath($hook_id).'/test/'.self::encodePath($trigger))); + } + /** * Get project users. * diff --git a/tests/Api/ProjectsTest.php b/tests/Api/ProjectsTest.php index 20049552..b4f31ded 100644 --- a/tests/Api/ProjectsTest.php +++ b/tests/Api/ProjectsTest.php @@ -1358,6 +1358,34 @@ public function shouldGetHookEventsWithStatusFilter(): void $this->assertEquals($expectedArray, $api->hookEvents(1, 2, ['status' => 'server_failure'])); } + #[Test] + public function shouldResendHookEvent(): void + { + $expectedArray = ['message' => '201 Created']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('projects/1/hooks/2/events/3/resend') + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->resendHookEvent(1, 2, 3)); + } + + #[Test] + public function shouldTestHook(): void + { + $expectedArray = ['message' => '201 Created']; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('projects/1/hooks/2/test/push_events') + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->testHook(1, 2, 'push_events')); + } + #[Test] public function shouldAddHook(): void {