builds) === 0; } public function addBuild(Document $project, Document $resource, string $resourceType, string $buildStatus, string $deploymentId, array $action, string $previewUrl): void { // Unique index $id = $project->getId() . '_' . $resource->getId(); $this->builds[$id] = [ 'projectName' => $project->getAttribute('name'), 'projectId' => $project->getId(), 'region' => $project->getAttribute('region', 'default'), 'resourceName' => $resource->getAttribute('name'), 'resourceId' => $resource->getId(), 'resourceType' => $resourceType, 'buildStatus' => $buildStatus, 'deploymentId' => $deploymentId, 'action' => $action, 'previewUrl' => $previewUrl, ]; } public function generateComment(): string { $json = \json_encode($this->builds); $text = $this->statePrefix . \base64_encode($json) . "\n\n"; $projects = []; foreach ($this->builds as $id => $build) { if (!\array_key_exists($build['projectId'], $projects)) { $projects[$build['projectId']] = [ 'name' => $build['projectName'], 'function' => [], 'site' => [] ]; } if ($build['resourceType'] === 'site') { $projects[$build['projectId']]['site'][$build['resourceId']] = [ 'name' => $build['resourceName'], 'region' => $build['region'], 'status' => $build['buildStatus'], 'deploymentId' => $build['deploymentId'], 'action' => $build['action'], 'previewUrl' => $build['previewUrl'], ]; } elseif ($build['resourceType'] === 'function') { $projects[$build['projectId']]['function'][$build['resourceId']] = [ 'name' => $build['resourceName'], 'region' => $build['region'], 'status' => $build['buildStatus'], 'deploymentId' => $build['deploymentId'], 'action' => $build['action'], ]; } } $i = 0; foreach ($projects as $projectId => $project) { $protocol = System::getEnv('_APP_OPTIONS_FORCE_HTTPS') == 'disabled' ? 'http' : 'https'; $hostname = System::getEnv('_APP_DOMAIN'); $text .= "## {$project['name']}\n\n"; $text .= "Project ID: `{$projectId}`\n\n"; $isOpen = $i === 0; if (\count($project['site']) > 0) { $text .= "\n"; $text .= "Sites (" . \count($project['site']) . ")\n\n"; $text .= "
\n\n"; $text .= "| Site | Status | Logs | Preview | QR\n"; $text .= "| :- | :- | :- | :- | :- |\n"; foreach ($project['site'] as $siteId => $site) { $extension = $site['status'] === 'building' ? 'gif' : 'png'; $pathLight = '/images/vcs/status-' . $site['status'] . '-light.' . $extension; $pathDark = '/images/vcs/status-' . $site['status'] . '-dark.' . $extension; $status = match ($site['status']) { 'waiting' => $this->generatImage($pathLight, $pathDark, 'Queued', 85) . ' _Queued_', 'processing' => $this->generatImage($pathLight, $pathDark, 'Processing', 85) . ' _Processing_', 'building' => $this->generatImage($pathLight, $pathDark, 'Building', 85) . ' _Building_', 'ready' => $this->generatImage($pathLight, $pathDark, 'Ready', 85) . ' _Ready_', 'failed' => $this->generatImage($pathLight, $pathDark, 'Failed', 85) . ' _Failed_', }; if ($site['action']['type'] === 'logs') { $action = '[View Logs](' . $protocol . '://' . $hostname . '/console/project-' . $site['region'] . '-' . $projectId . '/sites/site-' . $siteId . '/deployments/deployment-' . $site['deploymentId'] . ')'; } else { $action = '[Authorize](' . $site['action']['url'] . ')'; } $qrImagePathLight = '/images/vcs/qr-light.svg'; $qrImagePathDark = '/images/vcs/qr-dark.svg'; $consoleUrl = $protocol . '://' . $hostname . '/v1/avatars/qr?text=' . \urlencode($site['previewUrl']); $qr = '[' . $this->generatImage($qrImagePathLight, $qrImagePathDark, 'QR Code', 28) . '](' . $consoleUrl . ')'; $preview = '[Preview URL](' . $site['previewUrl'] . ')'; $text .= "|  **{$site['name']}**
`$siteId`"; $text .= "| {$status}"; $text .= "| {$action}"; $text .= "| {$preview}"; $text .= "| {$qr}"; $text .= "|\n"; } $text .= "\n\n\n"; } if (\count($project['function']) > 0) { $text .= "\n"; $text .= "Functions (" . \count($project['function']) . ")\n\n"; $text .= "
\n\n"; $text .= "| Function | ID | Status | Logs |\n"; $text .= "| :- | :- | :- | :- |\n"; foreach ($project['function'] as $functionId => $function) { $extension = $function['status'] === 'building' ? 'gif' : 'png'; $pathLight = '/images/vcs/status-' . $function['status'] . '-light.' . $extension; $pathDark = '/images/vcs/status-' . $function['status'] . '-dark.' . $extension; $status = match ($function['status']) { 'waiting' => $this->generatImage($pathLight, $pathDark, 'Queued', 85) . ' _Queued_', 'processing' => $this->generatImage($pathLight, $pathDark, 'Processing', 85) . ' _Processing_', 'building' => $this->generatImage($pathLight, $pathDark, 'Building', 85) . ' _Building_', 'ready' => $this->generatImage($pathLight, $pathDark, 'Ready', 85) . ' _Ready_', 'failed' => $this->generatImage($pathLight, $pathDark, 'Failed', 85) . ' _Failed_', }; if ($function['action']['type'] === 'logs') { $action = '[View Logs](' . $protocol . '://' . $hostname . '/console/project-' . $function['region'] . '-' . $projectId . '/functions/function-' . $functionId . '/deployment-' . $function['deploymentId'] . ')'; } else { $action = '[Authorize](' . $function['action']['url'] . ')'; } $text .= "|  **{$function['name']}**
`$functionId`"; $text .= "| {$status}"; $text .= "| {$action}"; $text .= "|\n"; } $text .= "\n\n"; } $text .= "\n\n"; $isLast = $i === \count($projects) - 1; if (\count($projects) > 1 && $isLast) { $text .= "---\n\n"; } $i++; } $tip = $this->tips[array_rand($this->tips)]; $text .= "\n
\n\n> [!NOTE]\n> $tip\n\n"; return $text; } public function generatImage(string $pathLight, string $pathDark, string $alt, int $width): string { $protocol = System::getEnv('_APP_OPTIONS_FORCE_HTTPS') == 'disabled' ? 'http' : 'https'; $hostname = System::getEnv('_APP_DOMAIN'); $imageLight = $protocol . '://' . $hostname . $pathLight; $imageDark = $protocol . '://' . $hostname . $pathDark; $imageUrl = '' . $alt . ''; return $imageUrl; } public function parseComment(string $comment): self { $state = \explode("\n", $comment)[0] ?? ''; $state = substr($state, strlen($this->statePrefix)); $json = \base64_decode($state); $builds = \json_decode($json, true); $this->builds = $builds; return $this; } }