Add Semaphore webhook integration.

This commit is contained in:
Rishi Gupta
2016-06-17 10:53:21 -07:00
parent e4b72c3a65
commit 17b6d136d5
10 changed files with 192 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -232,6 +232,12 @@
<span class="integration-label">RSS</span>
</a>
</div>
<div class="integration-lozenge integration-semaphore">
<a class="integration-link integration-semaphore" href="#semaphore">
<img class="integration-logo" src="/static/images/integrations/logos/semaphore.png" alt="Semaphore logo" />
<span class="integration-label">Semaphore</span>
</a>
</div>
<div class="integration-lozenge integration-stash">
<a class="integration-link integration-stash" href="#stash">
<img class="integration-logo" src="/static/images/integrations/logos/stash.png" alt="Stash logo" />
@@ -1768,6 +1774,50 @@ key = NAGIOS_BOT_API_KEY
</div>
<div id="semaphore" class="integration-instructions">
<h4>Semaphore</h4>
<p>See build and deploy statuses on Semaphore right in Zulip with the Zulip
Semaphore plugin!</p>
<p>First, create the stream you'd like to use for Semaphore notifications, and
subscribe all interested parties to this stream. We recommend the
name <code>builds</code>.</p>
<p>Next, on your <a href="/#settings" target="_blank">Zulip settings
page</a>, create a Semaphore bot.</p>
<p>Then, log into your account on <a href="http://semaphoreci.com">semaphoreci.com</a>, and:</p>
<ol>
<li>
<p>Visit the "Project Settings" page for the project for which you'd like to generate
Zulip notifications. Click the "Notifications" tab in the left sidebar,
click on "Webhooks" in the resulting menu, and then click on "+ Add Webhook".</p>
<img class="screenshot" src="/static/images/integrations/semaphore/001.png" />
</li>
<li>
<p> You should now see a form that looks like this: </p>
<p> <img class="screenshot" style="border:1px solid #000000" src="/static/images/integrations/semaphore/002.png" /> </p>
<p> Enter the following webhook URI, replacing the bot email address,
bot API key, and Zulip stream with the appropriate
information. <b>Note:</b> the <code>@</code>-sign in the bot e-mail
address must be escaped to <code>%40</code>:</p>
<p><code>{{ external_uri_scheme }}<font color="#00A26F">semaphore-bot%40example.com</font>:<font color="#00A26F">api_key</font>@{{ external_api_path }}/v1/external/semaphore?stream=<font color="#00A26F">builds</font></code></p>
</li>
</ol>
<p><b>Congratulations! You're done!</b><br /> When you push to Semaphore, the
team can see these updates in real time in Zulip:</p>
<img class="screenshot" src="/static/images/integrations/semaphore/003.png" />
</div>
<div id="stash" class="integration-instructions">
<h4>Stash</h4>

View File

@@ -0,0 +1,20 @@
{
"branch_name":"master",
"branch_url":"https://semaphoreci.com/rishig/semaphore-test/branches/master",
"project_name":"knighthood",
"project_hash_id":"dff749fa-6acf-467c-85c9-119d63c8af4b",
"build_url":"https://semaphoreci.com/donquixote/knighthood/branches/master/builds/314",
"build_number":314,
"result":"passed",
"event":"build",
"started_at":"1605-01-16T00:01:58Z",
"finished_at":"1605-01-16T00:02:09Z",
"commit":{
"id":"a490b8d508ebbdab1d77a5c2aefa35ceb2d62daf",
"url":"https://github.com/donquixote/knighthood/commit/a490b8d508ebbdab1d77a5c2aefa35ceb2d62daf",
"author_name":"Don Quixote",
"author_email":"don@lamancha.com",
"message":"Create user account for Rocinante :horse:.",
"timestamp":"1605-01-16T00:01:41Z"
}
}

View File

@@ -0,0 +1,25 @@
{
"project_name":"knighthood",
"project_hash_id":"dff749fa-6acf-467c-85c9-119d63c8af4b",
"server_name":"lamancha-271",
"number":17,
"event":"deploy",
"result":"passed",
"created_at":"2016-06-17T00:59:09Z",
"updated_at":"2016-06-17T01:00:11Z",
"started_at":"2016-06-17T00:59:11Z",
"finished_at":"2016-06-17T00:59:21Z",
"html_url":"https://semaphoreci.com/donquixote/knighthood/servers/lamancha-271/deploys/17",
"build_number":314,
"build_html_url":"https://semaphoreci.com/donquixote/knighthood/branches/master/builds/314",
"branch_name":"master",
"branch_html_url":"https://semaphoreci.com/donquixote/knighthood/branches/master",
"commit":{
"id":"a490b8d508ebbdab1d77a5c2aefa35ceb2d62daf",
"url":"https://github.com/donquixote/knighthood/commit/a490b8d508ebbdab1d77a5c2aefa35ceb2d62daf",
"author_name":"Don Quixote",
"author_email":"don@lamancha.com",
"message":"Create user account for Rocinante :horse:.",
"timestamp":"2016-06-16T18:29:08Z"
}
}

View File

@@ -1479,3 +1479,31 @@ class IFTTTHookTests(WebhookTestCase):
expected_subject = u"Email sent from email@email.com"
expected_message = u"Email subject: Subject"
self.send_and_test_stream_message('correct_subject_and_body', expected_subject, expected_message)
class SemaphoreHookTests(WebhookTestCase):
STREAM_NAME = 'semaphore'
URL_TEMPLATE = "/api/v1/external/semaphore?stream={stream}&api_key={api_key}"
# Messages are generated by Semaphore on git push. The subject lines below
# contain information on the repo and branch, and the message has links and
# details about the build, deploy, server, author, and commit
def test_semaphore_build(self):
# type: () -> None
expected_subject = u"knighthood/master" # repo/branch
expected_message = u"""[build 314](https://semaphoreci.com/donquixote/knighthood/branches/master/builds/314): passed
!avatar(don@lamancha.com) [`a490b8d`](https://github.com/donquixote/knighthood/commit/a490b8d508ebbdab1d77a5c2aefa35ceb2d62daf): Create user account for Rocinante :horse:."""
self.send_and_test_stream_message('build', expected_subject, expected_message,
content_type="application/x-www-form-urlencoded")
def test_semaphore_deploy(self):
# type: () -> None
expected_subject = u"knighthood/master"
expected_message = u"""[deploy 17](https://semaphoreci.com/donquixote/knighthood/servers/lamancha-271/deploys/17) of [build 314](https://semaphoreci.com/donquixote/knighthood/branches/master/builds/314) on server lamancha-271: passed
!avatar(don@lamancha.com) [`a490b8d`](https://github.com/donquixote/knighthood/commit/a490b8d508ebbdab1d77a5c2aefa35ceb2d62daf): Create user account for Rocinante :horse:."""
self.send_and_test_stream_message('deploy', expected_subject, expected_message,
content_type="application/x-www-form-urlencoded")
def get_body(self, fixture_name):
# type: (text_type) -> text_type
return self.fixture_data("semaphore", fixture_name, file_type="json")

View File

@@ -0,0 +1,68 @@
# Webhooks for external integrations.
from __future__ import absolute_import
from django.http import HttpRequest, HttpResponse
from django.utils.translation import ugettext as _
from zerver.models import get_client, get_user_profile_by_email
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
from zerver.models import UserProfile, Client
import ujson
from six import text_type
from typing import Any, Dict
@api_key_only_webhook_view('Semaphore')
@has_request_variables
def api_semaphore_webhook(request, user_profile, client,
payload=REQ(argument_type='body'),
stream=REQ(default='builds')):
# type: (HttpRequest, UserProfile, Client, Dict[str, Any], str) -> HttpResponse
# semaphore only gives the last commit, even if there were multiple commits
# since the last build
try:
branch_name = payload["branch_name"]
project_name = payload["project_name"]
result = payload["result"]
event = payload["event"]
commit_id = payload["commit"]["id"]
commit_url = payload["commit"]["url"]
author_email = payload["commit"]["author_email"]
message = payload["commit"]["message"]
except KeyError as e:
return json_error(_("Missing key %s in JSON") % (e.message,))
if event == "build":
try:
build_url = payload["build_url"]
build_number = payload["build_number"]
except KeyError as e:
return json_error(_("Missing key %s in JSON") % (e.message,))
content = u"[build %s](%s): %s\n" % (build_number, build_url, result)
elif event == "deploy":
try:
build_url = payload["build_html_url"]
build_number = payload["build_number"]
deploy_url = payload["html_url"]
deploy_number = payload["number"]
server_name = payload["server_name"]
except KeyError as e:
return json_error(_("Missing key %s in JSON") % (e.message,))
content = u"[deploy %s](%s) of [build %s](%s) on server %s: %s\n" % \
(deploy_number, deploy_url, build_number, build_url, server_name, result)
else: # should never get here
content = u"%s: %s\n" % (event, result)
content += "!avatar(%s) [`%s`](%s): %s" % (author_email, commit_id[:7],
commit_url, message)
subject = u"%s/%s" % (project_name, branch_name)
check_send_message(user_profile, client, "stream",
[stream], subject, content)
return json_success()

View File

@@ -262,6 +262,7 @@ urls += [
url(r'^api/v1/external/pagerduty$', 'zerver.views.webhooks.pagerduty.api_pagerduty_webhook'),
url(r'^api/v1/external/pingdom$', 'zerver.views.webhooks.pingdom.api_pingdom_webhook'),
url(r'^api/v1/external/pivotal$', 'zerver.views.webhooks.pivotal.api_pivotal_webhook'),
url(r'^api/v1/external/semaphore$', 'zerver.views.webhooks.semaphore.api_semaphore_webhook'),
url(r'^api/v1/external/stash$', 'zerver.views.webhooks.stash.api_stash_webhook'),
url(r'^api/v1/external/taiga$', 'zerver.views.webhooks.taiga.api_taiga_webhook'),
url(r'^api/v1/external/teamcity$', 'zerver.views.webhooks.teamcity.api_teamcity_webhook'),