feat: implement CI/CD pipeline with Gitea Actions

- Add Gitea Actions workflow with 4 stages: lint, test, build, push
- Configure ruff linting and formatting checks
- Set up Django tests with PostgreSQL and Redis services
- Implement Docker image building for web and celery services
- Add requirements.txt and requirements-dev.txt generation
- Fix ipdb compatibility issues in test runner
- Update ruff configuration for Django compatibility
- Add comprehensive CI/CD documentation
This commit is contained in:
2026-01-19 14:24:48 +01:00
parent cbfbd8652d
commit 06b30fca02
26 changed files with 1769 additions and 726 deletions

View File

@@ -5,7 +5,7 @@ from django.utils.translation import gettext_lazy as _
class User(AbstractUser):
"""Расширенная модель пользователя"""
# Переопределяем группы и разрешения для избежания конфликта
groups = models.ManyToManyField(
"auth.Group",
@@ -23,37 +23,29 @@ class User(AbstractUser):
related_name="custom_user_set",
related_query_name="custom_user",
)
email = models.EmailField(
_("email address"),
unique=True,
help_text=_("Required. Must be unique.")
_("email address"), unique=True, help_text=_("Required. Must be unique.")
)
phone = models.CharField(
_("phone number"),
max_length=20,
blank=True,
null=True,
help_text=_("Phone number in international format")
help_text=_("Phone number in international format"),
)
is_verified = models.BooleanField(
_("email verified"),
default=False,
help_text=_("Designates whether the user has verified their email.")
)
created_at = models.DateTimeField(
_("created at"),
auto_now_add=True
)
updated_at = models.DateTimeField(
_("updated at"),
auto_now=True
help_text=_("Designates whether the user has verified their email."),
)
created_at = models.DateTimeField(_("created at"), auto_now_add=True)
updated_at = models.DateTimeField(_("updated at"), auto_now=True)
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["username"]
@@ -69,59 +61,33 @@ class User(AbstractUser):
class Profile(models.Model):
"""Профиль пользователя (OneToOne связь с User)"""
user = models.OneToOneField(
User,
on_delete=models.CASCADE,
related_name="profile",
verbose_name=_("user")
User, on_delete=models.CASCADE, related_name="profile", verbose_name=_("user")
)
first_name = models.CharField(
_("first name"),
max_length=50,
blank=True,
null=True
)
last_name = models.CharField(
_("last name"),
max_length=50,
blank=True,
null=True
)
first_name = models.CharField(_("first name"), max_length=50, blank=True, null=True)
last_name = models.CharField(_("last name"), max_length=50, blank=True, null=True)
bio = models.TextField(
_("bio"),
blank=True,
null=True,
help_text=_("Short biography or description")
_("bio"), blank=True, null=True, help_text=_("Short biography or description")
)
avatar = models.ImageField(
_("avatar"),
upload_to="avatars/",
blank=True,
null=True,
help_text=_("User avatar image")
)
date_of_birth = models.DateField(
_("date of birth"),
blank=True,
null=True
)
created_at = models.DateTimeField(
_("created at"),
auto_now_add=True
)
updated_at = models.DateTimeField(
_("updated at"),
auto_now=True
help_text=_("User avatar image"),
)
date_of_birth = models.DateField(_("date of birth"), blank=True, null=True)
created_at = models.DateTimeField(_("created at"), auto_now_add=True)
updated_at = models.DateTimeField(_("updated at"), auto_now=True)
class Meta:
db_table = "profiles"
verbose_name = _("profile")
@@ -140,4 +106,4 @@ class Profile(models.Model):
return self.first_name
elif self.last_name:
return self.last_name
return self.user.username
return self.user.username