feat: add sanitized internal main deployment
Some checks failed
State Corp Backend CI/CD / Quality gate (push) Successful in 5m25s
State Corp Backend CI/CD / Build linux/amd64 images once (push) Successful in 2m44s
State Corp Backend CI/CD / Release dev (push) Failing after 8s
State Corp Backend CI/CD / Refresh and release internal main (push) Has been skipped
State Corp Backend CI/CD / Release customer main (push) Has been skipped

This commit is contained in:
2026-08-27 12:49:43 +03:00
parent 46d0971320
commit 9194ff3d0d
8 changed files with 742 additions and 347 deletions

View File

@@ -0,0 +1,61 @@
from __future__ import annotations
import json
from apps.core.management.commands.base import BaseAppCommand
from apps.core.models import (
BackgroundJob,
JobStatus,
ReportUpload,
ReportUploadStatus,
)
from django.utils import timezone
from django_celery_beat.models import PeriodicTask, PeriodicTasks
CLONED_JOB_MESSAGE = "Задача остановлена при подготовке клонированного окружения"
CLONED_UPLOAD_MESSAGE = "Обработка остановлена при подготовке клонированного окружения"
class Command(BaseAppCommand):
help = (
"Disable Celery Beat schedules and close in-flight job records after "
"cloning an environment."
)
use_transaction = True
def execute_command(self, *args, **options) -> str:
completed_at = timezone.now()
disabled_periodic_tasks = PeriodicTask.objects.filter(enabled=True).update(
enabled=False
)
if disabled_periodic_tasks:
PeriodicTasks.update_changed()
revoked_background_jobs = BackgroundJob.objects.filter(
status__in=(JobStatus.PENDING, JobStatus.STARTED, JobStatus.RETRY)
).update(
status=JobStatus.REVOKED,
completed_at=completed_at,
progress_message=CLONED_JOB_MESSAGE,
)
failed_report_uploads = ReportUpload.objects.filter(
status__in=(ReportUploadStatus.QUEUED, ReportUploadStatus.PROCESSING)
).update(
status=ReportUploadStatus.FAILED,
status_message=CLONED_UPLOAD_MESSAGE,
completed_at=completed_at,
)
result = json.dumps(
{
"disabled_periodic_tasks": disabled_periodic_tasks,
"failed_report_uploads": failed_report_uploads,
"revoked_background_jobs": revoked_background_jobs,
},
ensure_ascii=False,
sort_keys=True,
)
self.log_info(result)
return result

View File

@@ -0,0 +1,46 @@
from __future__ import annotations
import json
from apps.core.management.commands.base import BaseAppCommand
from django.core.management.base import CommandError
from django.db import connection
from django.db.migrations.loader import MigrationLoader
from django.db.migrations.recorder import MigrationRecorder
class Command(BaseAppCommand):
help = (
"Reject a cloned database when it records an applied migration that is "
"absent from the current image."
)
requires_migrations_checks = False
requires_system_checks: list[str] = []
def execute_command(self, *args, **options) -> str:
applied_migrations = set(MigrationRecorder(connection).applied_migrations())
disk_migrations = set(
MigrationLoader(connection, ignore_no_migrations=True).disk_migrations
)
unknown_migrations = sorted(applied_migrations - disk_migrations)
if unknown_migrations:
formatted = ", ".join(
f"{app_label}.{migration_name}"
for app_label, migration_name in unknown_migrations
)
raise CommandError(
"Cloned database contains applied migrations absent from this "
f"image: {formatted}"
)
result = json.dumps(
{
"applied_migrations": len(applied_migrations),
"disk_migrations": len(disk_migrations),
"unknown_applied_migrations": 0,
},
sort_keys=True,
)
self.log_info(result)
return result