new deployer command
This commit is contained in:
@@ -22,6 +22,12 @@ final class GitWebhookController
|
||||
private const SHA256_PREFIX = 'sha256=';
|
||||
|
||||
private const SHA1_PREFIX = 'sha1=';
|
||||
|
||||
private const REQUEST_ID_HEADER = 'X-Request-Id';
|
||||
|
||||
private const GITHUB_DELIVERY_HEADER = 'X-GitHub-Delivery';
|
||||
|
||||
private const GITHUB_EVENT_HEADER = 'X-GitHub-Event';
|
||||
/**
|
||||
* Ingest a signed Git provider webhook for a registered Helpdesk repository.
|
||||
*/
|
||||
@@ -235,43 +241,11 @@ final class GitWebhookController
|
||||
return null;
|
||||
}
|
||||
|
||||
$payloadValues = array_values(array_filter([
|
||||
Arr::get($payload, 'repository.full_name'),
|
||||
Arr::get($payload, 'repository.name'),
|
||||
Arr::get($payload, 'repository.html_url'),
|
||||
Arr::get($payload, 'repository.clone_url'),
|
||||
Arr::get($payload, 'repository.ssh_url'),
|
||||
Arr::get($payload, 'repository.url'),
|
||||
Arr::get($payload, 'repository.owner.username') && Arr::get($payload, 'repository.name')
|
||||
? Arr::get($payload, 'repository.owner.username') . '/' . Arr::get($payload, 'repository.name')
|
||||
: null,
|
||||
], static fn (mixed $value): bool => is_scalar($value) && trim((string) $value) !== ''));
|
||||
|
||||
$normalisedPayloadValues = array_values(array_filter(array_map(
|
||||
fn (mixed $value): ?string => $this->normaliseRepositoryIdentity((string) $value),
|
||||
$payloadValues,
|
||||
)));
|
||||
$normalisedPayloadValues = $this->normalisedPayloadRepositoryValues($payload);
|
||||
|
||||
foreach ($repositories as $repository) {
|
||||
$repositoryValues = array_filter([
|
||||
$repository->remote_url,
|
||||
$repository->name,
|
||||
Str::of((string) $repository->remote_url)->afterLast(':')->beforeLast('.git')->value(),
|
||||
], static fn (mixed $value): bool => is_scalar($value) && trim((string) $value) !== '');
|
||||
|
||||
$normalisedRepositoryValues = array_values(array_filter(array_map(
|
||||
fn (mixed $value): ?string => $this->normaliseRepositoryIdentity((string) $value),
|
||||
$repositoryValues,
|
||||
)));
|
||||
|
||||
foreach ($normalisedPayloadValues as $payloadValue) {
|
||||
foreach ($normalisedRepositoryValues as $repositoryValue) {
|
||||
if ($payloadValue === $repositoryValue
|
||||
|| str_ends_with($repositoryValue, '/' . $payloadValue)
|
||||
|| str_ends_with($payloadValue, '/' . $repositoryValue)) {
|
||||
return $repository;
|
||||
}
|
||||
}
|
||||
if ($this->repositoryMatchesPayload($repository, $normalisedPayloadValues)) {
|
||||
return $repository;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,6 +261,74 @@ final class GitWebhookController
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/** @param array<string, mixed> $payload
|
||||
* @return list<string>
|
||||
*/
|
||||
private function normalisedPayloadRepositoryValues(array $payload): array
|
||||
{
|
||||
$name = Arr::get($payload, 'repository.name');
|
||||
$owner = Arr::get($payload, 'repository.owner.username');
|
||||
|
||||
return $this->normaliseRepositoryValues([
|
||||
Arr::get($payload, 'repository.full_name'),
|
||||
$name,
|
||||
Arr::get($payload, 'repository.html_url'),
|
||||
Arr::get($payload, 'repository.clone_url'),
|
||||
Arr::get($payload, 'repository.ssh_url'),
|
||||
Arr::get($payload, 'repository.url'),
|
||||
$owner && $name ? $owner . '/' . $name : null,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @param list<string> $payloadValues */
|
||||
private function repositoryMatchesPayload(GitRepository $repository, array $payloadValues): bool
|
||||
{
|
||||
$repositoryValues = $this->normaliseRepositoryValues([
|
||||
$repository->remote_url,
|
||||
$repository->name,
|
||||
Str::of((string) $repository->remote_url)->afterLast(':')->beforeLast('.git')->value(),
|
||||
]);
|
||||
|
||||
foreach ($payloadValues as $payloadValue) {
|
||||
foreach ($repositoryValues as $repositoryValue) {
|
||||
if ($this->repositoryIdentitiesMatch($payloadValue, $repositoryValue)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @param array<int, mixed> $values
|
||||
* @return list<string>
|
||||
*/
|
||||
private function normaliseRepositoryValues(array $values): array
|
||||
{
|
||||
$normalised = [];
|
||||
|
||||
foreach ($values as $value) {
|
||||
if (! is_scalar($value) || trim((string) $value) === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$identity = $this->normaliseRepositoryIdentity((string) $value);
|
||||
if ($identity !== null) {
|
||||
$normalised[] = $identity;
|
||||
}
|
||||
}
|
||||
|
||||
return $normalised;
|
||||
}
|
||||
|
||||
private function repositoryIdentitiesMatch(string $payloadValue, string $repositoryValue): bool
|
||||
{
|
||||
return $payloadValue === $repositoryValue
|
||||
|| str_ends_with($repositoryValue, '/' . $payloadValue)
|
||||
|| str_ends_with($payloadValue, '/' . $repositoryValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalise a repository name or URL so Gitea payloads match local settings reliably.
|
||||
*/
|
||||
@@ -341,11 +383,11 @@ final class GitWebhookController
|
||||
private function eventName(Request $request, string $provider): ?string
|
||||
{
|
||||
return match ($provider) {
|
||||
'github' => $request->header('X-GitHub-Event'),
|
||||
'github' => $request->header(self::GITHUB_EVENT_HEADER),
|
||||
'gitlab' => $request->header('X-Gitlab-Event'),
|
||||
'gitea' => $request->header('X-Gitea-Event') ?: $request->header('X-Gitea-Event-Type') ?: $request->header('X-GitHub-Event'),
|
||||
'gitea' => $request->header('X-Gitea-Event') ?: $request->header('X-Gitea-Event-Type') ?: $request->header(self::GITHUB_EVENT_HEADER),
|
||||
'bitbucket' => $request->header('X-Event-Key'),
|
||||
default => $request->header('X-Helpdesk-Event') ?: $request->header('X-GitHub-Event') ?: $request->header('X-Gitlab-Event') ?: 'push',
|
||||
default => $request->header('X-Helpdesk-Event') ?: $request->header(self::GITHUB_EVENT_HEADER) ?: $request->header('X-Gitlab-Event') ?: 'push',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -355,11 +397,11 @@ final class GitWebhookController
|
||||
private function deliveryId(Request $request, string $provider): ?string
|
||||
{
|
||||
return match ($provider) {
|
||||
'github' => $request->header('X-GitHub-Delivery'),
|
||||
'gitlab' => $request->header('X-Gitlab-Event-UUID') ?: $request->header('X-Request-Id'),
|
||||
'gitea' => $request->header('X-Gitea-Delivery') ?: $request->header('X-GitHub-Delivery') ?: $request->header('X-Request-Id'),
|
||||
'bitbucket' => $request->header('X-Request-UUID') ?: $request->header('X-Request-Id'),
|
||||
default => $request->header('X-Helpdesk-Delivery') ?: $request->header('X-GitHub-Delivery') ?: $request->header('X-Request-Id'),
|
||||
'github' => $request->header(self::GITHUB_DELIVERY_HEADER),
|
||||
'gitlab' => $request->header('X-Gitlab-Event-UUID') ?: $request->header(self::REQUEST_ID_HEADER),
|
||||
'gitea' => $request->header('X-Gitea-Delivery') ?: $request->header(self::GITHUB_DELIVERY_HEADER) ?: $request->header(self::REQUEST_ID_HEADER),
|
||||
'bitbucket' => $request->header('X-Request-UUID') ?: $request->header(self::REQUEST_ID_HEADER),
|
||||
default => $request->header('X-Helpdesk-Delivery') ?: $request->header(self::GITHUB_DELIVERY_HEADER) ?: $request->header(self::REQUEST_ID_HEADER),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user