mirror of https://github.com/zulip/zulip.git
Add codeship integration.
This commit is contained in:
parent
8c62a27769
commit
5fbda3a9c1
|
@ -9,7 +9,7 @@ All notable changes to this project will be documented in this file.
|
|||
- Added documentation on using Hubot to integrate with useful services
|
||||
not yet integrated with Zulip directly (e.g. Google Hangouts).
|
||||
- Added new management command to test sending email from Zulip.
|
||||
- Added Pingdom, Teamcity, and Yo integrations.
|
||||
- Added Codeship, Pingdom, Teamcity, and Yo integrations.
|
||||
- Refactored the Zulip puppet modules to be more modular.
|
||||
- Refactored the Tornado event system, fixing old memory leaks.
|
||||
- Implemented running queue processors multithreaded in development,
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
|
@ -78,6 +78,12 @@
|
|||
<span class="integration-label">Codebase</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="integration-lozenge integration-codeship">
|
||||
<a class="integration-link integration-codeship" href="#codeship">
|
||||
<img class="integration-logo" src="/static/images/integrations/logos/codeship.png" alt="Codeship logo" />
|
||||
<span class="integration-label">Codeship</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="integration-lozenge integration-deskcom">
|
||||
<a class="integration-link integration-deskcom" href="#deskcom">
|
||||
<img class="integration-logo" src="/static/images/integrations/logos/deskcom.png" alt="Desk.com logo" />
|
||||
|
@ -562,6 +568,35 @@
|
|||
<img class="screenshot" src="/static/images/integrations/codebase/001.png" />
|
||||
</div>
|
||||
|
||||
<div id="codeship" class="integration-instructions">
|
||||
|
||||
<p>Zulip supports integration with Codeship and can notify you of
|
||||
your build statuses.</p>
|
||||
|
||||
<p>First, create the stream you'd like to use for Codeship notifications,
|
||||
and subscribe all interested parties to this stream. We
|
||||
recommend the name <code>codeship</code>.</p>
|
||||
|
||||
<p><code>{{ external_api_uri }}/v1/external/codeship?api_key=abcdefgh&stream=codeship</code></p>
|
||||
|
||||
<p>where <code>api_key</code> is the API key of your Zulip bot,
|
||||
and <code>stream</code> is the stream name you want the
|
||||
notifications sent to.</p>
|
||||
|
||||
<p>Next, go to your project settings - notification settings
|
||||
page. The url should look like the following:</p>
|
||||
<p><code>https://codeship.com/projects/PROJECT_ID/configure_notifications</code></p>
|
||||
<p>where <code>PROJECT_ID</code> is the id of your project in Codeship.</p>
|
||||
<p>Scroll to the <code>Webhook</code> section and fill out the form as follows:</p>
|
||||
<img class="screenshot" src="/static/images/integrations/codeship/001.png" />
|
||||
|
||||
<p><b>Congratulations! You're done!</b><br /> When a build is
|
||||
triggered, you'll get a notification like this:</p>
|
||||
|
||||
<img class="screenshot" src="/static/images/integrations/codeship/002.png" />
|
||||
|
||||
</div>
|
||||
|
||||
<div id="deskcom" class="integration-instructions">
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"build": {
|
||||
"build_url":"https://www.codeship.com/projects/10213/builds/973711",
|
||||
"commit_url":"https://github.com/codeship/docs/commit/96943dc5269634c211b6fbb18896ecdcbd40a047",
|
||||
"project_id":10213,
|
||||
"build_id":973711,
|
||||
"status":"error",
|
||||
"project_full_name":"codeship/docs",
|
||||
"project_name":"codeship/docs",
|
||||
"commit_id":"96943dc5269634c211b6fbb18896ecdcbd40a047",
|
||||
"short_commit_id":"96943",
|
||||
"message":"Merge pull request #34 from codeship/feature/shallow-clone",
|
||||
"committer":"beanieboi",
|
||||
"branch":"master"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"build": {
|
||||
"build_url":"https://www.codeship.com/projects/10213/builds/973711",
|
||||
"commit_url":"https://github.com/codeship/docs/commit/96943dc5269634c211b6fbb18896ecdcbd40a047",
|
||||
"project_id":10213,
|
||||
"build_id":973711,
|
||||
"status":"some_other_status",
|
||||
"project_full_name":"codeship/docs",
|
||||
"project_name":"codeship/docs",
|
||||
"commit_id":"96943dc5269634c211b6fbb18896ecdcbd40a047",
|
||||
"short_commit_id":"96943",
|
||||
"message":"Merge pull request #34 from codeship/feature/shallow-clone",
|
||||
"committer":"beanieboi",
|
||||
"branch":"master"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"build": {
|
||||
"build_url":"https://www.codeship.com/projects/10213/builds/973711",
|
||||
"commit_url":"https://github.com/codeship/docs/commit/96943dc5269634c211b6fbb18896ecdcbd40a047",
|
||||
"project_id":10213,
|
||||
"build_id":973711,
|
||||
"status":"success",
|
||||
"project_full_name":"codeship/docs",
|
||||
"project_name":"codeship/docs",
|
||||
"commit_id":"96943dc5269634c211b6fbb18896ecdcbd40a047",
|
||||
"short_commit_id":"96943",
|
||||
"message":"Merge pull request #34 from codeship/feature/shallow-clone",
|
||||
"committer":"beanieboi",
|
||||
"branch":"master"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"build": {
|
||||
"build_url":"https://www.codeship.com/projects/10213/builds/973711",
|
||||
"commit_url":"https://github.com/codeship/docs/commit/96943dc5269634c211b6fbb18896ecdcbd40a047",
|
||||
"project_id":10213,
|
||||
"build_id":973711,
|
||||
"status":"testing",
|
||||
"project_full_name":"codeship/docs",
|
||||
"project_name":"codeship/docs",
|
||||
"commit_id":"96943dc5269634c211b6fbb18896ecdcbd40a047",
|
||||
"short_commit_id":"96943",
|
||||
"message":"Merge pull request #34 from codeship/feature/shallow-clone",
|
||||
"committer":"beanieboi",
|
||||
"branch":"master"
|
||||
}
|
||||
}
|
|
@ -1001,3 +1001,69 @@ class TeamcityHookTests(AuthedTestCase):
|
|||
self.assertEqual(msg.recipient.type, Recipient.PERSONAL)
|
||||
self.assertEqual(msg.content, u"Your personal build of Project :: Compile build 5535 - CL 123456 is broken with status Exit code 1 (new)! :thumbsdown:\nDetails: [changes](http://teamcity/viewLog.html?buildTypeId=Project_Compile&buildId=19952&tab=buildChangesDiv), [build log](http://teamcity/viewLog.html?buildTypeId=Project_Compile&buildId=19952)")
|
||||
|
||||
class CodeshipHookTests(AuthedTestCase):
|
||||
STREAM_NAME = 'codeship'
|
||||
TEST_USER_EMAIL = 'hamlet@zulip.com'
|
||||
URL_TEMPLATE = "/api/v1/external/codeship?stream={stream}&api_key={api_key}"
|
||||
|
||||
def setUp(self):
|
||||
api_key = self.get_api_key(self.TEST_USER_EMAIL)
|
||||
self._url = self.URL_TEMPLATE.format(stream=self.STREAM_NAME, api_key=api_key)
|
||||
self.subscribe_to_stream(self.TEST_USER_EMAIL, self.STREAM_NAME)
|
||||
|
||||
def test_codeship_build_in_testing_status_message(self):
|
||||
"""
|
||||
Tests if codeship testing status is mapped correctly
|
||||
"""
|
||||
body = self._get_fixture_data('testing_build')
|
||||
self._send_post_request_with_params(body)
|
||||
|
||||
expected_message = u"[Build](https://www.codeship.com/projects/10213/builds/973711) triggered by beanieboi on master branch started."
|
||||
msg = self._get_recently_added_message()
|
||||
self.assertEqual(msg.subject, u"codeship/docs")
|
||||
self.assertEqual(msg.content, expected_message)
|
||||
|
||||
def test_codeship_build_in_error_status_message(self):
|
||||
"""
|
||||
Tests if codeship error status is mapped correctly
|
||||
"""
|
||||
body = self._get_fixture_data('error_build')
|
||||
self._send_post_request_with_params(body)
|
||||
|
||||
expected_message = u"[Build](https://www.codeship.com/projects/10213/builds/973711) triggered by beanieboi on master branch failed."
|
||||
msg = self._get_recently_added_message()
|
||||
self.assertEqual(msg.subject, u"codeship/docs")
|
||||
self.assertEqual(msg.content, expected_message)
|
||||
|
||||
def test_codeship_build_in_success_status_message(self):
|
||||
"""
|
||||
Tests if codeship success status is mapped correctly
|
||||
"""
|
||||
body = self._get_fixture_data('success_build')
|
||||
self._send_post_request_with_params(body)
|
||||
|
||||
expected_message = u"[Build](https://www.codeship.com/projects/10213/builds/973711) triggered by beanieboi on master branch succeeded."
|
||||
msg = self._get_recently_added_message()
|
||||
self.assertEqual(msg.subject, u"codeship/docs")
|
||||
self.assertEqual(msg.content, expected_message)
|
||||
|
||||
def test_codeship_build_in_other_status_status_message(self):
|
||||
"""
|
||||
Tests if codeship other status is mapped correctly
|
||||
"""
|
||||
body = self._get_fixture_data('other_status_build')
|
||||
self._send_post_request_with_params(body)
|
||||
|
||||
expected_message = u"[Build](https://www.codeship.com/projects/10213/builds/973711) triggered by beanieboi on master branch has some_other_status status."
|
||||
msg = self._get_recently_added_message()
|
||||
self.assertEqual(msg.subject, u"codeship/docs")
|
||||
self.assertEqual(msg.content, expected_message)
|
||||
|
||||
def _get_recently_added_message(self):
|
||||
return Message.objects.filter().order_by('-id')[0]
|
||||
|
||||
def _get_fixture_data(self, name):
|
||||
return ujson.dumps(ujson.loads(self.fixture_data('codeship', name)))
|
||||
|
||||
def _send_post_request_with_params(self, json):
|
||||
return self.client.post(self._url, json, stream_name=self.STREAM_NAME, content_type="application/json")
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
# Webhooks for external integrations.
|
||||
from __future__ import absolute_import
|
||||
from zerver.models import get_client
|
||||
from zerver.lib.actions import check_send_message
|
||||
from zerver.lib.response import json_success, json_error
|
||||
from zerver.decorator import REQ, has_request_variables, api_key_only_webhook_view
|
||||
|
||||
import ujson
|
||||
|
||||
|
||||
CODESHIP_SUBJECT_TEMPLATE = '{project_name}'
|
||||
CODESHIP_MESSAGE_TEMPLATE = '[Build]({build_url}) triggered by {committer} on {branch} branch {status}.'
|
||||
|
||||
CODESHIP_DEFAULT_STATUS = 'has {status} status'
|
||||
CODESHIP_STATUS_MAPPER = {
|
||||
'testing': 'started',
|
||||
'error': 'failed',
|
||||
'success': 'succeeded',
|
||||
}
|
||||
|
||||
|
||||
@api_key_only_webhook_view
|
||||
@has_request_variables
|
||||
def api_codeship_webhook(request, user_profile, stream=REQ(default='codeship')):
|
||||
try:
|
||||
payload = ujson.loads(request.body)['build']
|
||||
subject = get_subject_for_http_request(payload)
|
||||
body = get_body_for_http_request(payload)
|
||||
except KeyError as e:
|
||||
return json_error("Missing key {} in JSON".format(e.message))
|
||||
except ValueError as e:
|
||||
return json_error("Malformed JSON")
|
||||
|
||||
check_send_message(user_profile, get_client('ZulipCodeshipWebhook'), 'stream', [stream], subject, body)
|
||||
return json_success()
|
||||
|
||||
|
||||
def get_subject_for_http_request(payload):
|
||||
return CODESHIP_SUBJECT_TEMPLATE.format(project_name=payload['project_name'])
|
||||
|
||||
|
||||
def get_body_for_http_request(payload):
|
||||
return CODESHIP_MESSAGE_TEMPLATE.format(
|
||||
build_url=payload['build_url'],
|
||||
committer=payload['committer'],
|
||||
branch=payload['branch'],
|
||||
status=get_status_message(payload)
|
||||
)
|
||||
|
||||
|
||||
def get_status_message(payload):
|
||||
build_status = payload['status']
|
||||
return CODESHIP_STATUS_MAPPER.get(build_status, CODESHIP_DEFAULT_STATUS.format(status=build_status))
|
|
@ -157,6 +157,7 @@ urlpatterns += patterns('zerver.views',
|
|||
url(r'^api/v1/external/teamcity$', 'webhooks.teamcity.api_teamcity_webhook'),
|
||||
url(r'^api/v1/external/pingdom$', 'webhooks.pingdom.api_pingdom_webhook'),
|
||||
url(r'^api/v1/external/yo$', 'webhooks.yo.api_yo_app_webhook'),
|
||||
url(r'^api/v1/external/codeship', 'webhooks.codeship.api_codeship_webhook'),
|
||||
|
||||
url(r'^user_uploads/(?P<realm_id>(\d*|unk))/(?P<filename>.*)', 'get_uploaded_file'),
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue