From 9859d31ea712b075f8c56bb9306e4578c2197c56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Luiz=20Lorencetti?= Date: Sun, 22 Oct 2017 17:15:14 -0200 Subject: [PATCH] add a django command to notify opbeat about new release --- AUTHORS | 2 +- .../management/commands/make_release.py | 49 +++++++++++++++++++ tests/contrib/django/django_tests.py | 44 +++++++++++++++++ 3 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 opbeat/contrib/django/management/commands/make_release.py diff --git a/AUTHORS b/AUTHORS index 7a988787..73cd74e0 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,3 +1,3 @@ -http://github.com/dcramer/raven/contributors +https://github.com/opbeat/opbeat_python/graphs/contributors and Opbeat \ No newline at end of file diff --git a/opbeat/contrib/django/management/commands/make_release.py b/opbeat/contrib/django/management/commands/make_release.py new file mode 100644 index 00000000..707dfe84 --- /dev/null +++ b/opbeat/contrib/django/management/commands/make_release.py @@ -0,0 +1,49 @@ +from __future__ import absolute_import + +from django.core.management.base import BaseCommand + +import requests +import six + +from opbeat.contrib.django.models import client + +if six.PY2: + from commands import getoutput +else: + from subprocess import getoutput + + +OPBEAT_URL = 'https://intake.opbeat.com/api/v1/organizations/{org_id}/apps/{app_id}/releases/' + + +class Command(BaseCommand): + help = 'Notify Opbeat when a release has completed' + + @staticmethod + def opbeat_info(): + return { + 'org_id': client.organization_id, + 'app_id': client.app_id, + 'token': client.secret_token, + } + + @staticmethod + def build_data(): + revision = getoutput('git log -n 1 --pretty="format:%H"') + branch = getoutput('git rev-parse --abbrev-ref HEAD') + return { + 'branch': branch, + 'rev': revision, + 'status': 'completed', + } + + @staticmethod + def make_request(data, org_id, app_id, token): + headers = {'Authorization': 'Bearer {token}'.format(token=token)} + return requests.post(OPBEAT_URL.format(org_id=org_id, app_id=app_id), data=data, headers=headers) + + def handle(self, *args, **options): + response = self.make_request(self.build_data(), **self.opbeat_info()) + + if response.status_code == '202': + print('Release received') diff --git a/tests/contrib/django/django_tests.py b/tests/contrib/django/django_tests.py index b01e7bcb..983050ac 100644 --- a/tests/contrib/django/django_tests.py +++ b/tests/contrib/django/django_tests.py @@ -31,6 +31,7 @@ from opbeat.contrib.django import DjangoClient from opbeat.contrib.django.celery import CeleryClient from opbeat.contrib.django.handlers import OpbeatHandler +from opbeat.contrib.django.management.commands import make_release from opbeat.contrib.django.middleware.wsgi import Opbeat from opbeat.contrib.django.models import client, get_client, get_client_config from opbeat.traces import Transaction @@ -1302,3 +1303,46 @@ def test_test_exception(self, urlopen_mock): call_command('opbeat', 'test', stdout=stdout, stderr=stdout) output = stdout.getvalue() assert 'http://example.com' in output + + +class DjangoMakeReleaseManagementCommandTest(TestCase): + def setUp(self): + self.opbeat_info = { + 'org_id': 'org_id', + 'app_id': 'app_id', + 'token': 'token', + } + self.data = { + 'branch': 'branch', + 'rev': 'rev', + 'status': 'completed' + } + + def test_build_data(self): + with mock.patch('opbeat.contrib.django.management.commands.make_release.getoutput'): + data = make_release.Command.build_data() + + assert 'branch' in data + assert 'rev' in data + assert 'status' in data + + @mock.patch('opbeat.contrib.django.management.commands.make_release.client') + def test_opbeat_info(self, mock_client): + mock_client.organization_id = 'org_id' + mock_client.app_id = 'app_id' + mock_client.secret_token = 'token' + + info = make_release.Command.opbeat_info() + + assert info == self.opbeat_info + + @mock.patch('opbeat.contrib.django.management.commands.make_release.Command.build_data') + @mock.patch('opbeat.contrib.django.management.commands.make_release.Command.opbeat_info') + @mock.patch('opbeat.contrib.django.management.commands.make_release.Command.make_request') + def test_command(self, mock_request, mock_opbeat_info, mock_build_data): + mock_build_data.return_value = self.data + mock_opbeat_info.return_value = self.opbeat_info + + call_command('make_release') + + mock_request.assert_called_once_with(self.data, **self.opbeat_info)