MT#33006 repoapi: support mantis

* tracker app, move everything related to WF or Mantis there
* move settings to tracker:
  - REPOAPI_TRACKER -> TRACKER_PROVIDER
  - MANTIS_* -> TRACKER_MANTIS_*
  - WORKFRONT_* -> TRACKER_WORKFRONT_*

Change-Id: If3eba4e86ec90d6cb4259104d0f474e936f70d43
pull/9/head
Victor Seva 3 years ago
parent 70d70da8c9
commit 16aadc64a1

@ -9,3 +9,4 @@ repoapi usr/share/repoapi
repoapi.ini etc/uwsgi/apps-available
requirements usr/share/repoapi
static_media usr/share/repoapi
tracker usr/share/repoapi

@ -15,15 +15,8 @@
from django.conf import settings # noqa
from appconf import AppConf
from repoapi.conf import Tracker
class HotfixConf(AppConf):
REGEX = {
Tracker.NONE: r"#(\d+)",
Tracker.WORKFRONT: r"TT#(\d+)",
Tracker.MANTIS: r"MT#(\d+)",
}
ARTIFACT = "debian_changelog.txt"
class Meta:

@ -15,19 +15,20 @@
import re
from django.db import models
from natsort import humansorted
from .conf import settings
from .conf import Tracker
from .exceptions import TrackerNotDefined
from tracker.conf import Tracker
from tracker.exceptions import TrackerNotDefined
from tracker.models import MantisInfo
from tracker.models import TrackerInfo
from tracker.models import WorkfrontInfo
hotfix_re_release = re.compile(r".+~(mr[0-9]+\.[0-9]+\.[0-9]+.[0-9]+)$")
class NoteInfo(models.Model):
class NoteInfo(TrackerInfo):
projectname = models.CharField(max_length=50, null=False)
version = models.CharField(max_length=50, null=False)
tracker_re = re.compile(settings.HOTFIX_REGEX[Tracker.NONE])
class Meta:
abstract = True
@ -44,9 +45,9 @@ class NoteInfo(models.Model):
@staticmethod
def get_model():
if settings.REPOAPI_TRACKER == Tracker.MANTIS:
if settings.TRACKER_PROVIDER == Tracker.MANTIS:
return MantisNoteInfo
elif settings.REPOAPI_TRACKER == Tracker.WORKFRONT:
elif settings.TRACKER_PROVIDER == Tracker.WORKFRONT:
return WorkfrontNoteInfo
return NoteInfo
@ -68,73 +69,32 @@ class NoteInfo(models.Model):
@classmethod
def get_or_create(cls, defaults=None, **kwargs):
field_id = kwargs.pop("field_id")
if settings.REPOAPI_TRACKER == Tracker.MANTIS:
if settings.TRACKER_PROVIDER == Tracker.MANTIS:
model = MantisNoteInfo
kwargs["mantis_id"] = field_id
elif settings.REPOAPI_TRACKER == Tracker.WORKFRONT:
elif settings.TRACKER_PROVIDER == Tracker.WORKFRONT:
model = WorkfrontNoteInfo
kwargs["workfront_id"] = field_id
else:
raise TrackerNotDefined()
return model.objects.get_or_create(defaults, **kwargs)
@classmethod
def getIds(cls, change):
"""
parses text searching for tracker occurrences
returns a list of IDs
"""
if change:
res = cls.tracker_re.findall(change)
return set(res)
else:
return set()
class WorkfrontNoteInfo(NoteInfo):
workfront_id = models.CharField(max_length=50, null=False)
tracker_re = re.compile(settings.HOTFIX_REGEX[Tracker.WORKFRONT])
class WorkfrontNoteInfo(NoteInfo, WorkfrontInfo):
class Meta:
unique_together = ["workfront_id", "projectname", "version"]
def send(self, msg: str):
from repoapi import utils
utils.workfront_note_send(self.workfront_id, msg)
def set_target_release(self):
from repoapi import utils
utils.workfront_set_release_target(
self.workfront_id, self.target_release
return super(WorkfrontNoteInfo, self).set_target_release(
self.target_release
)
class MantisNoteInfo(NoteInfo):
mantis_id = models.CharField(max_length=50, null=False)
tracker_re = re.compile(settings.HOTFIX_REGEX[Tracker.MANTIS])
class MantisNoteInfo(NoteInfo, MantisInfo):
class Meta:
unique_together = ["mantis_id", "projectname", "version"]
def send(self, msg: str):
from repoapi import utils
utils.mantis_note_send(self.mantis_id, msg)
def set_target_release(self):
"""reconstruct value without asking for previous value"""
from repoapi import utils
qs = MantisNoteInfo.objects.filter(mantis_id=self.mantis_id)
values = qs.values_list("version", flat=True)
versions = set()
for val in values:
target_release = self.get_target_release(val)
if target_release:
versions.add(target_release)
if len(versions) > 0:
utils.mantis_set_release_target(
self.mantis_id, ",".join(humansorted(versions))
)
return super(MantisNoteInfo, self).set_target_release(
self.target_release
)

@ -20,9 +20,9 @@ from django.test import override_settings
from hotfix import models
from hotfix import utils
from hotfix.conf import Tracker
from repoapi.models import JenkinsBuildInfo
from repoapi.test.base import BaseTest
from tracker.conf import Tracker
debian_changelog = """ngcp-fake (3.8.7.4+0~mr3.8.7.4) unstable; urgency=medium
@ -57,11 +57,11 @@ class TestHotfixReleased(BaseTest):
}
return defaults
@override_settings(REPOAPI_TRACKER=Tracker.WORKFRONT)
@override_settings(TRACKER_PROVIDER=Tracker.WORKFRONT)
@patch("builtins.open", mock_open(read_data=debian_changelog))
@patch("repoapi.utils.dlfile")
@patch("repoapi.utils.workfront_set_release_target")
@patch("repoapi.utils.workfront_note_send")
@patch("tracker.utils.workfront_set_release_target")
@patch("tracker.utils.workfront_note_send")
def test_hotfixreleased_wf(self, wns, wsrt, dlfile):
param = self.get_defaults()
jbi = JenkinsBuildInfo.objects.create(**param)
@ -92,11 +92,11 @@ class TestHotfixReleased(BaseTest):
any_order=True,
)
@override_settings(REPOAPI_TRACKER=Tracker.MANTIS)
@override_settings(TRACKER_PROVIDER=Tracker.MANTIS)
@patch("builtins.open", mock_open(read_data=debian_changelog))
@patch("repoapi.utils.dlfile")
@patch("repoapi.utils.mantis_set_release_target")
@patch("repoapi.utils.mantis_note_send")
@patch("tracker.utils.mantis_set_release_target")
@patch("tracker.utils.mantis_note_send")
def test_hotfixreleased_mantis(self, mns, msrt, dlfile):
param = self.get_defaults()
jbi = JenkinsBuildInfo.objects.create(**param)
@ -127,25 +127,21 @@ class TestHotfixReleased(BaseTest):
any_order=True,
)
@override_settings(REPOAPI_TRACKER=Tracker.MANTIS)
@override_settings(TRACKER_PROVIDER=Tracker.MANTIS)
@patch("builtins.open", mock_open(read_data=debian_changelog))
@patch("repoapi.utils.dlfile")
@patch("repoapi.utils.mantis_set_release_target")
@patch("repoapi.utils.mantis_note_send")
@patch("tracker.utils.mantis_set_release_target")
@patch("tracker.utils.mantis_note_send")
def test_hotfixreleased_mantis_versions(self, mns, msrt, dlfile):
param = self.get_defaults()
jbi = JenkinsBuildInfo.objects.create(**param)
projectname = "fake"
version = "3.8.7.4+0~mr3.8.7.4"
other_version = "5.8.7.4+0~mr5.8.7.4"
gri = models.MantisNoteInfo.objects.create(
mantis_id="8989", projectname=projectname, version=other_version
)
utils.process_hotfix(str(jbi), jbi.projectname, "/tmp/fake.txt")
gri = models.MantisNoteInfo.objects.filter(
mantis_id="8989", projectname=projectname
)
self.assertEqual(gri.count(), 2)
self.assertEqual(gri.count(), 1)
msg = "hotfix %s.git %s triggered" % (projectname, version)
calls = [
call("8989", msg),
@ -159,7 +155,7 @@ class TestHotfixReleased(BaseTest):
mns.assert_has_calls(calls, any_order=True)
msrt.assert_has_calls(
[
call("8989", "mr3.8.7.4,mr5.8.7.4"),
call("8989", "mr3.8.7.4"),
call("21499", "mr3.8.7.4"),
],
any_order=True,

@ -20,7 +20,7 @@ from django.test import SimpleTestCase
from natsort import humansorted
from hotfix import utils
from hotfix.conf import Tracker
from tracker.conf import Tracker
debian_changelog = """ngcp-fake (3.8.7.4+0~mr3.8.7.4) unstable; urgency=medium
[ Kirill Solomko ]
@ -34,7 +34,7 @@ debian_changelog = """ngcp-fake (3.8.7.4+0~mr3.8.7.4) unstable; urgency=medium
class TestUtils(SimpleTestCase):
@override_settings(REPOAPI_TRACKER=Tracker.NONE)
@override_settings(TRACKER_PROVIDER=Tracker.NONE)
@patch("builtins.open", mock_open(read_data=debian_changelog))
def test_parse_changelog_none(self):
ids, changelog = utils.parse_changelog("/tmp/fake.txt")
@ -42,7 +42,7 @@ class TestUtils(SimpleTestCase):
self.assertEqual(changelog.full_version, "3.8.7.4+0~mr3.8.7.4")
self.assertEqual(changelog.package, "ngcp-fake")
@override_settings(REPOAPI_TRACKER=Tracker.WORKFRONT)
@override_settings(TRACKER_PROVIDER=Tracker.WORKFRONT)
@patch("builtins.open", mock_open(read_data=debian_changelog))
def test_parse_changelog_wf(self):
ids, changelog = utils.parse_changelog("/tmp/fake.txt")
@ -50,7 +50,7 @@ class TestUtils(SimpleTestCase):
self.assertEqual(changelog.full_version, "3.8.7.4+0~mr3.8.7.4")
self.assertEqual(changelog.package, "ngcp-fake")
@override_settings(REPOAPI_TRACKER=Tracker.MANTIS)
@override_settings(TRACKER_PROVIDER=Tracker.MANTIS)
@patch("builtins.open", mock_open(read_data=debian_changelog))
def test_parse_changelog_mantis(self):
ids, changelog = utils.parse_changelog("/tmp/fake.txt")

@ -38,3 +38,23 @@ class JenkinsBuildInfoAdmin(ImportExportModelAdmin):
@admin.register(models.GerritRepoInfo)
class GerritRepoInfoAdmin(ImportExportModelAdmin):
resource_class = GerritRepoInfoResource
class WorkfrontNoteInfoResource(resources.ModelResource):
class Meta:
model = models.WorkfrontNoteInfo
@admin.register(models.WorkfrontNoteInfo)
class WorkfrontNoteInfoAdmin(ImportExportModelAdmin):
resource_class = WorkfrontNoteInfoResource
class MantisNoteInfoResource(resources.ModelResource):
class Meta:
model = models.MantisNoteInfo
@admin.register(models.MantisNoteInfo)
class MantisNoteInfoAdmin(ImportExportModelAdmin):
resource_class = MantisNoteInfoResource

@ -20,14 +20,13 @@ class RepoAPIConfig(AppConfig):
name = "repoapi"
def ready(self):
from .conf import settings, Tracker
from .conf import settings # noqa
# Implicitly connect a signal handlers decorated with @receiver.
from . import signals
if settings.REPOAPI_TRACKER == Tracker.WORKFRONT:
post_save.connect(
signals.workfront_note_manage,
sender="repoapi.JenkinsBuildInfo",
dispatch_uid="workfront_note_manage",
)
post_save.connect(
signals.note_manager,
sender="repoapi.JenkinsBuildInfo",
dispatch_uid="tracker_note_manager",
)

@ -12,23 +12,14 @@
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
from enum import Enum, unique
from django.conf import settings # noqa
from appconf import AppConf
@unique
class Tracker(Enum):
NONE = "None"
MANTIS = "Mantis"
WORKFRONT = "WorkFront"
class RepoAPIConf(AppConf):
ARTIFACT_JOB_REGEX = [
".*-repos$",
]
TRACKER = Tracker.MANTIS
class Meta:
prefix = "repoapi"

@ -0,0 +1,85 @@
{'note': {'id': 406459, 'reporter': {'id': 281, 'name': 'vseva', 'real_name': 'Victor Seva (Sipwise)', 'email': 'vseva@sipwise.com'
}, 'text': 'hotfix fake_project.git fake_version triggered', 'view_state': {'id': 50, 'name': 'private', 'label': 'private'
}, 'attachments': [], 'type': 'note', 'created_at': '2022-09-13T12: 10: 22+02: 00', 'updated_at': '2022-09-13T12: 10: 22+02: 00'
}, 'issue': {'id': 13503, 'summary': 'Test custom support queue flag', 'description': 'is_support_queue should be true', 'project': {'id': 3, 'name': 'test project'
}, 'category': {'id': 1, 'name': 'None'
}, 'reporter': {'id': 125, 'name': 'gfuchs', 'real_name': 'Gernot Fuchs'
}, 'handler': {'id': 125, 'name': 'gfuchs', 'real_name': 'Gernot Fuchs'
}, 'status': {'id': 80, 'name': 'resolved', 'label': 'resolved', 'color': '#d2f5b0'
}, 'resolution': {'id': 20, 'name': 'fixed', 'label': 'fixed'
}, 'view_state': {'id': 10, 'name': 'public', 'label': 'public'
}, 'priority': {'id': 30, 'name': 'P3-normal', 'label': 'P3-normal'
}, 'severity': {'id': 50, 'name': 'minor', 'label': 'minor'
}, 'reproducibility': {'id': 70, 'name': 'have not tried', 'label': 'have not tried'
}, 'sticky': False, 'created_at': '2015-06-19T11: 01: 42+02: 00', 'updated_at': '2022-09-13T12: 10: 22+02: 00', 'notes': [
{'id': 406459, 'reporter': {'id': 281, 'name': 'vseva', 'real_name': 'Victor Seva (Sipwise)', 'email': 'vseva@sipwise.com'
}, 'text': 'hotfix fake_project.git fake_version triggered', 'view_state': {'id': 50, 'name': 'private', 'label': 'private'
}, 'attachments': [], 'type': 'note', 'created_at': '2022-09-13T12: 10: 22+02: 00', 'updated_at': '2022-09-13T12: 10: 22+02: 00'
}
], 'custom_fields': [
{'field': {'id': 11, 'name': 'Classification'
}, 'value': ''
},
{'field': {'id': 23, 'name': 'Dev Related Tickets'
}, 'value': ''
},
{'field': {'id': 7, 'name': 'Log Time'
}, 'value': '0.5'
},
{'field': {'id': 24, 'name': 'NGCP Version'
}, 'value': ''
},
{'field': {'id': 38, 'name': 'Product Version'
}, 'value': ''
},
{'field': {'id': 52, 'name': 'Status Details'
}, 'value': ''
}
], 'monitors': [
{'id': 125, 'name': 'gfuchs', 'real_name': 'Gernot Fuchs'
}
], 'history': [
{'created_at': '2015-06-19T11: 01: 42+02: 00', 'user': {'id': 125, 'name': 'gfuchs', 'real_name': 'Gernot Fuchs'
}, 'type': {'id': 1, 'name': 'issue-new'
}, 'message': 'New Issue'
},
{'created_at': '2015-06-19T11: 01: 42+02: 00', 'user': {'id': 125, 'name': 'gfuchs', 'real_name': 'Gernot Fuchs'
}, 'type': {'id': 12, 'name': 'monitor-added'
}, 'old_value': '125', 'new_value': '', 'message': 'Issue Monitored: Gernot Fuchs'
},
{'created_at': '2015-06-19T11: 05: 01+02: 00', 'user': {'id': 125, 'name': 'gfuchs', 'real_name': 'Gernot Fuchs'
}, 'field': {'name': 'handler', 'label': 'Assigned To'
}, 'type': {'id': 0, 'name': 'field-updated'
}, 'old_value': {'id': 0
}, 'new_value': {'id': 125, 'name': 'gfuchs', 'real_name': 'Gernot Fuchs'
}, 'message': 'Assigned To', 'change': ' => Gernot Fuchs'
},
{'created_at': '2015-06-19T11: 05: 01+02: 00', 'user': {'id': 125, 'name': 'gfuchs', 'real_name': 'Gernot Fuchs'
}, 'field': {'name': 'status', 'label': 'Status'
}, 'type': {'id': 0, 'name': 'field-updated'
}, 'old_value': {'id': 10, 'name': 'new', 'label': 'new', 'color': '#fcbdbd'
}, 'new_value': {'id': 50, 'name': 'assigned', 'label': 'assigned', 'color': '#c2dfff'
}, 'message': 'Status', 'change': 'new => assigned'
},
{'created_at': '2015-06-19T11: 05: 09+02: 00', 'user': {'id': 125, 'name': 'gfuchs', 'real_name': 'Gernot Fuchs'
}, 'field': {'name': 'status', 'label': 'Status'
}, 'type': {'id': 0, 'name': 'field-updated'
}, 'old_value': {'id': 50, 'name': 'assigned', 'label': 'assigned', 'color': '#c2dfff'
}, 'new_value': {'id': 80, 'name': 'resolved', 'label': 'resolved', 'color': '#d2f5b0'
}, 'message': 'Status', 'change': 'assigned => resolved'
},
{'created_at': '2015-06-19T11: 05: 09+02: 00', 'user': {'id': 125, 'name': 'gfuchs', 'real_name': 'Gernot Fuchs'
}, 'field': {'name': 'resolution', 'label': 'Resolution'
}, 'type': {'id': 0, 'name': 'field-updated'
}, 'old_value': {'id': 10, 'name': 'open', 'label': 'open'
}, 'new_value': {'id': 20, 'name': 'fixed', 'label': 'fixed'
}, 'message': 'Resolution', 'change': 'open => fixed'
},
{'created_at': '2022-09-13T12: 10: 22+02: 00', 'user': {'id': 281, 'name': 'vseva', 'real_name': 'Victor Seva (Sipwise)'
}, 'type': {'id': 2, 'name': 'note-added'
}, 'note': {'id': 406459
}, 'message': 'Note Added: 0406459'
}
]
}
}

@ -0,0 +1,35 @@
# Generated by Django 3.2.15 on 2022-09-13 17:33
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("repoapi", "0012_ldap_grp_perms"),
]
operations = [
migrations.CreateModel(
name="MantisNoteInfo",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("mantis_id", models.CharField(max_length=50)),
("gerrit_change", models.CharField(max_length=50)),
("eventtype", models.CharField(max_length=50)),
],
options={
"unique_together": {
("mantis_id", "gerrit_change", "eventtype")
},
},
),
]

@ -14,4 +14,5 @@
# with this program. If not, see <http://www.gnu.org/licenses/>.
from .gri import GerritRepoInfo # noqa
from .jbi import JenkinsBuildInfo # noqa
from .wni import MantisNoteInfo # noqa
from .wni import WorkfrontNoteInfo # noqa

@ -1,4 +1,4 @@
# Copyright (C) 2015-2020 The Sipwise Team - http://sipwise.com
# Copyright (C) 2015-2022 The Sipwise Team - http://sipwise.com
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
@ -16,30 +16,44 @@ import re
from django.db import models
workfront_re = re.compile(r"TT#(\d+)")
workfront_re_branch = re.compile(r"^mr[0-9]+\.[0-9]+\.[0-9]+$")
from repoapi.conf import settings
from tracker.conf import Tracker
from tracker.exceptions import TrackerNotDefined
from tracker.models import MantisInfo
from tracker.models import TrackerInfo
from tracker.models import WorkfrontInfo
re_branch = re.compile(r"^mr[0-9]+\.[0-9]+\.[0-9]+$")
commit_re = re.compile(r"^(\w{7}) ")
class WorkfrontNoteInfo(models.Model):
workfront_id = models.CharField(max_length=50, null=False)
class NoteInfo(TrackerInfo):
gerrit_change = models.CharField(max_length=50, null=False)
eventtype = models.CharField(max_length=50, null=False)
class Meta:
unique_together = ["workfront_id", "gerrit_change", "eventtype"]
abstract = True
@staticmethod
def getIds(git_comment):
"""
parses git_commit_msg searching for Workfront TT# occurrences
returns a list of IDs
"""
if git_comment:
res = workfront_re.findall(git_comment)
return set(res)
def get_model():
if settings.TRACKER_PROVIDER == Tracker.MANTIS:
return MantisNoteInfo
elif settings.TRACKER_PROVIDER == Tracker.WORKFRONT:
return WorkfrontNoteInfo
return NoteInfo
@classmethod
def get_or_create(cls, defaults=None, **kwargs):
field_id = kwargs.pop("field_id")
if settings.TRACKER_PROVIDER == Tracker.MANTIS:
model = MantisNoteInfo
kwargs["mantis_id"] = field_id
elif settings.TRACKER_PROVIDER == Tracker.WORKFRONT:
model = WorkfrontNoteInfo
kwargs["workfront_id"] = field_id
else:
return set()
raise TrackerNotDefined()
return model.objects.get_or_create(defaults, **kwargs)
@staticmethod
def getCommit(git_comment):
@ -52,4 +66,14 @@ class WorkfrontNoteInfo(models.Model):
return res.group(1)
def __str__(self):
return "%s:%s" % (self.workfront_id, self.gerrit_change)
return "%s:%s" % (self.field_id, self.gerrit_change)
class WorkfrontNoteInfo(NoteInfo, WorkfrontInfo):
class Meta:
unique_together = ["workfront_id", "gerrit_change", "eventtype"]
class MantisNoteInfo(NoteInfo, MantisInfo):
class Meta:
unique_together = ["mantis_id", "gerrit_change", "eventtype"]

@ -38,6 +38,7 @@ INSTALLED_APPS = [
"crispy_forms",
"jsonify",
"import_export",
"tracker",
"hotfix",
"panel",
"release_dashboard",
@ -177,11 +178,6 @@ structlog.configure(
)
JENKINS_TOKEN = "sipwise_jenkins_ci"
MANTIS_TOKEN = "fake_mantis_token"
MANTIS_TARGET_RELEASE = {
"id": 77,
"name": "Target Release",
}
CELERY_TASK_SERIALIZER = "json"
CELERY_RESULT_SERIALIZER = "json"

@ -69,9 +69,8 @@ GERRIT_URL = server_config.get("gerrit", "URL")
GERRIT_REST_HTTP_USER = server_config.get("gerrit", "HTTP_USER")
GERRIT_REST_HTTP_PASSWD = server_config.get("gerrit", "HTTP_PASSWD")
MANTIS_URL = server_config.get("mantis", "URL")
MANTIS_TOKEN = server_config.get("mantis", "TOKEN")
MANTIS_TARGET_RELEASE["id"] = 75 # noqa
TRACKER_MANTIS_URL = server_config.get("mantis", "URL")
TRACKER_MANTIS_TOKEN = server_config.get("mantis", "TOKEN")
DOCKER_REGISTRY_URL = server_config.get("server", "DOCKER_REGISTRY_URL")
AUTH_LDAP_SERVER_URI = server_config.get("server", "AUTH_LDAP_SERVER_URI")
@ -136,7 +135,7 @@ STATICFILES_STORAGE = (
"django.contrib.staticfiles.storage.ManifestStaticFilesStorage"
)
GITWEB_URL = "https://git.mgm.sipwise.com/gitweb/?p={}.git;a=commit;h={}"
WORKFRONT_CREDENTIALS = BASE_DIR / "/etc/jenkins_jobs/workfront.ini"
TRACKER_WORKFRONT_CREDENTIALS = BASE_DIR / "/etc/jenkins_jobs/workfront.ini"
# build app
BUILD_REPOS_SCRIPTS_CONFIG_DIR = Path(

@ -17,7 +17,7 @@ import os
from pathlib import Path
from .common import * # noqa
from repoapi.conf import Tracker
from tracker.conf import Tracker
# pylint: disable=W0401,W0614
@ -57,9 +57,8 @@ GERRIT_URL = "https://gerrit.local/{}"
GERRIT_REST_HTTP_USER = "jenkins"
GERRIT_REST_HTTP_PASSWD = "verysecrethttppasswd"
GITWEB_URL = "https://git.local/gitweb/?p={}.git;a=commit;h={}"
WORKFRONT_CREDENTIALS = BASE_DIR / ".workfront.ini"
TRACKER_WORKFRONT_CREDENTIALS = BASE_DIR / ".workfront.ini"
DOCKER_REGISTRY_URL = "https://localhost:5000/v2/{}"
MANTIS_URL = "https://support.local/api/rest/{}"
# fake info
DOCKER_REGISTRY = """
@ -112,4 +111,4 @@ REPOAPI_ARTIFACT_JOB_REGEX = []
JBI_ALLOWED_HOSTS = ["jenkins-dev.mgm.sipwise.com"]
# no tracker
REPOAPI_TRACKER = Tracker.NONE
TRACKER_PROVIDER = Tracker.NONE

@ -18,7 +18,8 @@ from django.db.models.signals import post_save
from django.dispatch import receiver
from . import utils
from .models.wni import workfront_re_branch
from .models.wni import NoteInfo
from .models.wni import re_branch
from .tasks import get_jbi_files
from .tasks import jenkins_remove_project
from release_dashboard.utils.build import is_ngcp_project
@ -126,48 +127,47 @@ def gerrit_repo_manage(sender, **kwargs):
gerrit_repo_del(instance)
def workfront_release_target(instance, wid):
def tracker_release_target(instance, note: NoteInfo):
if not is_ngcp_project(instance.projectname):
logger.info(
"%s not a NGCP project, skip release_target", instance.projectname
)
return
branch = instance.param_branch
if workfront_re_branch.search(branch):
if re_branch.search(branch):
release = branch
else:
release = utils.get_next_release(branch)
if release:
utils.workfront_set_release_target(wid, release)
note.set_target_release(release)
def workfront_note_add(instance, message, release_target=False):
WorkfrontNoteInfo = apps.get_model("repoapi", "WorkfrontNoteInfo")
wni = WorkfrontNoteInfo.objects
workfront_ids = WorkfrontNoteInfo.getIds(instance.git_commit_msg)
def tracker_note_add(instance, message, release_target=False):
model = NoteInfo.get_model()
ids = model.getIds(instance.git_commit_msg)
from django.conf import settings
for wid in workfront_ids:
for id in ids:
if not instance.gerrit_eventtype:
change = WorkfrontNoteInfo.getCommit(instance.git_commit_msg)
change = model.getCommit(instance.git_commit_msg)
url = settings.GITWEB_URL.format(instance.projectname, change)
eventtype = "git-commit"
else:
change = instance.gerrit_change
url = settings.GERRIT_URL.format(instance.gerrit_change)
eventtype = instance.gerrit_eventtype
note, created = wni.get_or_create(
workfront_id=wid, gerrit_change=change, eventtype=eventtype
note, created = NoteInfo.get_or_create(
field_id=id, gerrit_change=change, eventtype=eventtype
)
if created:
if not utils.workfront_note_send(wid, "%s %s " % (message, url)):
logger.error("remove related WorkfrontNoteInfo")
if not note.send(f"{message} {url} "):
logger.error("remove related NoteInfo")
note.delete()
if release_target:
workfront_release_target(instance, wid)
tracker_release_target(instance, note)
def workfront_note_manage(sender, **kwargs):
def note_manager(sender, **kwargs):
"""
<name>-get-code job is the first in the flow that has the proper
GIT_CHANGE_SUBJECT envVar set, so git_commit_msg is fine
@ -185,7 +185,7 @@ def workfront_note_manage(sender, **kwargs):
set_release_target = False
else:
msg = "%s.git[%s] commit created"
workfront_note_add(
tracker_note_add(
instance,
msg % (instance.projectname, instance.param_branch),
set_release_target,

@ -22,13 +22,13 @@ from django.apps import apps
from .celery import jbi_parse_hotfix
from .celery import process_result
from .conf import settings
from .conf import Tracker
from .utils import is_download_artifacts
from .utils import jenkins_get_artifact
from .utils import jenkins_get_build
from .utils import jenkins_get_console
from .utils import jenkins_get_env
from .utils import jenkins_remove_project_ppa
from tracker.conf import Tracker
logger = structlog.get_logger(__name__)
@ -60,7 +60,7 @@ def jbi_get_artifact(jbi_id, jobname, buildnumber, artifact_info):
)
path = jenkins_get_artifact(jobname, buildnumber, artifact_info)
if path.name == settings.HOTFIX_ARTIFACT:
if settings.REPOAPI_TRACKER == Tracker.NONE:
if settings.TRACKER_PROVIDER == Tracker.NONE:
log.info("no tracker defined, skip hotfix management")
return
jbi_parse_hotfix.delay(jbi_id, str(path))

@ -34,13 +34,13 @@ class BaseTest(TestCase):
cls.path = Path(settings.JBI_BASEDIR)
def setUp(self, *args, **kwargs):
def setUp(self):
RepoAPIConfig = apps.get_app_config("repoapi")
RepoAPIConfig.ready()
super(BaseTest, self).setUp()
self.path.mkdir(parents=True, exist_ok=True)
def tearDown(self, *args, **kwargs):
def tearDown(self):
if self.path.exists():
shutil.rmtree(self.path)

@ -0,0 +1,65 @@
# Copyright (C) 2015-2022 The Sipwise Team - http://sipwise.com
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
from django.test import override_settings
from repoapi.models.wni import MantisNoteInfo
from repoapi.models.wni import NoteInfo
from repoapi.models.wni import WorkfrontNoteInfo
from repoapi.test.base import BaseTest
from tracker.conf import Tracker
@override_settings(TRACKER_PROVIDER=Tracker.WORKFRONT)
class WorkfrontNoteTestCase(BaseTest):
def test_get_model(self):
self.assertIs(NoteInfo.get_model(), WorkfrontNoteInfo)
def test_getID(self):
res = WorkfrontNoteInfo.getIds("jojo TT#0891 whatever")
self.assertCountEqual(res, ["0891"])
def test_getID_multiple(self):
res = WorkfrontNoteInfo.getIds("jojo TT#0891 whatever TT#0001")
self.assertCountEqual(res, ["0891", "0001"])
def test_getID_multiple_duplicate(self):
res = WorkfrontNoteInfo.getIds("jojo TT#0891 whatever TT#0001 TT#0891")
self.assertCountEqual(res, ["0891", "0001"])
def test_getCommit(self):
res = WorkfrontNoteInfo.getCommit("1234567 TT#67676 whatever")
self.assertEqual(res, "1234567")
@override_settings(TRACKER_PROVIDER=Tracker.MANTIS)
class MantisNoteTestCase(BaseTest):
def test_get_model(self):
self.assertIs(NoteInfo.get_model(), MantisNoteInfo)
def test_getID(self):
res = MantisNoteInfo.getIds("jojo TT#0891 MT#123 whatever")
self.assertCountEqual(res, ["123"])
def test_getID_multiple(self):
res = MantisNoteInfo.getIds("jojo MT#0891 whatever MT#0001")
self.assertCountEqual(res, ["0891", "0001"])
def test_getID_multiple_duplicate(self):
res = MantisNoteInfo.getIds("jojo MT#0891 whatever MT#0001 MT#0891")
self.assertCountEqual(res, ["0891", "0001"])
def test_getCommit(self):
res = MantisNoteInfo.getCommit("1234567 TT#67676 MT#1234 whatever")
self.assertEqual(res, "1234567")

@ -17,30 +17,14 @@ from unittest.mock import patch
from django.conf import settings
from django.test import override_settings
from repoapi.conf import Tracker
from repoapi.models import JenkinsBuildInfo
from repoapi.models import WorkfrontNoteInfo
from repoapi.test.base import BaseTest
from tracker.conf import Tracker
@override_settings(REPOAPI_TRACKER=Tracker.WORKFRONT)
@override_settings(TRACKER_PROVIDER=Tracker.WORKFRONT)
class WorkfrontNoteTestCase(BaseTest):
def test_getID(self):
res = WorkfrontNoteInfo.getIds("jojo TT#0891 whatever")
self.assertCountEqual(res, ["0891"])
def test_getID_multiple(self):
res = WorkfrontNoteInfo.getIds("jojo TT#0891 whatever TT#0001")
self.assertCountEqual(res, ["0891", "0001"])
def test_getID_multiple_duplicate(self):
res = WorkfrontNoteInfo.getIds("jojo TT#0891 whatever TT#0001 TT#0891")
self.assertCountEqual(res, ["0891", "0001"])
def test_getCommit(self):
res = WorkfrontNoteInfo.getCommit("1234567 TT#67676 whatever")
self.assertEqual(res, "1234567")
def get_defaults(self):
defaults = {
"tag": "edc90cd9-37f3-4613-9748-ed05a32031c2",
@ -68,9 +52,9 @@ class WorkfrontNoteTestCase(BaseTest):
del defaults["gerrit_eventtype"]
return defaults
@patch("repoapi.utils.workfront_set_release_target")
@patch("tracker.utils.workfront_set_release_target")
@patch("repoapi.utils.get_next_release")
@patch("repoapi.utils.workfront_note_send")
@patch("tracker.utils.workfront_note_send")
def test_note_gerrit(self, wns, gnr, wsrt):
param = self.get_defaults()
JenkinsBuildInfo.objects.create(**param)
@ -97,9 +81,9 @@ class WorkfrontNoteTestCase(BaseTest):
gnr.assert_not_called()
wns.assert_called_once_with("0001", msg)
@patch("repoapi.utils.workfront_set_release_target")
@patch("tracker.utils.workfront_set_release_target")
@patch("repoapi.utils.get_next_release")
@patch("repoapi.utils.workfront_note_send")
@patch("tracker.utils.workfront_note_send")
def test_note_merge(self, wns, gnr, wsrt):
param = self.get_defaults()
JenkinsBuildInfo.objects.create(**param)
@ -157,9 +141,9 @@ class WorkfrontNoteTestCase(BaseTest):
gnr.assert_called_once_with("master")
wns.assert_called_with("0001", msg)
@patch("repoapi.utils.workfront_set_release_target")
@patch("tracker.utils.workfront_set_release_target")
@patch("repoapi.utils.get_next_release")
@patch("repoapi.utils.workfront_note_send")
@patch("tracker.utils.workfront_note_send")
def test_note_commit(self, wns, gnr, wsrt):
param = self.get_non_gerrit_defaults()
param["jobname"] = "kamailio-get-code"
@ -188,9 +172,9 @@ class WorkfrontNoteTestCase(BaseTest):
gnr.assert_called_once_with("master")
wns.assert_called_once_with("0001", msg)
@patch("repoapi.utils.workfront_set_release_target")
@patch("tracker.utils.workfront_set_release_target")
@patch("repoapi.utils.get_next_release")
@patch("repoapi.utils.workfront_note_send")
@patch("tracker.utils.workfront_note_send")
def test_note_commit_mrXX(self, wns, gnr, wsrt):
param = self.get_non_gerrit_defaults()
param["jobname"] = "kamailio-get-code"
@ -221,9 +205,9 @@ class WorkfrontNoteTestCase(BaseTest):
gnr.assert_called_once_with("mr5.5")
wns.assert_called_once_with("0001", msg)
@patch("repoapi.utils.workfront_set_release_target")
@patch("tracker.utils.workfront_set_release_target")
@patch("repoapi.utils.get_next_release")
@patch("repoapi.utils.workfront_note_send")
@patch("tracker.utils.workfront_note_send")
def test_note_commit_mrXXX(self, wns, gnr, wsrt):
param = self.get_non_gerrit_defaults()
param["jobname"] = "kamailio-get-code"
@ -252,9 +236,9 @@ class WorkfrontNoteTestCase(BaseTest):
gnr.assert_not_called()
wns.assert_called_once_with("0001", msg)
@patch("repoapi.utils.workfront_set_release_target")
@patch("tracker.utils.workfront_set_release_target")
@patch("repoapi.utils.get_next_release")
@patch("repoapi.utils.workfront_note_send")
@patch("tracker.utils.workfront_note_send")
def test_note_commit_next_distri(self, wns, gnr, wsrt):
param = self.get_non_gerrit_defaults()
param["jobname"] = "kamailio-get-code"
@ -286,9 +270,9 @@ class WorkfrontNoteTestCase(BaseTest):
wsrt.assert_not_called()
wns.assert_called_once_with("0001", msg)
@patch("repoapi.utils.workfront_set_release_target")
@patch("tracker.utils.workfront_set_release_target")
@patch("repoapi.utils.get_next_release")
@patch("repoapi.utils.workfront_note_send")
@patch("tracker.utils.workfront_note_send")
def test_note_commit_non_ngcp(self, wns, gnr, wsrt):
param = self.get_non_gerrit_defaults()
param["projectname"] = "fake"

@ -12,7 +12,6 @@
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
import json
import re
import subprocess
from pathlib import Path
@ -29,10 +28,6 @@ JBI_CONSOLE_URL = "{}/job/{}/{}/consoleText"
JBI_BUILD_URL = "{}/job/{}/{}/api/json"
JBI_ARTIFACT_URL = "{}/job/{}/{}/artifact/{}"
JBI_ENVVARS_URL = "{}/job/{}/{}/injectedEnvVars/api/json"
MANTIS_HEADERS = {
"Authorization": settings.MANTIS_TOKEN,
"Content-Type": "application/json",
}
def executeAndReturnOutput(command, env=None):
@ -171,22 +166,6 @@ def jenkins_get_artifact(jobname, buildnumber, artifact_info):
return _jenkins_get(url, base_path, artifact_info["fileName"])
def workfront_note_send(_id, message):
command = [
"/usr/bin/workfront-jenkins-update",
"--credfile=%s" % settings.WORKFRONT_CREDENTIALS,
"--taskid=%s" % _id,
'--message="%s"' % message,
]
res = executeAndReturnOutput(command)
if res[0] != 0:
logger.error(
"can't post workfront notes", stdout=res[1], stderr=res[2]
)
return False
return True
def get_next_release(branch):
command = ["/usr/bin/meta-release-helper", "--next-release", branch]
res = executeAndReturnOutput(command)
@ -209,20 +188,6 @@ def get_next_release(branch):
return None
def workfront_set_release_target(_id, release):
command = [
"/usr/bin/workfront-target-task",
"--credfile=%s" % settings.WORKFRONT_CREDENTIALS,
"--taskid=%s" % _id,
"--release=%s" % release,
]
res = executeAndReturnOutput(command)
if res[0] != 0:
logger.error("can't set release target", stdout=res[1], stderr=res[2])
return False
return True
def is_download_artifacts(jobname):
if jobname in settings.JBI_ARTIFACT_JOBS:
return True
@ -230,43 +195,3 @@ def is_download_artifacts(jobname):
if re.search(check, jobname) is not None:
return True
return False
def mantis_query(method, url, payload):
logger.bind(
method=method,
url=url,
payload=payload,
)
response = requests.request(
f"{method}", url, headers=MANTIS_HEADERS, data=payload
)
response.raise_for_status()
return response
def mantis_note_send(_id, message):
url = settings.MANTIS_URL.format(f"issues/{_id}/notes")
payload = json.dumps(
{"text": f"{message}", "view_state": {"name": "private"}}
)
mantis_query("POST", url, payload)
def mantis_set_release_target(_id, msg):
url = settings.MANTIS_URL.format(f"issues/{_id}")
cf = settings.MANTIS_TARGET_RELEASE
payload = json.dumps(
{
"custom_fields": [
{
"field": {
"id": cf["id"],
"name": cf["name"],
},
"value": f"{msg}",
},
]
}
)
mantis_query("PATCH", url, payload)

@ -0,0 +1,23 @@
# Copyright (C) 2022 The Sipwise Team - http://sipwise.com
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
from django.apps import AppConfig
class TrackerConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "tracker"
def ready(self):
from .conf import settings # noqa

@ -0,0 +1,46 @@
# Copyright (C) 2022 The Sipwise Team - http://sipwise.com
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
from enum import Enum, unique
from django.conf import settings # noqa
from appconf import AppConf
@unique
class Tracker(Enum):
NONE = "None"
MANTIS = "Mantis"
WORKFRONT = "WorkFront"
class TrackerConf(AppConf):
REGEX = {
Tracker.NONE: r"#(\d+)",
Tracker.WORKFRONT: r"TT#(\d+)",
Tracker.MANTIS: r"MT#(\d+)",
}
ARTIFACT_JOB_REGEX = [
".*-repos$",
]
WORKFRONT_CREDENTIALS = "fake.txt"
MANTIS_URL = "https://support.local/api/rest/{}"
MANTIS_TOKEN = "fake_mantis_token"
MANTIS_TARGET_RELEASE = {
"id": 75,
"name": "Target Release",
}
PROVIDER = Tracker.MANTIS
class Meta:
prefix = "tracker"

@ -22,3 +22,7 @@ class Error(Exception):
class TrackerNotDefined(Error):
pass
class IssueNotFound(Error):
pass

File diff suppressed because one or more lines are too long

@ -0,0 +1,76 @@
# Copyright (C) 2022 The Sipwise Team - http://sipwise.com
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
import re
from django.db import models
from . import utils
from .conf import Tracker
from .conf import TrackerConf
tracker_settings = TrackerConf()
class TrackerInfo(models.Model):
tracker_re = re.compile(tracker_settings.REGEX[Tracker.NONE])
class Meta:
abstract = True
@classmethod
def getIds(cls, change):
"""
parses text searching for tracker occurrences
returns a list of IDs
"""
if change:
res = cls.tracker_re.findall(change)
return set(res)
else:
return set()
@property
def field_id(self):
return getattr(self, self.field_id_name)
class WorkfrontInfo(TrackerInfo):
workfront_id = models.CharField(max_length=50, null=False)
tracker_re = re.compile(tracker_settings.REGEX[Tracker.WORKFRONT])
field_id_name = "workfront_id"
class Meta:
abstract = True
def send(self, msg: str):
return utils.workfront_note_send(self.workfront_id, msg)
def set_target_release(self, release):
return utils.workfront_set_release_target(self.workfront_id, release)
class MantisInfo(TrackerInfo):
mantis_id = models.CharField(max_length=50, null=False)
tracker_re = re.compile(tracker_settings.REGEX[Tracker.MANTIS])
field_id_name = "mantis_id"
class Meta:
abstract = True
def send(self, msg: str):
return utils.mantis_note_send(self.mantis_id, msg)
def set_target_release(self, release):
return utils.mantis_set_release_target(self.mantis_id, release)

@ -0,0 +1,86 @@
# Copyright (C) 2022 The Sipwise Team - http://sipwise.com
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
import json
from unittest.mock import patch
from django.conf import settings
from django.test import SimpleTestCase
from tracker import utils
from tracker.conf import TrackerConf
FIXTURES_PATH = settings.BASE_DIR.joinpath("tracker", "fixtures")
MANTIS_ISSUE_JSON = FIXTURES_PATH.joinpath("mantis_issue.json")
MANTIS_ISSUE_ID = 36018
tracker_settings = TrackerConf()
class FakeResponse(object):
def __init__(self, filepath):
self.filepath = filepath
def json(self):
with self.filepath.open() as f:
res = json.load(f)
return res
class TestFakeResponse(SimpleTestCase):
def test_json(self):
fake = FakeResponse(MANTIS_ISSUE_JSON)
res = fake.json()
self.assertTrue(len(res["issues"]), 1)
self.assertEqual(res["issues"][0]["id"], MANTIS_ISSUE_ID)
def set_target_release_value(issue, value):
cf = issue["custom_fields"]
for val in cf:
if val["field"]["id"] == tracker_settings.MANTIS_TARGET_RELEASE["id"]:
val["value"] = value
class TestUtils(SimpleTestCase):
@patch(
"tracker.utils.mantis_query",
return_value=FakeResponse(MANTIS_ISSUE_JSON),
)
def test_mantis_get_issue_ok(self, mq):
res = utils.mantis_get_issue(MANTIS_ISSUE_ID)
self.assertEqual(res["id"], MANTIS_ISSUE_ID)
mq.assert_called_once_with(
"GET", "https://support.local/api/rest/issues/36018"
)
def test_mantis_get_issue_id(self):
fake = FakeResponse(MANTIS_ISSUE_JSON)
res = utils.mantis_get_issue_id(fake.json(), MANTIS_ISSUE_ID)
self.assertEqual(res["id"], MANTIS_ISSUE_ID)
def test_mantis_get_target_releases(self):
fake = FakeResponse(MANTIS_ISSUE_JSON)
issue = utils.mantis_get_issue_id(fake.json(), MANTIS_ISSUE_ID)
set_target_release_value(issue, "mr10.1")
res = utils.mantis_get_target_releases(issue)
self.assertListEqual(res, ["mr10.1"])
set_target_release_value(issue, "mr10.1, mr8.5.1")
res = utils.mantis_get_target_releases(issue)
self.assertListEqual(res, ["mr8.5.1", "mr10.1"])
set_target_release_value(issue, "mr10.1, mr8.5.1,,")
res = utils.mantis_get_target_releases(issue)
self.assertListEqual(res, ["mr8.5.1", "mr10.1"])

@ -0,0 +1,131 @@
# Copyright (C) 2022 The Sipwise Team - http://sipwise.com
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
import json
import requests
import structlog
from natsort import humansorted
from .conf import TrackerConf
from .exceptions import IssueNotFound
from repoapi.utils import executeAndReturnOutput
tracker_settings = TrackerConf()
logger = structlog.get_logger(__name__)
MANTIS_HEADERS = {
"Authorization": tracker_settings.MANTIS_TOKEN,
"Content-Type": "application/json",
}
def workfront_note_send(_id, message):
command = [
"/usr/bin/workfront-jenkins-update",
"--credfile=%s" % tracker_settings.WORKFRONT_CREDENTIALS,
"--taskid=%s" % _id,
'--message="%s"' % message,
]
res = executeAndReturnOutput(command)
if res[0] != 0:
logger.error(
"can't post workfront notes", stdout=res[1], stderr=res[2]
)
return False
return True
def workfront_set_release_target(_id, release):
command = [
"/usr/bin/workfront-target-task",
"--credfile=%s" % tracker_settings.WORKFRONT_CREDENTIALS,
"--taskid=%s" % _id,
"--release=%s" % release,
]
res = executeAndReturnOutput(command)
if res[0] != 0:
logger.error("can't set release target", stdout=res[1], stderr=res[2])
return False
return True
def mantis_query(method, url, payload=None) -> requests.Response:
logger.bind(
method=method,
url=url,
payload=payload,
)
response = requests.request(
f"{method}", url, headers=MANTIS_HEADERS, data=payload
)
response.raise_for_status()
return response
def mantis_get_issue_id(res, _id: int):
for issue in res["issues"]:
if issue["id"] == _id:
return issue
def mantis_get_issue(_id: int):
url = tracker_settings.MANTIS_URL.format(f"issues/{_id}")
response = mantis_query("GET", url)
res = mantis_get_issue_id(response.json(), _id)
if res:
return res
raise IssueNotFound(f"{_id} Not found in response")
def mantis_note_send(_id: int, message: str) -> requests.Response:
url = tracker_settings.MANTIS_URL.format(f"issues/{_id}/notes")
payload = json.dumps(
{"text": f"{message}", "view_state": {"name": "private"}}
)
return mantis_query("POST", url, payload)
def mantis_get_target_releases(issue) -> list:
cf = issue["custom_fields"]
res = set()
for val in cf:
if val["field"]["id"] == tracker_settings.MANTIS_TARGET_RELEASE["id"]:
for word in val["value"].split(","):
word = word.strip()
if word:
res.add(word)
break
return humansorted(res)
def mantis_set_release_target(_id: int, release: str) -> requests.Response:
issue = mantis_get_issue(_id)
releases = mantis_get_target_releases(issue)
url = tracker_settings.MANTIS_URL.format(f"issues/{_id}")
cf = tracker_settings.MANTIS_TARGET_RELEASE
payload = json.dumps(
{
"custom_fields": [
{
"field": {
"id": cf["id"],
"name": cf["name"],
},
"value": f"{releases}",
},
]
}
)
return mantis_query("PATCH", url, payload)
Loading…
Cancel
Save