[damned-lies] Add webhook to automatically update code
- From: Claude Paroz <claudep src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [damned-lies] Add webhook to automatically update code
- Date: Sat, 19 May 2018 10:19:03 +0000 (UTC)
commit 6ab6f34e2ea24f578346ada1e47428df3feef1fe
Author: Claude Paroz <claude 2xlibre net>
Date: Tue Apr 24 15:16:18 2018 +0200
Add webhook to automatically update code
common/tests.py | 20 ++++++++++++++++++++
common/views.py | 23 +++++++++++++++++++++--
damnedlies/settings.py | 2 ++
damnedlies/urls.py | 3 +++
4 files changed, 46 insertions(+), 2 deletions(-)
---
diff --git a/common/tests.py b/common/tests.py
index ce14382..f766218 100644
--- a/common/tests.py
+++ b/common/tests.py
@@ -3,6 +3,7 @@ from datetime import datetime, timedelta
from unittest import skipUnless
from unittest.mock import MagicMock, patch
+from django.conf import settings
from django.core.management import call_command
from django.test import TestCase
from django.urls import reverse
@@ -61,6 +62,25 @@ class CommonTest(TestCase):
for role in Role.objects.filter(person=jt):
self.assertFalse(role.is_active)
+ def test_pull_code(self):
+ push_data = {
+ "object_kind": "push",
+ "ref": "refs/heads/master",
+ # Gitlab will send a lot more, but we don't care.
+ }
+ with patch('common.views.run_shell_command', return_value=(0, '', '')) as rsc_patched:
+ with patch('common.views.call_command') as cc_patched:
+ response = self.client.post('/pull_code/', data=push_data)
+ self.assertEqual(response.status_code, 403)
+ response = self.client.post(
+ '/pull_code/', data=push_data,
+ HTTP_X_GITLAB_EVENT='Push Hook',
+ HTTP_X_GITLAB_TOKEN=settings.GITLAB_TOKEN,
+ )
+ self.assertEqual(rsc_patched.call_count, 2)
+ self.assertEqual(cc_patched.call_count, 1)
+ self.assertEqual(response.content, b'OK')
+
class LcSortedTest(TestCase):
diff --git a/common/views.py b/common/views.py
index 3b2100b..0e2bd57 100644
--- a/common/views.py
+++ b/common/views.py
@@ -1,7 +1,10 @@
+from pathlib import Path
+
from django.conf import settings
from django.contrib.auth import login, authenticate
from django.contrib import messages
-from django.http import HttpResponseRedirect, Http404
+from django.core.management import call_command
+from django.http import HttpResponse, HttpResponseForbidden, HttpResponseRedirect, Http404
from django.shortcuts import render
from django.template.loader import get_template, TemplateDoesNotExist
from django.urls import reverse
@@ -11,7 +14,7 @@ from django.utils.translation import ugettext as _
from people.models import Person, obfuscate_email
from teams.models import Role
from people.forms import LoginForm, RegistrationForm
-from common.utils import get_user_locale
+from .utils import get_user_locale, run_shell_command
def index(request):
@@ -115,3 +118,19 @@ def help(request, topic, modal):
return render(request, template, {
'base': 'base_modal.html' if modal and int(modal) else 'base.html'
})
+
+
+def pull_code(request):
+ """GitLab Webhok endpoint to update code after a repository push."""
+ verified = (
+ request.method == 'POST' and
+ request.META.get('HTTP_X_GITLAB_EVENT') == 'Push Hook' and
+ request.META.get('HTTP_X_GITLAB_TOKEN') == settings.GITLAB_TOKEN
+ )
+ if not verified:
+ return HttpResponseForbidden()
+
+ run_shell_command(['git', 'pull', '--rebase'])
+ call_command('compile-trans', verbosity=0)
+ run_shell_command(['touch', 'wsgi.py'], cwd=Path(settings.BASE_DIR) / 'damnedlies')
+ return HttpResponse('OK')
diff --git a/damnedlies/settings.py b/damnedlies/settings.py
index 61bb81b..b6c3355 100644
--- a/damnedlies/settings.py
+++ b/damnedlies/settings.py
@@ -171,6 +171,8 @@ GETTEXT_ITS_DATA = {
],
}
+GITLAB_TOKEN = 'fill_with_real_token'
+
try:
from .local_settings import *
except ImportError:
diff --git a/damnedlies/urls.py b/damnedlies/urls.py
index 7943ef8..e24bdf3 100644
--- a/damnedlies/urls.py
+++ b/damnedlies/urls.py
@@ -50,6 +50,9 @@ urlpatterns = [
auth_views.password_reset_complete,
name='password_reset_complete'),
+ # Webhook endpoint
+ url(r'^pull_code/$', common_views.pull_code),
+
url(r'^teams/', include('teams.urls')),
url(r'^people/', include('people.urls')),
url(# users is the hardcoded url in the contrib.auth User class, making it identical to /people
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]