loadMissing(['application.organisation.registries', 'services.replicas']); $existingArtifact = $environment->buildArtifacts() ->where('commit_sha', $commitSha) ->whereIn('status', [BuildArtifactStatus::PENDING, BuildArtifactStatus::BUILDING, BuildArtifactStatus::AVAILABLE]) ->latest() ->first(); if ($existingArtifact) { return $existingArtifact; } $targetServerCount = $this->targetServerCount($environment); $registry = $this->registryResolver->buildRegistryFor($environment->application->organisation); $registryType = $this->registryType($registry); if ($targetServerCount > 1 && ! $registry) { $blocker = $this->registryResolver->managedRegistryBlockerFor($environment->application->organisation); throw new RuntimeException($blocker ?: 'A registry is required before building artifacts for multi-server deployments.'); } $builder = $environment->application->organisation->services() ->where('category', ServiceCategory::BUILDER) ->first(); $buildServerId = null; if ($registryType === RegistryType::MANAGED) { $buildServerId = (int) $registry->control_server_id; if ($buildServerId <= 0) { throw new RuntimeException('A control/build server is required for managed registry builds.'); } } $strategy = match (true) { $registryType === RegistryType::MANAGED => BuildStrategy::DEDICATED_BUILDER, $registry !== null => BuildStrategy::EXTERNAL_REGISTRY, $builder !== null => BuildStrategy::DEDICATED_BUILDER, default => BuildStrategy::TARGET_SERVER, }; $imageTag = $this->imageReference->tagFor($environment, $commitSha, $registry); return $environment->buildArtifacts()->create([ 'commit_sha' => $commitSha, 'image_tag' => $imageTag, 'registry_ref' => $registry ? $this->imageReference->registryReference($registry, $imageTag) : null, 'built_by_service_id' => $builder?->id, 'status' => BuildArtifactStatus::PENDING, 'metadata' => [ 'build_strategy' => $strategy->value, 'registry_type' => $registryType?->value, 'target_server_count' => $targetServerCount, 'build_server_id' => $buildServerId, ], ]); } private function targetServerCount(Environment $environment): int { $replicaServerCount = $environment->services ->flatMap(fn ($service) => $service->replicas->pluck('server_id')->filter()) ->unique() ->count(); if ($replicaServerCount > 0) { return $replicaServerCount; } return $environment->services->sum('desired_replicas') > 1 ? 2 : 1; } private function registryType(mixed $registry): ?RegistryType { if (! $registry) { return null; } if ($registry->type instanceof RegistryType) { return $registry->type; } return RegistryType::tryFrom((string) $registry->type); } }