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 = $environment->application->organisation->registries()->first(); if ($targetServerCount > 1 && ! $registry) { throw new RuntimeException('A registry is required before building artifacts for multi-server deployments.'); } $builder = $environment->application->organisation->services() ->where('category', ServiceCategory::BUILDER) ->first(); $strategy = match (true) { $registry !== null => BuildStrategy::EXTERNAL_REGISTRY, $builder !== null => BuildStrategy::DEDICATED_BUILDER, default => BuildStrategy::TARGET_SERVER, }; $imageTag = str($environment->application->name) ->slug() ->append(':'.substr($commitSha, 0, 12)) ->value(); return $environment->buildArtifacts()->create([ 'commit_sha' => $commitSha, 'image_tag' => $imageTag, 'registry_ref' => $registry ? rtrim((string) $registry->url, '/').'/'.$imageTag : null, 'built_by_service_id' => $builder?->id, 'status' => BuildArtifactStatus::PENDING, 'metadata' => [ 'build_strategy' => $strategy->value, 'target_server_count' => $targetServerCount, ], ]); } 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; } }