fix(deployment): avoid shared preview tags for HEAD commits

Use the deployment UUID when preview deployments are built from HEAD so each deployment gets distinct production and build image tags.
This commit is contained in:
Andras Bacsai
2026-05-11 22:11:08 +02:00
parent 2253c40e01
commit 9bb40f3ccb
4 changed files with 53 additions and 34 deletions
+5 -1
View File
@@ -1184,7 +1184,11 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
$prefix = "pr-{$this->pull_request_id}-";
$suffix = $build ? '-build' : '';
$maxCommitLength = max(1, 128 - strlen($prefix) - strlen($suffix));
$commit = Str::of($this->commit ?: 'HEAD')
$commitSource = ($this->commit === 'HEAD' || blank($this->commit))
? $this->deployment_uuid
: $this->commit;
$commit = Str::of($commitSource)
->replaceMatches('/[^A-Za-z0-9_.-]/', '-')
->substr(0, $maxCommitLength)
->toString();
+14 -16
View File
@@ -1634,6 +1634,20 @@
"minversion": "0.0.0",
"port": "2368"
},
"gitea-runner": {
"documentation": "https://github.com/go-gitea/gitea?utm_source=coolify.io",
"slogan": "Gitea Actions runner for docker",
"compose": "c2VydmljZXM6CiAgcnVubmVyOgogICAgaW1hZ2U6ICdkb2NrZXIuaW8vZ2l0ZWEvcnVubmVyOjEuMC4wJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0dJVEVBX0lOU1RBTkNFX1VSTD0ke0dJVEVBX0lOU1RBTkNFX1VSTH0nCiAgICAgIC0gJ0dJVEVBX1JVTk5FUl9SRUdJU1RSQVRJT05fVE9LRU49JHtHSVRFQV9SVU5ORVJfUkVHSVNUUkFUSU9OX1RPS0VOfScKICAgICAgLSAnR0lURUFfUlVOTkVSX05BTUU9JHtHSVRFQV9SVU5ORVJfTkFNRTotZ2l0ZWEtcnVubmVyfScKICAgICAgLSAnR0lURUFfUlVOTkVSX0xBQkVMUz0ke0dJVEVBX1JVTk5FUl9MQUJFTFM6LXVidW50dS1sYXRlc3Q6ZG9ja2VyOi8vbm9kZToyMn0nCiAgICAgIC0gJ0dJVEVBX1RPS0VOPSR7R0lURUFfVE9LRU59JwogICAgd29ya2luZ19kaXI6IC9kYXRhCiAgICB2b2x1bWVzOgogICAgICAtICdydW5uZXItZGF0YTovZGF0YScKICAgICAgLSAnL3Zhci9ydW4vZG9ja2VyLnNvY2s6L3Zhci9ydW4vZG9ja2VyLnNvY2snCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gInBzIGF1eCB8IGdyZXAgJ1tSXXVubmVyJyA+IC9kZXYvbnVsbCB8fCBleGl0IDEiCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMTUK",
"tags": [
"gitea",
"actions",
"runner",
"docker"
],
"category": "devtools",
"logo": "svgs/gitea.svg",
"minversion": "0.0.0"
},
"gitea-with-mariadb": {
"documentation": "https://docs.gitea.com?utm_source=coolify.io",
"slogan": "Gitea is a self-hosted, lightweight Git service, offering version control, collaboration, and code hosting.",
@@ -2587,22 +2601,6 @@
"minversion": "0.0.0",
"port": "4000"
},
"litequeen": {
"documentation": "https://litequeen.com/?utm_source=coolify.io",
"slogan": "Lite Queen is an open-source SQLite database management software that runs on your server.",
"compose": "c2VydmljZXM6CiAgbGl0ZXF1ZWVuOgogICAgaW1hZ2U6ICdraXZzZWdyb2IvbGl0ZS1xdWVlbjpsYXRlc3QnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX1VSTF9MSVRFUVVFRU5fODAwMAogICAgdm9sdW1lczoKICAgICAgLSAnbGl0ZXF1ZWVuLWRhdGE6L2hvbWUvbGl0ZXF1ZWVuL2RhdGEnCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL2RhdGFiYXNlcwogICAgICAgIHRhcmdldDogL3NydgogICAgICAgIGlzX2RpcmVjdG9yeTogdHJ1ZQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICJiYXNoIC1jICc6PiAvZGV2L3RjcC8xMjcuMC4wLjEvODAwMCcgfHwgZXhpdCAxIgogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMwo=",
"tags": [
"sqlite",
"sqlite-database-management",
"self-hosted",
"vps",
"database"
],
"category": "database",
"logo": "svgs/litequeen.svg",
"minversion": "0.0.0",
"port": "8000"
},
"lobe-chat": {
"documentation": "https://github.com/lobehub/lobe-chat?tab=readme-ov-file#b-deploying-with-docker?utm_source=coolify.io",
"slogan": "An open-source, modern-design AI chat framework.",
+14 -16
View File
@@ -1634,6 +1634,20 @@
"minversion": "0.0.0",
"port": "2368"
},
"gitea-runner": {
"documentation": "https://github.com/go-gitea/gitea?utm_source=coolify.io",
"slogan": "Gitea Actions runner for docker",
"compose": "c2VydmljZXM6CiAgcnVubmVyOgogICAgaW1hZ2U6ICdkb2NrZXIuaW8vZ2l0ZWEvcnVubmVyOjEuMC4wJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0dJVEVBX0lOU1RBTkNFX1VSTD0ke0dJVEVBX0lOU1RBTkNFX1VSTH0nCiAgICAgIC0gJ0dJVEVBX1JVTk5FUl9SRUdJU1RSQVRJT05fVE9LRU49JHtHSVRFQV9SVU5ORVJfUkVHSVNUUkFUSU9OX1RPS0VOfScKICAgICAgLSAnR0lURUFfUlVOTkVSX05BTUU9JHtHSVRFQV9SVU5ORVJfTkFNRTotZ2l0ZWEtcnVubmVyfScKICAgICAgLSAnR0lURUFfUlVOTkVSX0xBQkVMUz0ke0dJVEVBX1JVTk5FUl9MQUJFTFM6LXVidW50dS1sYXRlc3Q6ZG9ja2VyOi8vbm9kZToyMn0nCiAgICAgIC0gJ0dJVEVBX1RPS0VOPSR7R0lURUFfVE9LRU59JwogICAgd29ya2luZ19kaXI6IC9kYXRhCiAgICB2b2x1bWVzOgogICAgICAtICdydW5uZXItZGF0YTovZGF0YScKICAgICAgLSAnL3Zhci9ydW4vZG9ja2VyLnNvY2s6L3Zhci9ydW4vZG9ja2VyLnNvY2snCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gInBzIGF1eCB8IGdyZXAgJ1tSXXVubmVyJyA+IC9kZXYvbnVsbCB8fCBleGl0IDEiCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMTUK",
"tags": [
"gitea",
"actions",
"runner",
"docker"
],
"category": "devtools",
"logo": "svgs/gitea.svg",
"minversion": "0.0.0"
},
"gitea-with-mariadb": {
"documentation": "https://docs.gitea.com?utm_source=coolify.io",
"slogan": "Gitea is a self-hosted, lightweight Git service, offering version control, collaboration, and code hosting.",
@@ -2587,22 +2601,6 @@
"minversion": "0.0.0",
"port": "4000"
},
"litequeen": {
"documentation": "https://litequeen.com/?utm_source=coolify.io",
"slogan": "Lite Queen is an open-source SQLite database management software that runs on your server.",
"compose": "c2VydmljZXM6CiAgbGl0ZXF1ZWVuOgogICAgaW1hZ2U6ICdraXZzZWdyb2IvbGl0ZS1xdWVlbjpsYXRlc3QnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fTElURVFVRUVOXzgwMDAKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2xpdGVxdWVlbi1kYXRhOi9ob21lL2xpdGVxdWVlbi9kYXRhJwogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi9kYXRhYmFzZXMKICAgICAgICB0YXJnZXQ6IC9zcnYKICAgICAgICBpc19kaXJlY3Rvcnk6IHRydWUKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAiYmFzaCAtYyAnOj4gL2Rldi90Y3AvMTI3LjAuMC4xLzgwMDAnIHx8IGV4aXQgMSIKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDMK",
"tags": [
"sqlite",
"sqlite-database-management",
"self-hosted",
"vps",
"database"
],
"category": "database",
"logo": "svgs/litequeen.svg",
"minversion": "0.0.0",
"port": "8000"
},
"lobe-chat": {
"documentation": "https://github.com/lobehub/lobe-chat?tab=readme-ov-file#b-deploying-with-docker?utm_source=coolify.io",
"slogan": "An open-source, modern-design AI chat framework.",
@@ -3,7 +3,7 @@
use App\Jobs\ApplicationDeploymentJob;
use App\Models\Application;
function makePreviewImageNameJob(string $commit, int $pullRequestId = 42, ?string $registryImageName = null): object
function makePreviewImageNameJob(string $commit, int $pullRequestId = 42, ?string $registryImageName = null, string $deploymentUuid = 'deployment-uuid'): object
{
$reflection = new ReflectionClass(ApplicationDeploymentJob::class);
$job = $reflection->newInstanceWithoutConstructor();
@@ -18,6 +18,7 @@ function makePreviewImageNameJob(string $commit, int $pullRequestId = 42, ?strin
'application' => $application,
'pull_request_id' => $pullRequestId,
'commit' => $commit,
'deployment_uuid' => $deploymentUuid,
] as $property => $value) {
$reflectionProperty = $reflection->getProperty($property);
$reflectionProperty->setAccessible(true);
@@ -70,6 +71,24 @@ it('generates different preview image names for different commits on the same pu
->and($firstCommitNames['build'])->not->toBe($secondCommitNames['build']);
});
it('uses the deployment uuid for preview image names when commit is HEAD', function () {
$firstDeploymentNames = generatePreviewImageNames(makePreviewImageNameJob(
commit: 'HEAD',
pullRequestId: 123,
deploymentUuid: 'deployment-one',
));
$secondDeploymentNames = generatePreviewImageNames(makePreviewImageNameJob(
commit: 'HEAD',
pullRequestId: 123,
deploymentUuid: 'deployment-two',
));
expect($firstDeploymentNames['production'])->toBe('preview-app:pr-123-deployment-one')
->and($firstDeploymentNames['build'])->toBe('preview-app:pr-123-deployment-one-build')
->and($secondDeploymentNames['production'])->toBe('preview-app:pr-123-deployment-two')
->and($secondDeploymentNames['build'])->toBe('preview-app:pr-123-deployment-two-build');
});
it('uses the configured registry image name for commit-specific preview tags', function () {
$names = generatePreviewImageNames(makePreviewImageNameJob(
commit: '111222333444555666777888999000aaabbbccc1',