From 1b7ada43159a8dea52196d223ed6e7b0e9400f4f Mon Sep 17 00:00:00 2001 From: Ildar Iskhakov Date: Mon, 6 Feb 2023 16:01:37 +0800 Subject: [PATCH] Add database migrations linter (#1020) # What this PR does This PR adds [django-migration-linter](https://github.com/3YOURMIND/django-migration-linter) to keep database migrations backwards compatible - we can automatically run migrations and they are zero-downtime, e.g. old code can work with the migrated database - we can run and rollback migrations without worrying about data safety - OnCall is deployed to the multiple environments core team is not able to control See [django-migration-linter checklist](https://github.com/3YOURMIND/django-migration-linter/blob/main/docs/incompatibilities.md) for the common mistakes and best practices ## Which issue(s) this PR fixes ## Checklist - [ ] Tests updated - [ ] Documentation added - [ ] `CHANGELOG.md` updated --------- Co-authored-by: Joey Orlando --- .github/workflows/ci.yml | 29 +++++++++++++++++++ dev/README.md | 13 +++++++++ .../migrations/0001_squashed_initial.py | 2 ++ .../migrations/0002_squashed_initial.py | 2 ++ ...fanaalertingcontactpoint_datasource_uid.py | 2 ++ .../migrations/0004_auto_20220711_1106.py | 2 ++ .../0005_alertgroup_cached_render_for_web.py | 2 ++ ...ertgroup_alerts_aler_channel_ee84a7_idx.py | 2 ++ .../0007_populate_web_title_cache.py | 2 ++ .../0008_alter_alertgrouplogrecord_type.py | 2 ++ .../migrations/0001_squashed_initial.py | 2 ++ .../migrations/0002_squashed_initial.py | 2 ++ .../migrations/0003_auto_20221121_1610.py | 2 ++ .../base/migrations/0001_squashed_initial.py | 2 ++ .../base/migrations/0002_squashed_initial.py | 2 ++ .../0003_delete_organizationlogrecord.py | 2 ++ engine/apps/email/migrations/0001_initial.py | 2 ++ .../migrations/0001_squashed_initial.py | 2 ++ .../mobile_app/migrations/0001_initial.py | 2 ++ .../migrations/0001_squashed_initial.py | 2 ++ .../migrations/0001_squashed_initial.py | 2 ++ .../migrations/0002_squashed_initial.py | 2 ++ .../0003_alter_customoncallshift_frequency.py | 2 ++ .../0004_customoncallshift_until.py | 2 ++ .../migrations/0005_auto_20220704_1947.py | 2 ++ .../0006_customoncallshift_rotation_start.py | 2 ++ .../0007_customoncallshift_updated_shift.py | 2 ++ .../migrations/0008_auto_20221201_0809.py | 2 ++ .../slack/migrations/0001_squashed_initial.py | 2 ++ .../slack/migrations/0002_squashed_initial.py | 2 ++ .../migrations/0001_squashed_initial.py | 2 ++ ...0002_alter_telegrammessage_message_type.py | 2 ++ .../migrations/0001_squashed_initial.py | 2 ++ .../migrations/0002_auto_20220604_1008.py | 2 ++ .../migrations/0001_squashed_initial.py | 2 ++ .../migrations/0002_auto_20220705_1214.py | 2 ++ .../migrations/0003_user_hide_phone_number.py | 2 ++ .../migrations/0004_auto_20221025_0316.py | 2 ++ .../migrations/0005_rbac_permissions.py | 2 ++ .../migrations/0006_organization_uuid.py | 2 ++ .../0007_organization_deleted_at.py | 2 ++ ...rganization_is_grafana_incident_enabled.py | 2 ++ engine/requirements.txt | 1 + engine/settings/base.py | 5 ++++ 44 files changed, 128 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bb574046..29f34083 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,6 +23,9 @@ jobs: cd grafana-plugin/ yarn --network-timeout 500000 yarn build + # pre-commit uses git, which is not working in the action without this workaround + # see https://github.com/actions/runner-images/issues/6775 + - run: git config --global --add safe.directory "$GITHUB_WORKSPACE" - name: Lint All run: | pre-commit run --all-files @@ -55,6 +58,32 @@ jobs: run: | docker run -v ${PWD}/docs/sources:/hugo/content/docs/oncall/latest -e HUGO_REFLINKSERRORLEVEL=ERROR --rm grafana/docs-base:latest /bin/bash -c 'make hugo' + lint-migrations-backend-mysql-rabbitmq: + name: "Lint migrations" + runs-on: ubuntu-latest + container: python:3.9 + env: + DJANGO_SETTINGS_MODULE: settings.ci-test + SLACK_CLIENT_OAUTH_ID: 1 + services: + rabbit_test: + image: rabbitmq:3.7.19 + env: + RABBITMQ_DEFAULT_USER: rabbitmq + RABBITMQ_DEFAULT_PASS: rabbitmq + mysql_test: + image: mysql:5.7.25 + env: + MYSQL_DATABASE: oncall_local_dev + MYSQL_ROOT_PASSWORD: local_dev_pwd + steps: + - uses: actions/checkout@v3 + - name: Lint migrations + run: | + cd engine/ + pip install -r requirements.txt + python manage.py lintmigrations + unit-test-backend-mysql-rabbitmq: name: "Backend Tests: MySQL + RabbitMQ (RBAC enabled: ${{ matrix.rbac_enabled }})" runs-on: ubuntu-latest diff --git a/dev/README.md b/dev/README.md index bd88dabf..15b3fd9c 100644 --- a/dev/README.md +++ b/dev/README.md @@ -20,6 +20,7 @@ - [symbol not found in flat namespace '\_EVP_DigestSignUpdate'](#symbol-not-found-in-flat-namespace-_evp_digestsignupdate) - [IDE Specific Instructions](#ide-specific-instructions) - [PyCharm](#pycharm) +- [How to write database migrations](#how-to-write-database-migrations) Related: [How to develop integrations](/engine/config_integrations/README.md) @@ -397,3 +398,15 @@ make run-backend-celery 5. Create a new Django Server run configuration to Run/Debug the engine - Use a plugin such as EnvFile to load the .env.dev file - Change port from 8000 to 8080 + +## How to write database migrations + +We use [django-migration-linter](https://github.com/3YOURMIND/django-migration-linter) to keep database migrations +backwards compatible + +- we can automatically run migrations and they are zero-downtime, e.g. old code can work with the migrated database +- we can run and rollback migrations without worrying about data safety +- OnCall is deployed to the multiple environments core team is not able to control + +See [django-migration-linter checklist](https://github.com/3YOURMIND/django-migration-linter/blob/main/docs/incompatibilities.md) +for the common mistakes and best practices diff --git a/engine/apps/alerts/migrations/0001_squashed_initial.py b/engine/apps/alerts/migrations/0001_squashed_initial.py index bc66bc5c..0c96d7d4 100644 --- a/engine/apps/alerts/migrations/0001_squashed_initial.py +++ b/engine/apps/alerts/migrations/0001_squashed_initial.py @@ -15,6 +15,7 @@ import django.core.validators from django.db import migrations, models import django.db.models.deletion import django.db.models.manager +import django_migration_linter as linter from apps.alerts.integration_options_mixin import IntegrationOptionsMixin @@ -27,6 +28,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.CreateModel( name='Alert', fields=[ diff --git a/engine/apps/alerts/migrations/0002_squashed_initial.py b/engine/apps/alerts/migrations/0002_squashed_initial.py index bd0b33dc..765e8bfa 100644 --- a/engine/apps/alerts/migrations/0002_squashed_initial.py +++ b/engine/apps/alerts/migrations/0002_squashed_initial.py @@ -3,6 +3,7 @@ from django.db import migrations, models import django.db.models.deletion import django.db.models.manager +import django_migration_linter as linter class Migration(migrations.Migration): @@ -18,6 +19,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.AddField( model_name='userhasnotification', name='user', diff --git a/engine/apps/alerts/migrations/0003_grafanaalertingcontactpoint_datasource_uid.py b/engine/apps/alerts/migrations/0003_grafanaalertingcontactpoint_datasource_uid.py index 4bdcec63..2962923a 100644 --- a/engine/apps/alerts/migrations/0003_grafanaalertingcontactpoint_datasource_uid.py +++ b/engine/apps/alerts/migrations/0003_grafanaalertingcontactpoint_datasource_uid.py @@ -1,6 +1,7 @@ # Generated by Django 3.2.13 on 2022-06-14 15:18 from django.db import migrations, models +import django_migration_linter as linter class Migration(migrations.Migration): @@ -10,6 +11,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.AddField( model_name='grafanaalertingcontactpoint', name='datasource_uid', diff --git a/engine/apps/alerts/migrations/0004_auto_20220711_1106.py b/engine/apps/alerts/migrations/0004_auto_20220711_1106.py index ddae2447..6e0396b8 100644 --- a/engine/apps/alerts/migrations/0004_auto_20220711_1106.py +++ b/engine/apps/alerts/migrations/0004_auto_20220711_1106.py @@ -1,6 +1,7 @@ # Generated by Django 3.2.13 on 2022-07-11 11:06 from django.db import migrations +import django_migration_linter as linter class Migration(migrations.Migration): @@ -17,6 +18,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), # migrations.RemoveField( # model_name='alertgroup', # name='active_cache_for_web_calculation_id', diff --git a/engine/apps/alerts/migrations/0005_alertgroup_cached_render_for_web.py b/engine/apps/alerts/migrations/0005_alertgroup_cached_render_for_web.py index cff73da3..7717a56a 100644 --- a/engine/apps/alerts/migrations/0005_alertgroup_cached_render_for_web.py +++ b/engine/apps/alerts/migrations/0005_alertgroup_cached_render_for_web.py @@ -1,6 +1,7 @@ # Generated by Django 3.2.13 on 2022-07-20 09:04 from django.db import migrations, models, OperationalError, ProgrammingError +import django_migration_linter as linter class AddFieldIfNotExists(migrations.AddField): @@ -36,6 +37,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), AddFieldIfNotExists( model_name='alertgroup', name='cached_render_for_web', diff --git a/engine/apps/alerts/migrations/0006_alertgroup_alerts_aler_channel_ee84a7_idx.py b/engine/apps/alerts/migrations/0006_alertgroup_alerts_aler_channel_ee84a7_idx.py index ada7b0da..d3ec42ab 100644 --- a/engine/apps/alerts/migrations/0006_alertgroup_alerts_aler_channel_ee84a7_idx.py +++ b/engine/apps/alerts/migrations/0006_alertgroup_alerts_aler_channel_ee84a7_idx.py @@ -1,6 +1,7 @@ # Generated by Django 3.2.13 on 2022-07-27 10:51 from django.db import migrations, models +import django_migration_linter as linter class Migration(migrations.Migration): @@ -10,6 +11,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.AddIndex( model_name='alertgroup', index=models.Index(fields=['channel_id', 'resolved', 'acknowledged', 'silenced', 'root_alert_group_id', 'is_archived'], name='alerts_aler_channel_ee84a7_idx'), diff --git a/engine/apps/alerts/migrations/0007_populate_web_title_cache.py b/engine/apps/alerts/migrations/0007_populate_web_title_cache.py index 9869a9da..09ada136 100644 --- a/engine/apps/alerts/migrations/0007_populate_web_title_cache.py +++ b/engine/apps/alerts/migrations/0007_populate_web_title_cache.py @@ -4,6 +4,7 @@ from django.db import migrations from apps.alerts.models import AlertReceiveChannel from apps.alerts.tasks import update_web_title_cache_for_alert_receive_channel +import django_migration_linter as linter def populate_web_title_cache(apps, _): @@ -19,6 +20,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.RenameField( model_name='alertgroup', old_name='verbose_name', diff --git a/engine/apps/alerts/migrations/0008_alter_alertgrouplogrecord_type.py b/engine/apps/alerts/migrations/0008_alter_alertgrouplogrecord_type.py index f805f599..08ea965c 100644 --- a/engine/apps/alerts/migrations/0008_alter_alertgrouplogrecord_type.py +++ b/engine/apps/alerts/migrations/0008_alter_alertgrouplogrecord_type.py @@ -1,6 +1,7 @@ # Generated by Django 3.2.16 on 2023-01-19 18:06 from django.db import migrations, models +import django_migration_linter as linter class Migration(migrations.Migration): @@ -10,6 +11,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.AlterField( model_name='alertgrouplogrecord', name='type', diff --git a/engine/apps/auth_token/migrations/0001_squashed_initial.py b/engine/apps/auth_token/migrations/0001_squashed_initial.py index 7c7fe23a..b816d815 100644 --- a/engine/apps/auth_token/migrations/0001_squashed_initial.py +++ b/engine/apps/auth_token/migrations/0001_squashed_initial.py @@ -3,6 +3,7 @@ from django.utils import timezone import apps.auth_token.models.slack_auth_token from django.db import migrations, models +import django_migration_linter as linter class Migration(migrations.Migration): @@ -13,6 +14,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.CreateModel( name='ApiAuthToken', fields=[ diff --git a/engine/apps/auth_token/migrations/0002_squashed_initial.py b/engine/apps/auth_token/migrations/0002_squashed_initial.py index e35e5ce2..8141df51 100644 --- a/engine/apps/auth_token/migrations/0002_squashed_initial.py +++ b/engine/apps/auth_token/migrations/0002_squashed_initial.py @@ -2,6 +2,7 @@ from django.db import migrations, models import django.db.models.deletion +import django_migration_linter as linter class Migration(migrations.Migration): @@ -15,6 +16,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.AddField( model_name='userscheduleexportauthtoken', name='organization', diff --git a/engine/apps/auth_token/migrations/0003_auto_20221121_1610.py b/engine/apps/auth_token/migrations/0003_auto_20221121_1610.py index 08406946..df003a55 100644 --- a/engine/apps/auth_token/migrations/0003_auto_20221121_1610.py +++ b/engine/apps/auth_token/migrations/0003_auto_20221121_1610.py @@ -1,6 +1,7 @@ # Generated by Django 3.2.16 on 2022-11-21 16:10 from django.db import migrations +import django_migration_linter as linter class Migration(migrations.Migration): @@ -10,6 +11,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.RemoveField( model_name='mobileappverificationtoken', name='organization', diff --git a/engine/apps/base/migrations/0001_squashed_initial.py b/engine/apps/base/migrations/0001_squashed_initial.py index 0055fa88..ee0572ef 100644 --- a/engine/apps/base/migrations/0001_squashed_initial.py +++ b/engine/apps/base/migrations/0001_squashed_initial.py @@ -6,6 +6,7 @@ import datetime import django.core.validators from django.db import migrations, models import django.db.models.deletion +import django_migration_linter as linter class Migration(migrations.Migration): @@ -17,6 +18,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.CreateModel( name='DynamicSetting', fields=[ diff --git a/engine/apps/base/migrations/0002_squashed_initial.py b/engine/apps/base/migrations/0002_squashed_initial.py index 9bf98adb..18cb6bcc 100644 --- a/engine/apps/base/migrations/0002_squashed_initial.py +++ b/engine/apps/base/migrations/0002_squashed_initial.py @@ -2,6 +2,7 @@ from django.db import migrations, models import django.db.models.deletion +import django_migration_linter as linter class Migration(migrations.Migration): @@ -14,6 +15,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.AddField( model_name='usernotificationpolicylogrecord', name='author', diff --git a/engine/apps/base/migrations/0003_delete_organizationlogrecord.py b/engine/apps/base/migrations/0003_delete_organizationlogrecord.py index b0a49a1a..c5515881 100644 --- a/engine/apps/base/migrations/0003_delete_organizationlogrecord.py +++ b/engine/apps/base/migrations/0003_delete_organizationlogrecord.py @@ -1,6 +1,7 @@ # Generated by Django 3.2.5 on 2022-08-23 12:03 from django.db import migrations +import django_migration_linter as linter class Migration(migrations.Migration): @@ -10,6 +11,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.DeleteModel( name='OrganizationLogRecord', ), diff --git a/engine/apps/email/migrations/0001_initial.py b/engine/apps/email/migrations/0001_initial.py index 3fe9537a..8b5a7e94 100644 --- a/engine/apps/email/migrations/0001_initial.py +++ b/engine/apps/email/migrations/0001_initial.py @@ -3,6 +3,7 @@ from django.db import migrations, models import django.db.models.deletion import uuid +import django_migration_linter as linter class Migration(migrations.Migration): @@ -16,6 +17,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.CreateModel( name='EmailMessage', fields=[ diff --git a/engine/apps/heartbeat/migrations/0001_squashed_initial.py b/engine/apps/heartbeat/migrations/0001_squashed_initial.py index a30b29e7..687c9a3c 100644 --- a/engine/apps/heartbeat/migrations/0001_squashed_initial.py +++ b/engine/apps/heartbeat/migrations/0001_squashed_initial.py @@ -4,6 +4,7 @@ import apps.heartbeat.models import django.core.validators from django.db import migrations, models import django.db.models.deletion +import django_migration_linter as linter class Migration(migrations.Migration): @@ -15,6 +16,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.CreateModel( name='IntegrationHeartBeat', fields=[ diff --git a/engine/apps/mobile_app/migrations/0001_initial.py b/engine/apps/mobile_app/migrations/0001_initial.py index de3faf32..a52c649c 100644 --- a/engine/apps/mobile_app/migrations/0001_initial.py +++ b/engine/apps/mobile_app/migrations/0001_initial.py @@ -3,6 +3,7 @@ import apps.mobile_app.models from django.db import migrations, models import django.db.models.deletion +import django_migration_linter as linter class Migration(migrations.Migration): @@ -15,6 +16,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.CreateModel( name='MobileAppVerificationToken', fields=[ diff --git a/engine/apps/oss_installation/migrations/0001_squashed_initial.py b/engine/apps/oss_installation/migrations/0001_squashed_initial.py index b1a34cbd..fc7def6e 100644 --- a/engine/apps/oss_installation/migrations/0001_squashed_initial.py +++ b/engine/apps/oss_installation/migrations/0001_squashed_initial.py @@ -2,6 +2,7 @@ from django.db import migrations, models import uuid +import django_migration_linter as linter class Migration(migrations.Migration): @@ -12,6 +13,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.CreateModel( name='CloudHeartbeat', fields=[ diff --git a/engine/apps/schedules/migrations/0001_squashed_initial.py b/engine/apps/schedules/migrations/0001_squashed_initial.py index 8456b7fe..e55e1aba 100644 --- a/engine/apps/schedules/migrations/0001_squashed_initial.py +++ b/engine/apps/schedules/migrations/0001_squashed_initial.py @@ -6,6 +6,7 @@ import django.core.validators from django.db import migrations, models import django.db.models.deletion import uuid +import django_migration_linter as linter class Migration(migrations.Migration): @@ -16,6 +17,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.CreateModel( name='CustomOnCallShift', fields=[ diff --git a/engine/apps/schedules/migrations/0002_squashed_initial.py b/engine/apps/schedules/migrations/0002_squashed_initial.py index d5e25ccd..c33cf204 100644 --- a/engine/apps/schedules/migrations/0002_squashed_initial.py +++ b/engine/apps/schedules/migrations/0002_squashed_initial.py @@ -2,6 +2,7 @@ from django.db import migrations, models import django.db.models.deletion +import django_migration_linter as linter class Migration(migrations.Migration): @@ -16,6 +17,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.AddField( model_name='oncallschedule', name='organization', diff --git a/engine/apps/schedules/migrations/0003_alter_customoncallshift_frequency.py b/engine/apps/schedules/migrations/0003_alter_customoncallshift_frequency.py index 239ce026..fa56dd7c 100644 --- a/engine/apps/schedules/migrations/0003_alter_customoncallshift_frequency.py +++ b/engine/apps/schedules/migrations/0003_alter_customoncallshift_frequency.py @@ -1,6 +1,7 @@ # Generated by Django 3.2.5 on 2022-06-28 13:06 from django.db import migrations, models +import django_migration_linter as linter class Migration(migrations.Migration): @@ -10,6 +11,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.AlterField( model_name='customoncallshift', name='frequency', diff --git a/engine/apps/schedules/migrations/0004_customoncallshift_until.py b/engine/apps/schedules/migrations/0004_customoncallshift_until.py index 46c3c8e2..3f501cfa 100644 --- a/engine/apps/schedules/migrations/0004_customoncallshift_until.py +++ b/engine/apps/schedules/migrations/0004_customoncallshift_until.py @@ -1,6 +1,7 @@ # Generated by Django 3.2.5 on 2022-06-28 13:07 from django.db import migrations, models +import django_migration_linter as linter class Migration(migrations.Migration): @@ -10,6 +11,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.AddField( model_name='customoncallshift', name='until', diff --git a/engine/apps/schedules/migrations/0005_auto_20220704_1947.py b/engine/apps/schedules/migrations/0005_auto_20220704_1947.py index 03b77e60..aa159184 100644 --- a/engine/apps/schedules/migrations/0005_auto_20220704_1947.py +++ b/engine/apps/schedules/migrations/0005_auto_20220704_1947.py @@ -2,6 +2,7 @@ from django.db import migrations, models import django.db.models.deletion +import django_migration_linter as linter class Migration(migrations.Migration): @@ -11,6 +12,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.CreateModel( name='OnCallScheduleWeb', fields=[ diff --git a/engine/apps/schedules/migrations/0006_customoncallshift_rotation_start.py b/engine/apps/schedules/migrations/0006_customoncallshift_rotation_start.py index 682df514..3a1c02e0 100644 --- a/engine/apps/schedules/migrations/0006_customoncallshift_rotation_start.py +++ b/engine/apps/schedules/migrations/0006_customoncallshift_rotation_start.py @@ -2,6 +2,7 @@ from django.db import migrations, models from django.db.models import F +import django_migration_linter as linter def fill_rotation_start_field(apps, schema_editor): @@ -16,6 +17,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.AddField( model_name='customoncallshift', name='rotation_start', diff --git a/engine/apps/schedules/migrations/0007_customoncallshift_updated_shift.py b/engine/apps/schedules/migrations/0007_customoncallshift_updated_shift.py index c034f53a..a7c36c0b 100644 --- a/engine/apps/schedules/migrations/0007_customoncallshift_updated_shift.py +++ b/engine/apps/schedules/migrations/0007_customoncallshift_updated_shift.py @@ -2,6 +2,7 @@ from django.db import migrations, models import django.db.models.deletion +import django_migration_linter as linter class Migration(migrations.Migration): @@ -11,6 +12,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.AddField( model_name='customoncallshift', name='updated_shift', diff --git a/engine/apps/schedules/migrations/0008_auto_20221201_0809.py b/engine/apps/schedules/migrations/0008_auto_20221201_0809.py index 0aee5c7e..27b9b6ad 100644 --- a/engine/apps/schedules/migrations/0008_auto_20221201_0809.py +++ b/engine/apps/schedules/migrations/0008_auto_20221201_0809.py @@ -5,6 +5,7 @@ from django.db import migrations from django.db.models import Q from common.timezones import is_valid_timezone +import django_migration_linter as linter def fix_bad_timezone_values(model): @@ -34,6 +35,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.RunPython(fix_bad_timezone_values('CustomOnCallShift')), migrations.RunPython(fix_bad_timezone_values('OnCallScheduleCalendar')), migrations.RunPython(fix_bad_timezone_values('OnCallScheduleWeb')), diff --git a/engine/apps/slack/migrations/0001_squashed_initial.py b/engine/apps/slack/migrations/0001_squashed_initial.py index 7bc20cbb..3a3140d2 100644 --- a/engine/apps/slack/migrations/0001_squashed_initial.py +++ b/engine/apps/slack/migrations/0001_squashed_initial.py @@ -6,6 +6,7 @@ import django.core.validators from django.db import migrations, models import django.db.models.deletion import uuid +import django_migration_linter as linter class Migration(migrations.Migration): @@ -17,6 +18,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.CreateModel( name='SlackActionRecord', fields=[ diff --git a/engine/apps/slack/migrations/0002_squashed_initial.py b/engine/apps/slack/migrations/0002_squashed_initial.py index 3f322e6d..d0595e79 100644 --- a/engine/apps/slack/migrations/0002_squashed_initial.py +++ b/engine/apps/slack/migrations/0002_squashed_initial.py @@ -2,6 +2,7 @@ from django.db import migrations, models import django.db.models.deletion +import django_migration_linter as linter class Migration(migrations.Migration): @@ -14,6 +15,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.AddField( model_name='slackmessage', name='organization', diff --git a/engine/apps/telegram/migrations/0001_squashed_initial.py b/engine/apps/telegram/migrations/0001_squashed_initial.py index 196726e0..aea99590 100644 --- a/engine/apps/telegram/migrations/0001_squashed_initial.py +++ b/engine/apps/telegram/migrations/0001_squashed_initial.py @@ -5,6 +5,7 @@ import django.core.validators from django.db import migrations, models import django.db.models.deletion import uuid +import django_migration_linter as linter class Migration(migrations.Migration): @@ -17,6 +18,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.CreateModel( name='TelegramVerificationCode', fields=[ diff --git a/engine/apps/telegram/migrations/0002_alter_telegrammessage_message_type.py b/engine/apps/telegram/migrations/0002_alter_telegrammessage_message_type.py index 96415381..8e59f282 100644 --- a/engine/apps/telegram/migrations/0002_alter_telegrammessage_message_type.py +++ b/engine/apps/telegram/migrations/0002_alter_telegrammessage_message_type.py @@ -1,6 +1,7 @@ # Generated by Django 3.2.16 on 2022-12-29 14:42 from django.db import migrations, models +import django_migration_linter as linter class Migration(migrations.Migration): @@ -10,6 +11,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.AlterField( model_name='telegrammessage', name='message_type', diff --git a/engine/apps/twilioapp/migrations/0001_squashed_initial.py b/engine/apps/twilioapp/migrations/0001_squashed_initial.py index cd76ebdf..ffd3183f 100644 --- a/engine/apps/twilioapp/migrations/0001_squashed_initial.py +++ b/engine/apps/twilioapp/migrations/0001_squashed_initial.py @@ -2,6 +2,7 @@ from django.db import migrations, models import django.db.models.deletion +import django_migration_linter as linter class Migration(migrations.Migration): @@ -15,6 +16,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.CreateModel( name='TwilioLogRecord', fields=[ diff --git a/engine/apps/twilioapp/migrations/0002_auto_20220604_1008.py b/engine/apps/twilioapp/migrations/0002_auto_20220604_1008.py index cddd898c..4771d7a1 100644 --- a/engine/apps/twilioapp/migrations/0002_auto_20220604_1008.py +++ b/engine/apps/twilioapp/migrations/0002_auto_20220604_1008.py @@ -1,6 +1,7 @@ # Generated by Django 3.2.5 on 2022-06-04 10:08 from django.db import migrations, models +import django_migration_linter as linter class Migration(migrations.Migration): @@ -10,6 +11,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.AddField( model_name='phonecall', name='grafana_cloud_notification', diff --git a/engine/apps/user_management/migrations/0001_squashed_initial.py b/engine/apps/user_management/migrations/0001_squashed_initial.py index e88a5acb..c2308b64 100644 --- a/engine/apps/user_management/migrations/0001_squashed_initial.py +++ b/engine/apps/user_management/migrations/0001_squashed_initial.py @@ -8,6 +8,7 @@ import django.core.validators from django.db import migrations, models import django.db.models.deletion import mirage.fields +import django_migration_linter as linter class Migration(migrations.Migration): @@ -20,6 +21,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.CreateModel( name='Organization', fields=[ diff --git a/engine/apps/user_management/migrations/0002_auto_20220705_1214.py b/engine/apps/user_management/migrations/0002_auto_20220705_1214.py index 976bfe7a..fce96fe1 100644 --- a/engine/apps/user_management/migrations/0002_auto_20220705_1214.py +++ b/engine/apps/user_management/migrations/0002_auto_20220705_1214.py @@ -2,6 +2,7 @@ import apps.user_management.models.user from django.db import migrations, models +import django_migration_linter as linter class Migration(migrations.Migration): @@ -11,6 +12,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.AddField( model_name='user', name='_timezone', diff --git a/engine/apps/user_management/migrations/0003_user_hide_phone_number.py b/engine/apps/user_management/migrations/0003_user_hide_phone_number.py index e1d3a0ed..272e94a0 100644 --- a/engine/apps/user_management/migrations/0003_user_hide_phone_number.py +++ b/engine/apps/user_management/migrations/0003_user_hide_phone_number.py @@ -1,6 +1,7 @@ # Generated by Django 3.2.5 on 2022-08-25 08:51 from django.db import migrations, models +import django_migration_linter as linter class Migration(migrations.Migration): @@ -10,6 +11,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.AddField( model_name='user', name='hide_phone_number', diff --git a/engine/apps/user_management/migrations/0004_auto_20221025_0316.py b/engine/apps/user_management/migrations/0004_auto_20221025_0316.py index 8d1b15c8..01707dfd 100644 --- a/engine/apps/user_management/migrations/0004_auto_20221025_0316.py +++ b/engine/apps/user_management/migrations/0004_auto_20221025_0316.py @@ -2,6 +2,7 @@ from django.db import migrations, models import django.db.models.deletion +import django_migration_linter as linter class Migration(migrations.Migration): @@ -11,6 +12,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.CreateModel( name='Region', fields=[ diff --git a/engine/apps/user_management/migrations/0005_rbac_permissions.py b/engine/apps/user_management/migrations/0005_rbac_permissions.py index 560aa144..e1f4d5d7 100644 --- a/engine/apps/user_management/migrations/0005_rbac_permissions.py +++ b/engine/apps/user_management/migrations/0005_rbac_permissions.py @@ -1,6 +1,7 @@ # Generated by Django 3.2.15 on 2022-10-25 11:18 from django.db import migrations, models +import django_migration_linter as linter class Migration(migrations.Migration): @@ -10,6 +11,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.AddField( model_name='organization', name='is_rbac_permissions_enabled', diff --git a/engine/apps/user_management/migrations/0006_organization_uuid.py b/engine/apps/user_management/migrations/0006_organization_uuid.py index ab2e1d2b..e58c0bd6 100644 --- a/engine/apps/user_management/migrations/0006_organization_uuid.py +++ b/engine/apps/user_management/migrations/0006_organization_uuid.py @@ -2,6 +2,7 @@ from django.db import migrations, models import uuid +import django_migration_linter as linter def fill_org_uuid(apps, schema_editor): @@ -20,6 +21,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.AddField( model_name='organization', name='uuid', diff --git a/engine/apps/user_management/migrations/0007_organization_deleted_at.py b/engine/apps/user_management/migrations/0007_organization_deleted_at.py index fd80179e..76a718c5 100644 --- a/engine/apps/user_management/migrations/0007_organization_deleted_at.py +++ b/engine/apps/user_management/migrations/0007_organization_deleted_at.py @@ -1,6 +1,7 @@ # Generated by Django 3.2.16 on 2023-01-04 05:06 from django.db import migrations, models +import django_migration_linter as linter class Migration(migrations.Migration): @@ -10,6 +11,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.AddField( model_name='organization', name='deleted_at', diff --git a/engine/apps/user_management/migrations/0008_organization_is_grafana_incident_enabled.py b/engine/apps/user_management/migrations/0008_organization_is_grafana_incident_enabled.py index 3c8598e9..b7d75913 100644 --- a/engine/apps/user_management/migrations/0008_organization_is_grafana_incident_enabled.py +++ b/engine/apps/user_management/migrations/0008_organization_is_grafana_incident_enabled.py @@ -1,6 +1,7 @@ # Generated by Django 3.2.16 on 2023-01-16 09:41 from django.db import migrations, models +import django_migration_linter as linter class Migration(migrations.Migration): @@ -10,6 +11,7 @@ class Migration(migrations.Migration): ] operations = [ + linter.IgnoreMigration(), migrations.AddField( model_name='organization', name='is_grafana_incident_enabled', diff --git a/engine/requirements.txt b/engine/requirements.txt index d5fcce43..08e382f5 100644 --- a/engine/requirements.txt +++ b/engine/requirements.txt @@ -41,6 +41,7 @@ psycopg2==2.9.3 emoji==1.7.0 regex==2021.11.2 psutil==5.9.4 +django-migration-linter==4.1.0 opentelemetry-instrumentation-celery==0.36b0 opentelemetry-instrumentation-pymysql==0.36b0 opentelemetry-instrumentation-wsgi==0.36b0 diff --git a/engine/settings/base.py b/engine/settings/base.py index 3e7bf3a3..39c2ad3d 100644 --- a/engine/settings/base.py +++ b/engine/settings/base.py @@ -219,6 +219,7 @@ INSTALLED_APPS = [ "debug_toolbar", "social_django", "polymorphic", + "django_migration_linter", "fcm_django", "django_dbconn_retry", ] @@ -654,6 +655,10 @@ if OSS_INSTALLATION: "args": (), } # noqa +MIGRATION_LINTER_OPTIONS = {"exclude_apps": ["social_django", "silk", "fcm_django"]} +# Run migrations linter on each `python manage.py makemigrations` +MIGRATION_LINTER_OVERRIDE_MAKEMIGRATIONS = True + PYROSCOPE_PROFILER_ENABLED = getenv_boolean("PYROSCOPE_PROFILER_ENABLED", default=False) if PYROSCOPE_PROFILER_ENABLED: import pyroscope