|null */ protected function webhookPushChangedFiles(mixed $payload): ?Collection { $commits = data_get($payload, 'commits'); if (! is_array($commits)) { return null; } return collect($commits) ->filter(fn (mixed $commit): bool => is_array($commit)) ->flatMap(fn (array $commit): array => collect(['added', 'removed', 'modified']) ->flatMap(fn (string $type): array => is_array($commit[$type] ?? null) ? $commit[$type] : []) ->all()) ->filter(fn (mixed $file): bool => is_string($file) && $file !== '') ->unique() ->values(); } /** * Commit messages of a push. Values that are not strings are ignored. * * @return array */ protected function webhookPushCommitMessages(mixed $payload, string $commitsPath = 'commits'): array { $commits = data_get($payload, $commitsPath); if (! is_array($commits)) { return []; } return collect($commits) ->map(fn (mixed $commit): mixed => is_array($commit) ? ($commit['message'] ?? null) : null) ->filter(fn (mixed $message): bool => is_string($message)) ->values() ->all(); } /** * True when the push deletes the branch. Such a push has no commit to deploy. */ protected function isWebhookBranchDeletionPush(mixed $payload): bool { if (data_get($payload, 'deleted') === true) { return true; } $after = data_get($payload, 'after'); return is_string($after) && preg_match('/\A0+\z/', $after) === 1; } /** * True when the push must deploy the application with respect to its watch * paths. Unknown changed files (no commit list) do not skip the deployment. * * @param Collection|null $changedFiles */ protected function webhookPushMatchesWatchPaths(Application $application, ?Collection $changedFiles): bool { if (blank($application->watch_paths) || $changedFiles === null) { return true; } return $application->isWatchPathsTriggered($changedFiles); } }