From bfbca15c262a48384c90c5fc0ce5e0f8b27cee0d Mon Sep 17 00:00:00 2001 From: robertdfrench Date: Fri, 30 Dec 2016 13:05:58 -0500 Subject: [PATCH 01/16] Add github route --- .gitignore | 1 + gettingstarted/urls.py | 1 + hello/views.py | 2 ++ 3 files changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index f95d164a6..0bc3db67f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ venv staticfiles .env db.sqlite3 +.venv/* diff --git a/gettingstarted/urls.py b/gettingstarted/urls.py index 608147ae5..f0afb9405 100644 --- a/gettingstarted/urls.py +++ b/gettingstarted/urls.py @@ -13,4 +13,5 @@ url(r'^$', hello.views.index, name='index'), url(r'^db', hello.views.db, name='db'), url(r'^admin/', include(admin.site.urls)), + url(r'^github-push-events/', hello.views.github, name='github') ] diff --git a/hello/views.py b/hello/views.py index 8558d8451..6c2feb31b 100644 --- a/hello/views.py +++ b/hello/views.py @@ -18,3 +18,5 @@ def db(request): return render(request, 'db.html', {'greetings': greetings}) +def github(request): + return "This is the github route" From 2dc55f0fbb72c292ebe9f5109276d167506e43bc Mon Sep 17 00:00:00 2001 From: robertdfrench Date: Fri, 30 Dec 2016 13:08:48 -0500 Subject: [PATCH 02/16] Return Http Response --- hello/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hello/views.py b/hello/views.py index 6c2feb31b..a20976779 100644 --- a/hello/views.py +++ b/hello/views.py @@ -18,5 +18,6 @@ def db(request): return render(request, 'db.html', {'greetings': greetings}) + def github(request): - return "This is the github route" + return HttpResponse("This is the github route") From c1e46f656ac20ca4561a94121adc6493d48a4b61 Mon Sep 17 00:00:00 2001 From: robertdfrench Date: Fri, 30 Dec 2016 13:26:54 -0500 Subject: [PATCH 03/16] Add push events table: --- hello/migrations/0002_auto_20161230_1825.py | 29 +++++++++++++++++++++ hello/models.py | 5 ++++ hello/templates/push_events.html | 21 +++++++++++++++ hello/views.py | 17 +++++++++++- 4 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 hello/migrations/0002_auto_20161230_1825.py create mode 100644 hello/templates/push_events.html diff --git a/hello/migrations/0002_auto_20161230_1825.py b/hello/migrations/0002_auto_20161230_1825.py new file mode 100644 index 000000000..7d0058b86 --- /dev/null +++ b/hello/migrations/0002_auto_20161230_1825.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-12-30 18:25 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('hello', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='PushEvent', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('when', models.DateTimeField(auto_now_add=True, verbose_name='date created')), + ('payload', models.TextField()), + ('new', models.BooleanField()), + ], + ), + migrations.AlterField( + model_name='greeting', + name='when', + field=models.DateTimeField(auto_now_add=True, verbose_name='date created'), + ), + ] diff --git a/hello/models.py b/hello/models.py index 89d76fd1b..06a1cb27b 100644 --- a/hello/models.py +++ b/hello/models.py @@ -3,3 +3,8 @@ # Create your models here. class Greeting(models.Model): when = models.DateTimeField('date created', auto_now_add=True) + +class PushEvent(models.Model): + when = models.DateTimeField('date created', auto_now_add=True) + payload = models.TextField() + new = models.BooleanField() diff --git a/hello/templates/push_events.html b/hello/templates/push_events.html new file mode 100644 index 000000000..c1dc56fc9 --- /dev/null +++ b/hello/templates/push_events.html @@ -0,0 +1,21 @@ +{% extends "base.html" %} +{% load staticfiles %} + +{% block content %} +
+ + +

Page View Report

+ + +
    + +{% for push_event in push_events %} +
  • {{ push_event.when }} | {{ push_Event.payload }}
  • +{% endfor %} + +
+ +
+ +{% endblock %} diff --git a/hello/views.py b/hello/views.py index a20976779..14d073bbb 100644 --- a/hello/views.py +++ b/hello/views.py @@ -1,7 +1,7 @@ from django.shortcuts import render from django.http import HttpResponse -from .models import Greeting +from .models import Greeting, PushEvent # Create your views here. def index(request): @@ -20,4 +20,19 @@ def db(request): def github(request): + if request.method == 'GET': + return _show_requests(request) + else: + return _new_request(request) + + +def _new_request(request): + push_event = PushEvent() + push_event.payload = request.body + push_event.save() return HttpResponse("This is the github route") + + +def _show_requests(request): + push_events = PushEvent.objects.all() + return render(request, 'push_events.html', {'push_events': push_events}) From 05af719d55f6cf3f16e40cdf1dbdd22502b791b1 Mon Sep 17 00:00:00 2001 From: robertdfrench Date: Fri, 30 Dec 2016 13:53:23 -0500 Subject: [PATCH 04/16] update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 30cc47c48..caba962da 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# python-getting-started +# OLCF CI Thing A barebones Python app, which can easily be deployed to Heroku. From 1cdd5ba3c900b3f82ab9e19bc9319be96502f412 Mon Sep 17 00:00:00 2001 From: robertdfrench Date: Fri, 30 Dec 2016 13:56:29 -0500 Subject: [PATCH 05/16] Exempt CSRF for webhook handler --- hello/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hello/views.py b/hello/views.py index 14d073bbb..ba316ce71 100644 --- a/hello/views.py +++ b/hello/views.py @@ -1,5 +1,6 @@ from django.shortcuts import render from django.http import HttpResponse +from django.views.decorators.csrf import csrf_exempt from .models import Greeting, PushEvent @@ -18,7 +19,7 @@ def db(request): return render(request, 'db.html', {'greetings': greetings}) - +@csrf_exempt def github(request): if request.method == 'GET': return _show_requests(request) From 48c985fde1ae38c73151a61283779cd6af515e9f Mon Sep 17 00:00:00 2001 From: robertdfrench Date: Fri, 30 Dec 2016 14:00:23 -0500 Subject: [PATCH 06/16] Mark new events as new --- hello/views.py | 1 + 1 file changed, 1 insertion(+) diff --git a/hello/views.py b/hello/views.py index ba316ce71..f996c3a0b 100644 --- a/hello/views.py +++ b/hello/views.py @@ -30,6 +30,7 @@ def github(request): def _new_request(request): push_event = PushEvent() push_event.payload = request.body + push_event.new = True push_event.save() return HttpResponse("This is the github route") From f53448a85813c1456d70c3e43265d7c49f4ef013 Mon Sep 17 00:00:00 2001 From: robertdfrench Date: Fri, 30 Dec 2016 14:02:06 -0500 Subject: [PATCH 07/16] Unlike FORTRAN, Embedded Python is case-sensitive --- hello/templates/push_events.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hello/templates/push_events.html b/hello/templates/push_events.html index c1dc56fc9..71c1fe2ed 100644 --- a/hello/templates/push_events.html +++ b/hello/templates/push_events.html @@ -11,7 +11,7 @@

Page View Report

    {% for push_event in push_events %} -
  • {{ push_event.when }} | {{ push_Event.payload }}
  • +
  • {{ push_event.when }} | {{ push_event.payload }}
  • {% endfor %}
From 81d7599bed69af6f283acfa60a43292bb70ab6d9 Mon Sep 17 00:00:00 2001 From: robertdfrench Date: Fri, 30 Dec 2016 14:11:45 -0500 Subject: [PATCH 08/16] Respond in json --- hello/views.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hello/views.py b/hello/views.py index f996c3a0b..16fcab848 100644 --- a/hello/views.py +++ b/hello/views.py @@ -1,6 +1,7 @@ from django.shortcuts import render -from django.http import HttpResponse +from django.http import HttpResponse, JsonResponse from django.views.decorators.csrf import csrf_exempt +import json from .models import Greeting, PushEvent @@ -37,4 +38,5 @@ def _new_request(request): def _show_requests(request): push_events = PushEvent.objects.all() - return render(request, 'push_events.html', {'push_events': push_events}) + json_events = [json.loads(pe.payload) for pe in push_events] + return JsonResponse({'data': json_events}) From e23bc11c29d5ba06cd28abc117775cb64c4cab43 Mon Sep 17 00:00:00 2001 From: robertdfrench Date: Fri, 30 Dec 2016 14:26:52 -0500 Subject: [PATCH 09/16] Add pop method --- gettingstarted/urls.py | 1 + hello/views.py | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/gettingstarted/urls.py b/gettingstarted/urls.py index f0afb9405..87c296180 100644 --- a/gettingstarted/urls.py +++ b/gettingstarted/urls.py @@ -13,5 +13,6 @@ url(r'^$', hello.views.index, name='index'), url(r'^db', hello.views.db, name='db'), url(r'^admin/', include(admin.site.urls)), + url(r'^github-push-events/pop', hello.views.github_pop, name='github_pop'), url(r'^github-push-events/', hello.views.github, name='github') ] diff --git a/hello/views.py b/hello/views.py index 16fcab848..df33b822e 100644 --- a/hello/views.py +++ b/hello/views.py @@ -40,3 +40,14 @@ def _show_requests(request): push_events = PushEvent.objects.all() json_events = [json.loads(pe.payload) for pe in push_events] return JsonResponse({'data': json_events}) + + +@csrf_exempt +def github_pop(request): + push_event = PushEvent.objects.order_by('when').filter(new=True).first() + if push_event: + json_event = json.loads(push_event.payload) + push_event.delete() + return JsonResponse({'data': json_event}) + else: + return JsonResponse({}) From f521cc171e879563b785973442f106118d09050d Mon Sep 17 00:00:00 2001 From: robertdfrench Date: Fri, 30 Dec 2016 15:07:20 -0500 Subject: [PATCH 10/16] Add client --- client/__init__.py | 0 client/__main__.py | 27 +++++++++++++++++++++++++++ test.exe | 2 ++ 3 files changed, 29 insertions(+) create mode 100644 client/__init__.py create mode 100644 client/__main__.py create mode 100755 test.exe diff --git a/client/__init__.py b/client/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/client/__main__.py b/client/__main__.py new file mode 100644 index 000000000..62525ddf0 --- /dev/null +++ b/client/__main__.py @@ -0,0 +1,27 @@ +#!/bin/env python +import requests +import sys +import subprocess +import shlex +import os +import uuid + + +response = requests.get("https://olcf-ci-service.herokuapp.com/github-push-events/pop").json() +if 'data' not in response: + print("No push events available right now") + sys.exit(0) + +push_event = response['data'] +clone_url = push_event['repository']['clone_url'] +commit = push_event['head_commit']['id'] + +def shell(command): + print("$ %s" % command) + subprocess.call(shlex.split(command)) + +repo_dir = "olcf-ci-%s" % uuid.uuid4() +shell("git clone %s %s" % (clone_url, repo_dir)) +os.chdir(repo_dir) +shell("git checkout %s" % commit) +shell("./test.exe") diff --git a/test.exe b/test.exe new file mode 100755 index 000000000..fc45109e7 --- /dev/null +++ b/test.exe @@ -0,0 +1,2 @@ +#!/bin/bash +echo "It worked!" From 91a35f298e08f27d2a198f3be6267f94c62a9f7e Mon Sep 17 00:00:00 2001 From: robertdfrench Date: Fri, 30 Dec 2016 15:28:43 -0500 Subject: [PATCH 11/16] Refactor client --- client/__main__.py | 33 ++++++++------------------------- client/push_event.py | 18 ++++++++++++++++++ client/run_ci.py | 11 +++++++++++ client/util.py | 6 ++++++ 4 files changed, 43 insertions(+), 25 deletions(-) create mode 100644 client/push_event.py create mode 100644 client/run_ci.py create mode 100644 client/util.py diff --git a/client/__main__.py b/client/__main__.py index 62525ddf0..7259f1797 100644 --- a/client/__main__.py +++ b/client/__main__.py @@ -1,27 +1,10 @@ #!/bin/env python -import requests -import sys -import subprocess -import shlex -import os -import uuid - - -response = requests.get("https://olcf-ci-service.herokuapp.com/github-push-events/pop").json() -if 'data' not in response: +from client.util import shell +from client import push_event +from client import run_ci + +pe = push_event.next() +if pe: + run_ci.run(pe) +else: print("No push events available right now") - sys.exit(0) - -push_event = response['data'] -clone_url = push_event['repository']['clone_url'] -commit = push_event['head_commit']['id'] - -def shell(command): - print("$ %s" % command) - subprocess.call(shlex.split(command)) - -repo_dir = "olcf-ci-%s" % uuid.uuid4() -shell("git clone %s %s" % (clone_url, repo_dir)) -os.chdir(repo_dir) -shell("git checkout %s" % commit) -shell("./test.exe") diff --git a/client/push_event.py b/client/push_event.py new file mode 100644 index 000000000..a759ebcf4 --- /dev/null +++ b/client/push_event.py @@ -0,0 +1,18 @@ +import requests + + +def next(): + response = requests.get("https://olcf-ci-service.herokuapp.com/github-push-events/pop").json() + if 'data' in response: + return PushEvent.fromGithubEvent(response['data']) + + +class PushEvent(object): + def __init__(self, clone_url, commit): + self.clone_url = clone_url + self.commit = commit + + def fromGithubEvent(cls, event): + clone_url = event['repository']['clone_url'] + commit = event['head_commit']['id'] + return cls(clone_url, commit) diff --git a/client/run_ci.py b/client/run_ci.py new file mode 100644 index 000000000..cdd219e97 --- /dev/null +++ b/client/run_ci.py @@ -0,0 +1,11 @@ +import shlex +import os +import uuid + + +def run(push_event): + repo_dir = "olcf-ci-%s" % uuid.uuid4() + shell("git clone %s %s" % (push_event.clone_url, repo_dir)) + os.chdir(repo_dir) + shell("git checkout %s" % push_event.commit) + shell("./test.exe") diff --git a/client/util.py b/client/util.py new file mode 100644 index 000000000..930a837ec --- /dev/null +++ b/client/util.py @@ -0,0 +1,6 @@ +import subprocess + + +def shell(command): + print("$ %s" % command) + subprocess.call(shlex.split(command)) From ad1bb787da4db8cf66df3f2199d8c39a25c35042 Mon Sep 17 00:00:00 2001 From: robertdfrench Date: Fri, 30 Dec 2016 15:29:26 -0500 Subject: [PATCH 12/16] Use classmehtod decorator --- client/push_event.py | 1 + 1 file changed, 1 insertion(+) diff --git a/client/push_event.py b/client/push_event.py index a759ebcf4..324a4c651 100644 --- a/client/push_event.py +++ b/client/push_event.py @@ -12,6 +12,7 @@ def __init__(self, clone_url, commit): self.clone_url = clone_url self.commit = commit + @classmethod def fromGithubEvent(cls, event): clone_url = event['repository']['clone_url'] commit = event['head_commit']['id'] From dbe42d8b18e5aca31a39021ed14b4f98a4855693 Mon Sep 17 00:00:00 2001 From: robertdfrench Date: Fri, 30 Dec 2016 15:30:09 -0500 Subject: [PATCH 13/16] Import shell utils --- client/run_ci.py | 1 + 1 file changed, 1 insertion(+) diff --git a/client/run_ci.py b/client/run_ci.py index cdd219e97..5ccc444d0 100644 --- a/client/run_ci.py +++ b/client/run_ci.py @@ -1,6 +1,7 @@ import shlex import os import uuid +from client.util import shell def run(push_event): From b1004c4bf65fd059d314da8641514e83cd28d686 Mon Sep 17 00:00:00 2001 From: robertdfrench Date: Fri, 30 Dec 2016 15:30:47 -0500 Subject: [PATCH 14/16] Import shell utils --- client/run_ci.py | 1 - client/util.py | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/client/run_ci.py b/client/run_ci.py index 5ccc444d0..e8c051a51 100644 --- a/client/run_ci.py +++ b/client/run_ci.py @@ -1,4 +1,3 @@ -import shlex import os import uuid from client.util import shell diff --git a/client/util.py b/client/util.py index 930a837ec..539c8a8a6 100644 --- a/client/util.py +++ b/client/util.py @@ -1,4 +1,5 @@ import subprocess +import shlex def shell(command): From 37ae30a2ff163f697b2d74d7f22fdc4ff22719d8 Mon Sep 17 00:00:00 2001 From: robertdfrench Date: Fri, 30 Dec 2016 15:34:10 -0500 Subject: [PATCH 15/16] Run in a loop --- client/__main__.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/client/__main__.py b/client/__main__.py index 7259f1797..1d579ba39 100644 --- a/client/__main__.py +++ b/client/__main__.py @@ -1,10 +1,16 @@ #!/bin/env python +import time from client.util import shell from client import push_event from client import run_ci -pe = push_event.next() -if pe: - run_ci.run(pe) -else: - print("No push events available right now") +def try_ci(): + pe = push_event.next() + if pe: + run_ci.run(pe) + else: + print("No push events available right now") + +while True: + try_ci() + time.sleep(10) From 8f420ef7d3635a8c75b8536cdfabbd84cd553cc1 Mon Sep 17 00:00:00 2001 From: robertdfrench Date: Fri, 30 Dec 2016 15:36:37 -0500 Subject: [PATCH 16/16] Dummy commit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index caba962da..acf0abc4e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # OLCF CI Thing +Whatup scott A barebones Python app, which can easily be deployed to Heroku. This application supports the [Getting Started with Python on Heroku](https://devcenter.heroku.com/articles/getting-started-with-python) article - check it out.