enhancement: allow deploy from container image hash

This commit is contained in:
saurabhraghuvanshii committed 2025-08-28 02:10:14 +05:30
1 parent 886f910632
commit 3c126927d5
6 files changed
+145 -59

No files matched your search

+13 -2
View File
@@ -410,7 +410,12 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
} else {
$this->dockerImageTag = $this->application->docker_registry_image_tag;
}
$this->application_deployment_queue->addLogEntry("Starting deployment of {$this->dockerImage}:{$this->dockerImageTag} to {$this->server->name}.");
// Check if this is an image hash deployment
$isImageHash = str($this->dockerImageTag)->startsWith('sha256-');
$displayName = $isImageHash ? "{$this->dockerImage}@sha256:".str($this->dockerImageTag)->after('sha256-') : "{$this->dockerImage}:{$this->dockerImageTag}";
$this->application_deployment_queue->addLogEntry("Starting deployment of {$displayName} to {$this->server->name}.");
$this->generate_image_names();
$this->prepare_builder_image();
$this->generate_compose_file();
@@ -801,7 +806,13 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
$this->production_image_name = "{$this->application->uuid}:latest";
}
} elseif ($this->application->build_pack === 'dockerimage') {
$this->production_image_name = "{$this->dockerImage}:{$this->dockerImageTag}";
// Check if this is an image hash deployment
if (str($this->dockerImageTag)->startsWith('sha256-')) {
$hash = str($this->dockerImageTag)->after('sha256-');
$this->production_image_name = "{$this->dockerImage}@sha256:{$hash}";
} else {
$this->production_image_name = "{$this->dockerImage}:{$this->dockerImageTag}";
}
} elseif ($this->pull_request_id !== 0) {
if ($this->application->docker_registry_image_name) {
$this->build_image_name = "{$this->application->docker_registry_image_name}:pr-{$this->pull_request_id}-build";
+4
View File
@@ -45,6 +45,10 @@ class DockerImage extends Component
$project = Project::where('uuid', $this->parameters['project_uuid'])->first();
$environment = $project->load(['environments'])->environments->where('uuid', $this->parameters['environment_uuid'])->first();
// Determine the image tag based on whether it's a hash or regular tag
$imageTag = $parser->isImageHash() ? 'sha256-'.$parser->getTag() : $parser->getTag();
$application = Application::create([
'name' => 'docker-image-'.new Cuid2,
'repository_project_id' => 0,
+41
View File
@@ -10,6 +10,8 @@ class DockerImageParser
private string $tag = 'latest';
private bool $isImageHash = false;
public function parse(string $imageString): self
{
// First split by : to handle the tag, but be careful with registry ports
@@ -21,9 +23,13 @@ class DockerImageParser
if ($lastColon !== false && (! $hasSlash || $lastColon > strrpos($imageString, '/'))) {
$mainPart = substr($imageString, 0, $lastColon);
$this->tag = substr($imageString, $lastColon + 1);
// Check if the tag is a SHA256 hash
$this->isImageHash = $this->isSha256Hash($this->tag);
} else {
$mainPart = $imageString;
$this->tag = 'latest';
$this->isImageHash = false;
}
// Split the main part by / to handle registry and image name
@@ -41,6 +47,37 @@ class DockerImageParser
return $this;
}
/**
* Check if the given string is a SHA256 hash
*/
private function isSha256Hash(string $hash): bool
{
// SHA256 hashes are 64 characters long and contain only hexadecimal characters
return preg_match('/^[a-f0-9]{64}$/i', $hash) === 1;
}
/**
* Check if the current tag is an image hash
*/
public function isImageHash(): bool
{
return $this->isImageHash;
}
/**
* Get the full image name with hash if present
*/
public function getFullImageNameWithHash(): string
{
$imageName = $this->getFullImageNameWithoutTag();
if ($this->isImageHash) {
return $imageName.'@sha256:'.$this->tag;
}
return $imageName.':'.$this->tag;
}
public function getFullImageNameWithoutTag(): string
{
if ($this->registryUrl) {
@@ -73,6 +110,10 @@ class DockerImageParser
}
$parts[] = $this->imageName;
if ($this->isImageHash) {
return implode('/', $parts).'@sha256:'.$this->tag;
}
return implode('/', $parts).':'.$this->tag;
}
}