diff --git a/apps/taskman/migrations/0001_initial.py b/apps/taskman/migrations/0001_initial.py new file mode 100644 index 000000000..fca952b2e --- /dev/null +++ b/apps/taskman/migrations/0001_initial.py @@ -0,0 +1,33 @@ +# Generated by Django 3.2.20 on 2023-10-24 15:22 + +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('osidb', '0100_fix_affectcvss'), + ] + + operations = [ + migrations.CreateModel( + name='Task', + fields=[ + ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('jira_key', models.CharField(max_length=60)), + ('jira_group_key', models.CharField(blank=True, max_length=60)), + ('team_id', models.CharField(blank=True, max_length=8)), + ('owner', models.CharField(blank=True, max_length=60)), + ('status', models.CharField(choices=[('New', 'New'), ('Refinement', 'Refinement'), ('To Do', 'To Do'), ('In Progress', 'In Progress'), ('Review', 'Review'), ('Closed', 'Closed')], default='New', max_length=11)), + ('resolution', models.CharField(blank=True, choices=[('', 'None'), ('Done', 'Done'), ("Won't Do", 'Wont Do'), ('Cannot Reproduce', 'Cannot Reproduce'), ("Can't Do", 'Cant Do'), ('Duplicate', 'Duplicate'), ('Not a Bug', 'Not A Bug'), ('Done-Errata', 'Done Errata'), ('MirrorOrphan', 'Mirror Orphan'), ('Obsolete', 'Obsolete'), ('Test Pending', 'Test Pending'), ('Fixed', 'Fixed'), ('Duplicate Ticket', 'Duplicate Ticket')], max_length=16)), + ('flaw', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='task', to='osidb.flaw')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/apps/taskman/migrations/__init__.py b/apps/taskman/migrations/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/apps/taskman/models.py b/apps/taskman/models.py new file mode 100644 index 000000000..b6b586c98 --- /dev/null +++ b/apps/taskman/models.py @@ -0,0 +1,74 @@ +import uuid + +from django.db import models + +from osidb.mixins import NullStrFieldsMixin +from osidb.models import Flaw + + +class JiraCustomFields(models.TextChoices): + EPIC_KEY = "customfield_12311140" + TEAM = "customfield_12313240" + + +class JiraStatus(models.TextChoices): + """ + list of allowable status for tasks in Jira + """ + + NEW = "New" + REFINEMENT = "Refinement" + TO_DO = "To Do" + IN_PROGRESS = "In Progress" + REVIEW = "Review" + CLOSED = "Closed" + + +class JiraResolution(models.TextChoices): + """ + list of allowable resolution for tasks in Jira + """ + + NONE = "" + DONE = "Done" + WONT_DO = "Won't Do" + CANNOT_REPRODUCE = "Cannot Reproduce" + CANT_DO = "Can't Do" + DUPLICATE = "Duplicate" + NOT_A_BUG = "Not a Bug" + DONE_ERRATA = "Done-Errata" + MIRROR_ORPHAN = "MirrorOrphan" + OBSOLETE = "Obsolete" + TEST_PENDING = "Test Pending" + FIXED = "Fixed" + DUPLICATE_TICKET = "Duplicate Ticket" + + +class Task(NullStrFieldsMixin): + """ + Data cached from Jira tasks + """ + + uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + jira_key = models.CharField(max_length=60) + jira_group_key = models.CharField(max_length=60, blank=True) + team_id = models.CharField(max_length=8, blank=True) + owner = models.CharField(max_length=60, blank=True) + status = models.CharField( + choices=JiraStatus.choices, max_length=11, default=JiraStatus.NEW + ) + resolution = models.CharField( + choices=JiraResolution.choices, max_length=16, blank=True + ) + flaw = models.OneToOneField(Flaw, on_delete=models.CASCADE, related_name="task") + + def update_in_memory(self, issue): + """Deserializes a jira issue into task model""" + fields = issue["fields"] + self.jira_key = issue["key"] + self.team_id = ( + fields[JiraCustomFields.TEAM]["id"] if fields[JiraCustomFields.TEAM] else "" + ) + self.owner = fields["assignee"]["name"] if fields["assignee"] else "" + self.status = fields["status"]["name"] + self.resolution = fields["resolution"]["name"] if fields["resolution"] else "" diff --git a/config/settings.py b/config/settings.py index 81bd5c1a6..d290ab417 100644 --- a/config/settings.py +++ b/config/settings.py @@ -60,6 +60,7 @@ "apps.bbsync", "apps.exploits", "apps.osim", + "apps.taskman", "apps.trackers", "collectors.bzimport", "collectors.errata",