diff --git a/app/Http/Controllers/Webhook/Concerns/MatchesManualWebhookApplications.php b/app/Http/Controllers/Webhook/Concerns/MatchesManualWebhookApplications.php index f1fd0c40f..0463790eb 100644 --- a/app/Http/Controllers/Webhook/Concerns/MatchesManualWebhookApplications.php +++ b/app/Http/Controllers/Webhook/Concerns/MatchesManualWebhookApplications.php @@ -81,6 +81,10 @@ trait MatchesManualWebhookApplications $path = data_get($parts, 'path'); } elseif (Str::startsWith($gitRepository, 'git@') && str_contains($gitRepository, ':')) { $path = Str::after($gitRepository, ':'); + // scp-style SSH URLs embed a custom port as "git@host:2222/owner/repo". + // Strip the leading numeric port segment so the path matches the webhook + // payload's owner/repo, consistent with convertGitUrl() in shared.php. + $path = preg_replace('#^\d+/#', '', $path) ?? $path; } else { $path = $gitRepository; } diff --git a/tests/Feature/Webhook/WebhookHmacTest.php b/tests/Feature/Webhook/WebhookHmacTest.php index be2417462..3f49ff43d 100644 --- a/tests/Feature/Webhook/WebhookHmacTest.php +++ b/tests/Feature/Webhook/WebhookHmacTest.php @@ -509,6 +509,48 @@ describe('Manual Webhook Repository Matching', function () { expect($response->getContent())->not->toContain('No applications found'); }); + test('gitlab matches scp-style ssh repository URL with custom port', function () { + $app = createApplicationWithWebhook(overrides: [ + 'git_repository' => 'git@gitlab.example.com:2222/services/xyz.git', + 'git_branch' => 'master', + ]); + $secret = $app->manual_webhook_secret_gitlab; + + $response = $this->postJson('/webhooks/source/gitlab/events/manual', [ + 'object_kind' => 'push', + 'ref' => 'refs/heads/master', + 'project' => ['path_with_namespace' => 'services/xyz'], + 'after' => 'abc123', + 'commits' => [], + ], [ + 'X-Gitlab-Token' => $secret, + ]); + + $response->assertOk(); + expect($response->getContent())->not->toContain('No applications found'); + }); + + test('gitlab matches scp-style ssh repository URL without port', function () { + $app = createApplicationWithWebhook(overrides: [ + 'git_repository' => 'git@gitlab.example.com:services/xyz.git', + 'git_branch' => 'master', + ]); + $secret = $app->manual_webhook_secret_gitlab; + + $response = $this->postJson('/webhooks/source/gitlab/events/manual', [ + 'object_kind' => 'push', + 'ref' => 'refs/heads/master', + 'project' => ['path_with_namespace' => 'services/xyz'], + 'after' => 'abc123', + 'commits' => [], + ], [ + 'X-Gitlab-Token' => $secret, + ]); + + $response->assertOk(); + expect($response->getContent())->not->toContain('No applications found'); + }); + test('github matches repository case-insensitively', function () { $app = createApplicationWithWebhook(overrides: [ 'git_repository' => 'https://github.com/Test-Org/Test-Repo.git',