From 07cd389eb9bbef8d5f8cad3afe231fde75796ef7 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Mon, 15 Dec 2025 11:23:04 +0100 Subject: [PATCH] fix: add idempotency guards to 18 migrations to prevent upgrade failures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When any migration fails due to table/column already existing, PostgreSQL rolls back the entire batch and blocks all subsequent migrations. Add Schema::hasTable() and Schema::hasColumn() guards to all problem migrations for safe re-execution. Fixes #7606 #7625 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 --- ...125_create_cloud_provider_tokens_table.php | 20 +++++---- ...add_hetzner_server_id_to_servers_table.php | 16 ++++--- ...oud_provider_token_id_to_servers_table.php | 18 +++++--- ...hetzner_server_status_to_servers_table.php | 16 ++++--- ...036_add_is_validating_to_servers_table.php | 16 ++++--- ...ev_helper_version_to_instance_settings.php | 16 ++++--- ...1_add_timeout_to_scheduled_tasks_table.php | 16 ++++--- ...ove_scheduled_task_executions_tracking.php | 40 +++++++++++++---- ...restart_tracking_to_applications_table.php | 33 ++++++++++---- ...efik_version_tracking_to_servers_table.php | 16 ++++--- ...utdated_to_email_notification_settings.php | 16 ++++--- ...d_id_to_telegram_notification_settings.php | 16 ++++--- ...traefik_outdated_info_to_servers_table.php | 16 ++++--- ...cache_settings_to_application_settings.php | 30 +++++++++---- ...loyment_queue_limit_to_server_settings.php | 16 ++++--- ...images_to_keep_to_application_settings.php | 16 ++++--- ...ion_image_retention_to_server_settings.php | 16 ++++--- ...5600_add_uuid_to_cloud_provider_tokens.php | 44 ++++++++++--------- 18 files changed, 244 insertions(+), 133 deletions(-) diff --git a/database/migrations/2025_10_08_181125_create_cloud_provider_tokens_table.php b/database/migrations/2025_10_08_181125_create_cloud_provider_tokens_table.php index 2c92b0e19..a9c59cbc3 100644 --- a/database/migrations/2025_10_08_181125_create_cloud_provider_tokens_table.php +++ b/database/migrations/2025_10_08_181125_create_cloud_provider_tokens_table.php @@ -11,16 +11,18 @@ */ public function up(): void { - Schema::create('cloud_provider_tokens', function (Blueprint $table) { - $table->id(); - $table->foreignId('team_id')->constrained()->onDelete('cascade'); - $table->string('provider'); - $table->text('token'); - $table->string('name')->nullable(); - $table->timestamps(); + if (! Schema::hasTable('cloud_provider_tokens')) { + Schema::create('cloud_provider_tokens', function (Blueprint $table) { + $table->id(); + $table->foreignId('team_id')->constrained()->onDelete('cascade'); + $table->string('provider'); + $table->text('token'); + $table->string('name')->nullable(); + $table->timestamps(); - $table->index(['team_id', 'provider']); - }); + $table->index(['team_id', 'provider']); + }); + } } /** diff --git a/database/migrations/2025_10_08_185203_add_hetzner_server_id_to_servers_table.php b/database/migrations/2025_10_08_185203_add_hetzner_server_id_to_servers_table.php index b1c9ec48b..b5cae7d32 100644 --- a/database/migrations/2025_10_08_185203_add_hetzner_server_id_to_servers_table.php +++ b/database/migrations/2025_10_08_185203_add_hetzner_server_id_to_servers_table.php @@ -11,9 +11,11 @@ */ public function up(): void { - Schema::table('servers', function (Blueprint $table) { - $table->bigInteger('hetzner_server_id')->nullable()->after('id'); - }); + if (! Schema::hasColumn('servers', 'hetzner_server_id')) { + Schema::table('servers', function (Blueprint $table) { + $table->bigInteger('hetzner_server_id')->nullable()->after('id'); + }); + } } /** @@ -21,8 +23,10 @@ public function up(): void */ public function down(): void { - Schema::table('servers', function (Blueprint $table) { - $table->dropColumn('hetzner_server_id'); - }); + if (Schema::hasColumn('servers', 'hetzner_server_id')) { + Schema::table('servers', function (Blueprint $table) { + $table->dropColumn('hetzner_server_id'); + }); + } } }; diff --git a/database/migrations/2025_10_09_095905_add_cloud_provider_token_id_to_servers_table.php b/database/migrations/2025_10_09_095905_add_cloud_provider_token_id_to_servers_table.php index a25a4ce83..9f23a7ee9 100644 --- a/database/migrations/2025_10_09_095905_add_cloud_provider_token_id_to_servers_table.php +++ b/database/migrations/2025_10_09_095905_add_cloud_provider_token_id_to_servers_table.php @@ -11,9 +11,11 @@ */ public function up(): void { - Schema::table('servers', function (Blueprint $table) { - $table->foreignId('cloud_provider_token_id')->nullable()->after('private_key_id')->constrained()->onDelete('set null'); - }); + if (! Schema::hasColumn('servers', 'cloud_provider_token_id')) { + Schema::table('servers', function (Blueprint $table) { + $table->foreignId('cloud_provider_token_id')->nullable()->after('private_key_id')->constrained()->onDelete('set null'); + }); + } } /** @@ -21,9 +23,11 @@ public function up(): void */ public function down(): void { - Schema::table('servers', function (Blueprint $table) { - $table->dropForeign(['cloud_provider_token_id']); - $table->dropColumn('cloud_provider_token_id'); - }); + if (Schema::hasColumn('servers', 'cloud_provider_token_id')) { + Schema::table('servers', function (Blueprint $table) { + $table->dropForeign(['cloud_provider_token_id']); + $table->dropColumn('cloud_provider_token_id'); + }); + } } }; diff --git a/database/migrations/2025_10_09_113602_add_hetzner_server_status_to_servers_table.php b/database/migrations/2025_10_09_113602_add_hetzner_server_status_to_servers_table.php index d94c9c76f..54a0a37ba 100644 --- a/database/migrations/2025_10_09_113602_add_hetzner_server_status_to_servers_table.php +++ b/database/migrations/2025_10_09_113602_add_hetzner_server_status_to_servers_table.php @@ -11,9 +11,11 @@ */ public function up(): void { - Schema::table('servers', function (Blueprint $table) { - $table->string('hetzner_server_status')->nullable()->after('hetzner_server_id'); - }); + if (! Schema::hasColumn('servers', 'hetzner_server_status')) { + Schema::table('servers', function (Blueprint $table) { + $table->string('hetzner_server_status')->nullable()->after('hetzner_server_id'); + }); + } } /** @@ -21,8 +23,10 @@ public function up(): void */ public function down(): void { - Schema::table('servers', function (Blueprint $table) { - $table->dropColumn('hetzner_server_status'); - }); + if (Schema::hasColumn('servers', 'hetzner_server_status')) { + Schema::table('servers', function (Blueprint $table) { + $table->dropColumn('hetzner_server_status'); + }); + } } }; diff --git a/database/migrations/2025_10_09_125036_add_is_validating_to_servers_table.php b/database/migrations/2025_10_09_125036_add_is_validating_to_servers_table.php index ddb655d2c..b1309713d 100644 --- a/database/migrations/2025_10_09_125036_add_is_validating_to_servers_table.php +++ b/database/migrations/2025_10_09_125036_add_is_validating_to_servers_table.php @@ -11,9 +11,11 @@ */ public function up(): void { - Schema::table('servers', function (Blueprint $table) { - $table->boolean('is_validating')->default(false)->after('hetzner_server_status'); - }); + if (! Schema::hasColumn('servers', 'is_validating')) { + Schema::table('servers', function (Blueprint $table) { + $table->boolean('is_validating')->default(false)->after('hetzner_server_status'); + }); + } } /** @@ -21,8 +23,10 @@ public function up(): void */ public function down(): void { - Schema::table('servers', function (Blueprint $table) { - $table->dropColumn('is_validating'); - }); + if (Schema::hasColumn('servers', 'is_validating')) { + Schema::table('servers', function (Blueprint $table) { + $table->dropColumn('is_validating'); + }); + } } }; diff --git a/database/migrations/2025_11_02_161923_add_dev_helper_version_to_instance_settings.php b/database/migrations/2025_11_02_161923_add_dev_helper_version_to_instance_settings.php index 56ed2239a..f968d2926 100644 --- a/database/migrations/2025_11_02_161923_add_dev_helper_version_to_instance_settings.php +++ b/database/migrations/2025_11_02_161923_add_dev_helper_version_to_instance_settings.php @@ -11,9 +11,11 @@ */ public function up(): void { - Schema::table('instance_settings', function (Blueprint $table) { - $table->string('dev_helper_version')->nullable(); - }); + if (! Schema::hasColumn('instance_settings', 'dev_helper_version')) { + Schema::table('instance_settings', function (Blueprint $table) { + $table->string('dev_helper_version')->nullable(); + }); + } } /** @@ -21,8 +23,10 @@ public function up(): void */ public function down(): void { - Schema::table('instance_settings', function (Blueprint $table) { - $table->dropColumn('dev_helper_version'); - }); + if (Schema::hasColumn('instance_settings', 'dev_helper_version')) { + Schema::table('instance_settings', function (Blueprint $table) { + $table->dropColumn('dev_helper_version'); + }); + } } }; diff --git a/database/migrations/2025_11_09_000001_add_timeout_to_scheduled_tasks_table.php b/database/migrations/2025_11_09_000001_add_timeout_to_scheduled_tasks_table.php index 067861e16..59223a506 100644 --- a/database/migrations/2025_11_09_000001_add_timeout_to_scheduled_tasks_table.php +++ b/database/migrations/2025_11_09_000001_add_timeout_to_scheduled_tasks_table.php @@ -11,9 +11,11 @@ */ public function up(): void { - Schema::table('scheduled_tasks', function (Blueprint $table) { - $table->integer('timeout')->default(300)->after('frequency'); - }); + if (! Schema::hasColumn('scheduled_tasks', 'timeout')) { + Schema::table('scheduled_tasks', function (Blueprint $table) { + $table->integer('timeout')->default(300)->after('frequency'); + }); + } } /** @@ -21,8 +23,10 @@ public function up(): void */ public function down(): void { - Schema::table('scheduled_tasks', function (Blueprint $table) { - $table->dropColumn('timeout'); - }); + if (Schema::hasColumn('scheduled_tasks', 'timeout')) { + Schema::table('scheduled_tasks', function (Blueprint $table) { + $table->dropColumn('timeout'); + }); + } } }; diff --git a/database/migrations/2025_11_09_000002_improve_scheduled_task_executions_tracking.php b/database/migrations/2025_11_09_000002_improve_scheduled_task_executions_tracking.php index 14fdd5998..ff45b1fcf 100644 --- a/database/migrations/2025_11_09_000002_improve_scheduled_task_executions_tracking.php +++ b/database/migrations/2025_11_09_000002_improve_scheduled_task_executions_tracking.php @@ -11,12 +11,29 @@ */ public function up(): void { - Schema::table('scheduled_task_executions', function (Blueprint $table) { - $table->timestamp('started_at')->nullable()->after('scheduled_task_id'); - $table->integer('retry_count')->default(0)->after('status'); - $table->decimal('duration', 10, 2)->nullable()->after('retry_count')->comment('Duration in seconds'); - $table->text('error_details')->nullable()->after('message'); - }); + if (! Schema::hasColumn('scheduled_task_executions', 'started_at')) { + Schema::table('scheduled_task_executions', function (Blueprint $table) { + $table->timestamp('started_at')->nullable()->after('scheduled_task_id'); + }); + } + + if (! Schema::hasColumn('scheduled_task_executions', 'retry_count')) { + Schema::table('scheduled_task_executions', function (Blueprint $table) { + $table->integer('retry_count')->default(0)->after('status'); + }); + } + + if (! Schema::hasColumn('scheduled_task_executions', 'duration')) { + Schema::table('scheduled_task_executions', function (Blueprint $table) { + $table->decimal('duration', 10, 2)->nullable()->after('retry_count')->comment('Duration in seconds'); + }); + } + + if (! Schema::hasColumn('scheduled_task_executions', 'error_details')) { + Schema::table('scheduled_task_executions', function (Blueprint $table) { + $table->text('error_details')->nullable()->after('message'); + }); + } } /** @@ -24,8 +41,13 @@ public function up(): void */ public function down(): void { - Schema::table('scheduled_task_executions', function (Blueprint $table) { - $table->dropColumn(['started_at', 'retry_count', 'duration', 'error_details']); - }); + $columns = ['started_at', 'retry_count', 'duration', 'error_details']; + foreach ($columns as $column) { + if (Schema::hasColumn('scheduled_task_executions', $column)) { + Schema::table('scheduled_task_executions', function (Blueprint $table) use ($column) { + $table->dropColumn($column); + }); + } + } } }; diff --git a/database/migrations/2025_11_10_112500_add_restart_tracking_to_applications_table.php b/database/migrations/2025_11_10_112500_add_restart_tracking_to_applications_table.php index 329ac7af9..b9dfd4d9d 100644 --- a/database/migrations/2025_11_10_112500_add_restart_tracking_to_applications_table.php +++ b/database/migrations/2025_11_10_112500_add_restart_tracking_to_applications_table.php @@ -11,11 +11,23 @@ */ public function up(): void { - Schema::table('applications', function (Blueprint $table) { - $table->integer('restart_count')->default(0)->after('status'); - $table->timestamp('last_restart_at')->nullable()->after('restart_count'); - $table->string('last_restart_type', 10)->nullable()->after('last_restart_at'); - }); + if (! Schema::hasColumn('applications', 'restart_count')) { + Schema::table('applications', function (Blueprint $table) { + $table->integer('restart_count')->default(0)->after('status'); + }); + } + + if (! Schema::hasColumn('applications', 'last_restart_at')) { + Schema::table('applications', function (Blueprint $table) { + $table->timestamp('last_restart_at')->nullable()->after('restart_count'); + }); + } + + if (! Schema::hasColumn('applications', 'last_restart_type')) { + Schema::table('applications', function (Blueprint $table) { + $table->string('last_restart_type', 10)->nullable()->after('last_restart_at'); + }); + } } /** @@ -23,8 +35,13 @@ public function up(): void */ public function down(): void { - Schema::table('applications', function (Blueprint $table) { - $table->dropColumn(['restart_count', 'last_restart_at', 'last_restart_type']); - }); + $columns = ['restart_count', 'last_restart_at', 'last_restart_type']; + foreach ($columns as $column) { + if (Schema::hasColumn('applications', $column)) { + Schema::table('applications', function (Blueprint $table) use ($column) { + $table->dropColumn($column); + }); + } + } } }; diff --git a/database/migrations/2025_11_12_130931_add_traefik_version_tracking_to_servers_table.php b/database/migrations/2025_11_12_130931_add_traefik_version_tracking_to_servers_table.php index 3bab33368..290423526 100644 --- a/database/migrations/2025_11_12_130931_add_traefik_version_tracking_to_servers_table.php +++ b/database/migrations/2025_11_12_130931_add_traefik_version_tracking_to_servers_table.php @@ -11,9 +11,11 @@ */ public function up(): void { - Schema::table('servers', function (Blueprint $table) { - $table->string('detected_traefik_version')->nullable(); - }); + if (! Schema::hasColumn('servers', 'detected_traefik_version')) { + Schema::table('servers', function (Blueprint $table) { + $table->string('detected_traefik_version')->nullable(); + }); + } } /** @@ -21,8 +23,10 @@ public function up(): void */ public function down(): void { - Schema::table('servers', function (Blueprint $table) { - $table->dropColumn('detected_traefik_version'); - }); + if (Schema::hasColumn('servers', 'detected_traefik_version')) { + Schema::table('servers', function (Blueprint $table) { + $table->dropColumn('detected_traefik_version'); + }); + } } }; diff --git a/database/migrations/2025_11_12_131252_add_traefik_outdated_to_email_notification_settings.php b/database/migrations/2025_11_12_131252_add_traefik_outdated_to_email_notification_settings.php index ac509dc71..61a9c80b1 100644 --- a/database/migrations/2025_11_12_131252_add_traefik_outdated_to_email_notification_settings.php +++ b/database/migrations/2025_11_12_131252_add_traefik_outdated_to_email_notification_settings.php @@ -11,9 +11,11 @@ */ public function up(): void { - Schema::table('email_notification_settings', function (Blueprint $table) { - $table->boolean('traefik_outdated_email_notifications')->default(true); - }); + if (! Schema::hasColumn('email_notification_settings', 'traefik_outdated_email_notifications')) { + Schema::table('email_notification_settings', function (Blueprint $table) { + $table->boolean('traefik_outdated_email_notifications')->default(true); + }); + } } /** @@ -21,8 +23,10 @@ public function up(): void */ public function down(): void { - Schema::table('email_notification_settings', function (Blueprint $table) { - $table->dropColumn('traefik_outdated_email_notifications'); - }); + if (Schema::hasColumn('email_notification_settings', 'traefik_outdated_email_notifications')) { + Schema::table('email_notification_settings', function (Blueprint $table) { + $table->dropColumn('traefik_outdated_email_notifications'); + }); + } } }; diff --git a/database/migrations/2025_11_12_133400_add_traefik_outdated_thread_id_to_telegram_notification_settings.php b/database/migrations/2025_11_12_133400_add_traefik_outdated_thread_id_to_telegram_notification_settings.php index b7d69e634..3ceb07da8 100644 --- a/database/migrations/2025_11_12_133400_add_traefik_outdated_thread_id_to_telegram_notification_settings.php +++ b/database/migrations/2025_11_12_133400_add_traefik_outdated_thread_id_to_telegram_notification_settings.php @@ -11,9 +11,11 @@ */ public function up(): void { - Schema::table('telegram_notification_settings', function (Blueprint $table) { - $table->text('telegram_notifications_traefik_outdated_thread_id')->nullable(); - }); + if (! Schema::hasColumn('telegram_notification_settings', 'telegram_notifications_traefik_outdated_thread_id')) { + Schema::table('telegram_notification_settings', function (Blueprint $table) { + $table->text('telegram_notifications_traefik_outdated_thread_id')->nullable(); + }); + } } /** @@ -21,8 +23,10 @@ public function up(): void */ public function down(): void { - Schema::table('telegram_notification_settings', function (Blueprint $table) { - $table->dropColumn('telegram_notifications_traefik_outdated_thread_id'); - }); + if (Schema::hasColumn('telegram_notification_settings', 'telegram_notifications_traefik_outdated_thread_id')) { + Schema::table('telegram_notification_settings', function (Blueprint $table) { + $table->dropColumn('telegram_notifications_traefik_outdated_thread_id'); + }); + } } }; diff --git a/database/migrations/2025_11_14_114632_add_traefik_outdated_info_to_servers_table.php b/database/migrations/2025_11_14_114632_add_traefik_outdated_info_to_servers_table.php index 99e10707d..12fca4190 100644 --- a/database/migrations/2025_11_14_114632_add_traefik_outdated_info_to_servers_table.php +++ b/database/migrations/2025_11_14_114632_add_traefik_outdated_info_to_servers_table.php @@ -11,9 +11,11 @@ */ public function up(): void { - Schema::table('servers', function (Blueprint $table) { - $table->json('traefik_outdated_info')->nullable(); - }); + if (! Schema::hasColumn('servers', 'traefik_outdated_info')) { + Schema::table('servers', function (Blueprint $table) { + $table->json('traefik_outdated_info')->nullable(); + }); + } } /** @@ -21,8 +23,10 @@ public function up(): void */ public function down(): void { - Schema::table('servers', function (Blueprint $table) { - $table->dropColumn('traefik_outdated_info'); - }); + if (Schema::hasColumn('servers', 'traefik_outdated_info')) { + Schema::table('servers', function (Blueprint $table) { + $table->dropColumn('traefik_outdated_info'); + }); + } } }; diff --git a/database/migrations/2025_11_26_124200_add_build_cache_settings_to_application_settings.php b/database/migrations/2025_11_26_124200_add_build_cache_settings_to_application_settings.php index 5f41816f6..f38c9c2a8 100644 --- a/database/migrations/2025_11_26_124200_add_build_cache_settings_to_application_settings.php +++ b/database/migrations/2025_11_26_124200_add_build_cache_settings_to_application_settings.php @@ -11,10 +11,17 @@ */ public function up(): void { - Schema::table('application_settings', function (Blueprint $table) { - $table->boolean('inject_build_args_to_dockerfile')->default(true)->after('use_build_secrets'); - $table->boolean('include_source_commit_in_build')->default(false)->after('inject_build_args_to_dockerfile'); - }); + if (! Schema::hasColumn('application_settings', 'inject_build_args_to_dockerfile')) { + Schema::table('application_settings', function (Blueprint $table) { + $table->boolean('inject_build_args_to_dockerfile')->default(true)->after('use_build_secrets'); + }); + } + + if (! Schema::hasColumn('application_settings', 'include_source_commit_in_build')) { + Schema::table('application_settings', function (Blueprint $table) { + $table->boolean('include_source_commit_in_build')->default(false)->after('inject_build_args_to_dockerfile'); + }); + } } /** @@ -22,9 +29,16 @@ public function up(): void */ public function down(): void { - Schema::table('application_settings', function (Blueprint $table) { - $table->dropColumn('inject_build_args_to_dockerfile'); - $table->dropColumn('include_source_commit_in_build'); - }); + if (Schema::hasColumn('application_settings', 'inject_build_args_to_dockerfile')) { + Schema::table('application_settings', function (Blueprint $table) { + $table->dropColumn('inject_build_args_to_dockerfile'); + }); + } + + if (Schema::hasColumn('application_settings', 'include_source_commit_in_build')) { + Schema::table('application_settings', function (Blueprint $table) { + $table->dropColumn('include_source_commit_in_build'); + }); + } } }; diff --git a/database/migrations/2025_12_04_134435_add_deployment_queue_limit_to_server_settings.php b/database/migrations/2025_12_04_134435_add_deployment_queue_limit_to_server_settings.php index a1bcab5bb..88c236239 100644 --- a/database/migrations/2025_12_04_134435_add_deployment_queue_limit_to_server_settings.php +++ b/database/migrations/2025_12_04_134435_add_deployment_queue_limit_to_server_settings.php @@ -11,9 +11,11 @@ */ public function up(): void { - Schema::table('server_settings', function (Blueprint $table) { - $table->integer('deployment_queue_limit')->default(25)->after('concurrent_builds'); - }); + if (! Schema::hasColumn('server_settings', 'deployment_queue_limit')) { + Schema::table('server_settings', function (Blueprint $table) { + $table->integer('deployment_queue_limit')->default(25)->after('concurrent_builds'); + }); + } } /** @@ -21,8 +23,10 @@ public function up(): void */ public function down(): void { - Schema::table('server_settings', function (Blueprint $table) { - $table->dropColumn('deployment_queue_limit'); - }); + if (Schema::hasColumn('server_settings', 'deployment_queue_limit')) { + Schema::table('server_settings', function (Blueprint $table) { + $table->dropColumn('deployment_queue_limit'); + }); + } } }; diff --git a/database/migrations/2025_12_05_000000_add_docker_images_to_keep_to_application_settings.php b/database/migrations/2025_12_05_000000_add_docker_images_to_keep_to_application_settings.php index 97547ac45..3cc027466 100644 --- a/database/migrations/2025_12_05_000000_add_docker_images_to_keep_to_application_settings.php +++ b/database/migrations/2025_12_05_000000_add_docker_images_to_keep_to_application_settings.php @@ -8,15 +8,19 @@ { public function up(): void { - Schema::table('application_settings', function (Blueprint $table) { - $table->integer('docker_images_to_keep')->default(2); - }); + if (! Schema::hasColumn('application_settings', 'docker_images_to_keep')) { + Schema::table('application_settings', function (Blueprint $table) { + $table->integer('docker_images_to_keep')->default(2); + }); + } } public function down(): void { - Schema::table('application_settings', function (Blueprint $table) { - $table->dropColumn('docker_images_to_keep'); - }); + if (Schema::hasColumn('application_settings', 'docker_images_to_keep')) { + Schema::table('application_settings', function (Blueprint $table) { + $table->dropColumn('docker_images_to_keep'); + }); + } } }; diff --git a/database/migrations/2025_12_05_100000_add_disable_application_image_retention_to_server_settings.php b/database/migrations/2025_12_05_100000_add_disable_application_image_retention_to_server_settings.php index a2433e5c9..dc70cc9f0 100644 --- a/database/migrations/2025_12_05_100000_add_disable_application_image_retention_to_server_settings.php +++ b/database/migrations/2025_12_05_100000_add_disable_application_image_retention_to_server_settings.php @@ -8,15 +8,19 @@ { public function up(): void { - Schema::table('server_settings', function (Blueprint $table) { - $table->boolean('disable_application_image_retention')->default(false); - }); + if (! Schema::hasColumn('server_settings', 'disable_application_image_retention')) { + Schema::table('server_settings', function (Blueprint $table) { + $table->boolean('disable_application_image_retention')->default(false); + }); + } } public function down(): void { - Schema::table('server_settings', function (Blueprint $table) { - $table->dropColumn('disable_application_image_retention'); - }); + if (Schema::hasColumn('server_settings', 'disable_application_image_retention')) { + Schema::table('server_settings', function (Blueprint $table) { + $table->dropColumn('disable_application_image_retention'); + }); + } } }; diff --git a/database/migrations/2025_12_10_135600_add_uuid_to_cloud_provider_tokens.php b/database/migrations/2025_12_10_135600_add_uuid_to_cloud_provider_tokens.php index bd285c180..56f44794d 100644 --- a/database/migrations/2025_12_10_135600_add_uuid_to_cloud_provider_tokens.php +++ b/database/migrations/2025_12_10_135600_add_uuid_to_cloud_provider_tokens.php @@ -13,25 +13,27 @@ */ public function up(): void { - Schema::table('cloud_provider_tokens', function (Blueprint $table) { - $table->string('uuid')->nullable()->unique()->after('id'); - }); - - // Generate UUIDs for existing records using chunked processing - DB::table('cloud_provider_tokens') - ->whereNull('uuid') - ->chunkById(500, function ($tokens) { - foreach ($tokens as $token) { - DB::table('cloud_provider_tokens') - ->where('id', $token->id) - ->update(['uuid' => (string) new Cuid2]); - } + if (! Schema::hasColumn('cloud_provider_tokens', 'uuid')) { + Schema::table('cloud_provider_tokens', function (Blueprint $table) { + $table->string('uuid')->nullable()->unique()->after('id'); }); - // Make uuid non-nullable after filling in values - Schema::table('cloud_provider_tokens', function (Blueprint $table) { - $table->string('uuid')->nullable(false)->change(); - }); + // Generate UUIDs for existing records using chunked processing + DB::table('cloud_provider_tokens') + ->whereNull('uuid') + ->chunkById(500, function ($tokens) { + foreach ($tokens as $token) { + DB::table('cloud_provider_tokens') + ->where('id', $token->id) + ->update(['uuid' => (string) new Cuid2]); + } + }); + + // Make uuid non-nullable after filling in values + Schema::table('cloud_provider_tokens', function (Blueprint $table) { + $table->string('uuid')->nullable(false)->change(); + }); + } } /** @@ -39,8 +41,10 @@ public function up(): void */ public function down(): void { - Schema::table('cloud_provider_tokens', function (Blueprint $table) { - $table->dropColumn('uuid'); - }); + if (Schema::hasColumn('cloud_provider_tokens', 'uuid')) { + Schema::table('cloud_provider_tokens', function (Blueprint $table) { + $table->dropColumn('uuid'); + }); + } } };