From c584baede85a620cbf55d687ac19d40a83d28f4c Mon Sep 17 00:00:00 2001 From: Surya Prashanth Date: Mon, 23 Jun 2025 15:15:21 +0530 Subject: [PATCH] [SILO-325] chore: add migration to remove silo- prefix from apps (#3467) * [SILO-325] chore: add migration to remove silo- prefix from apps * add db app as dependency in migration --- .../migrations/0005_auto_20250620_0618.py | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 apiserver/plane/authentication/migrations/0005_auto_20250620_0618.py diff --git a/apiserver/plane/authentication/migrations/0005_auto_20250620_0618.py b/apiserver/plane/authentication/migrations/0005_auto_20250620_0618.py new file mode 100644 index 0000000000..90c0310c54 --- /dev/null +++ b/apiserver/plane/authentication/migrations/0005_auto_20250620_0618.py @@ -0,0 +1,99 @@ +# Generated by Django 4.2.22 on 2025-06-20 06:18 + +import logging +from django.db import migrations, transaction + +migrate_list = [ + "silo-gitlab", + "silo-slack", + "silo-github", + "silo-jira", + "silo-jira-server", + "silo-linear", + "silo-asana", + "silo-importer", +] + +rollback_list = [ + "gitlab", + "slack", + "github", + "jira", + "jira-server", + "linear", + "asana", + "importer", +] + +logger = logging.getLogger(__name__) + + +def create_migration_function(operation_type): + """ + Creates a migration function based on the slug list and operation type. + + Args: + slug_list: List of slugs to operate on + operation_type: Either 'migrate' or 'rollback' + """ + + def migration_function(apps, schema_editor): + Application = apps.get_model("authentication", "Application") + WorkspaceAppInstallation = apps.get_model( + "authentication", "WorkspaceAppInstallation" + ) + User = apps.get_model("db", "User") + slug_list = migrate_list if operation_type == "migrate" else rollback_list + + with transaction.atomic(): + # Get app IDs based on the slug list + app_ids = Application.objects.filter(slug__in=slug_list).values_list( + "id", flat=True + ) + + logger.info( + f"Found {len(app_ids)} applications to update for {operation_type}" + ) + + # Update application slugs + for app in Application.objects.filter(id__in=app_ids): + old_slug = app.slug + if operation_type == "migrate": + app.slug = app.slug.replace("silo-", "") + elif operation_type == "rollback": + app.slug = "silo-" + app.slug + new_slug = app.slug + app.save(update_fields=["slug"]) + logger.info(f"Updated app slug from {old_slug} to {app.slug}") + + # workspace app installations + workspace_app_installations = WorkspaceAppInstallation.objects.filter( + application_id=app.id + ) + for workspace_app_installation in workspace_app_installations: + workspace = workspace_app_installation.workspace + user = User.objects.get(id=workspace_app_installation.app_bot_id) + old_email = user.email + email = f"{workspace.slug}_{new_slug}_bot@plane.so" + + logger.info(f"Updating user email from {old_email} to {email}") + user.email = email + user.save(update_fields=["email"]) + + return migration_function + + +# Create the migration and rollback functions +migrate_slugs = create_migration_function("migrate") +reverse_migrate_slugs = create_migration_function("rollback") + + +class Migration(migrations.Migration): + dependencies = [ + ("authentication", "0004_application_is_mentionable"), + ("db", "__first__"), + ] + + operations = [ + migrations.RunPython(migrate_slugs, reverse_migrate_slugs), + ]