python-ci/server.py

89 lines
3.5 KiB
Python
Raw Normal View History

2018-11-04 14:51:04 +01:00
#! /usr/bin/env nix-shell
#! nix-shell -i python3 -p "python3.withPackages(ps: [ps.pyramid ps.python-gitlab])"
2018-11-04 12:05:00 +01:00
from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.view import view_config, view_defaults
from pyramid.httpexceptions import HTTPNotFound
2018-11-04 14:51:04 +01:00
from subprocess import check_call, CalledProcessError
2018-11-04 12:05:00 +01:00
import urllib.request
import tarfile
from tempfile import TemporaryDirectory
from multiprocessing import Pool
2018-11-04 14:51:04 +01:00
from gitlab import Gitlab
2018-11-04 18:22:16 +01:00
import argparse
2018-11-04 12:05:00 +01:00
2018-11-04 21:48:29 +01:00
def gitlab_build(payload, gl):
payload = payload
gl = gl
commit = gl.projects.get(payload['project']['path_with_namespace']).commits.get(payload['checkout_sha'])
commit.statuses.create({'state': 'running', 'name': 'Python CI'})
2018-11-04 12:05:00 +01:00
print("push from " + payload['user_name'])
print("repo: " + payload['project']['path_with_namespace'])
print("commit: " + payload['checkout_sha'])
temp_dir = TemporaryDirectory()
repo_dir = temp_dir.name + '/' + payload['project']['name'] + '-' + payload['checkout_sha']
archive_url = payload['project']['web_url'] + '/-/archive/' + payload['checkout_sha'] + \
'/' + payload['project']['name'] + '-' + payload['checkout_sha'] + '.tar.gz'
2018-11-04 21:48:29 +01:00
2018-11-04 12:05:00 +01:00
with urllib.request.urlopen(archive_url) as gitlab_archive:
with tarfile.open(fileobj=gitlab_archive, mode='r|gz') as gitlab_repo_files:
gitlab_repo_files.extractall(path=temp_dir.name)
2018-11-04 21:48:29 +01:00
2018-11-04 12:05:00 +01:00
check_call(['ls', '-lha', repo_dir])
2018-11-04 21:48:29 +01:00
2018-11-04 14:51:04 +01:00
try:
2018-11-04 18:22:16 +01:00
check_call(['nix-build', '-o', args.output + '/' + payload['project']['path_with_namespace'], repo_dir])
2018-11-04 14:51:04 +01:00
except CalledProcessError:
2018-11-04 21:48:29 +01:00
commit.statuses.create({'state': 'failed', 'name': 'Python CI'})
print("erreur build")
2018-11-04 14:51:04 +01:00
2018-11-04 21:48:29 +01:00
commit.statuses.create({'state': 'success', 'name': 'Python CI'})
print("build terminé")
2018-11-04 12:05:00 +01:00
@view_defaults(
route_name="gitlab_payload", renderer="json", request_method="POST"
)
2018-11-04 21:48:29 +01:00
class GitlabHook(object):
2018-11-04 12:05:00 +01:00
def __init__(self, request):
self.request = request
self.payload = self.request.json
2018-11-04 21:48:29 +01:00
self.whitelist = ['nyanloutre/site-musique']
self.secret = open(args.secret, 'r').readline().splitlines()[0]
self.gitlab_token = open(args.gitlab_token, 'r').readline().splitlines()[0]
2018-11-04 18:22:16 +01:00
self.gl = Gitlab('https://gitlab.com', private_token=self.gitlab_token)
2018-11-04 12:05:00 +01:00
@view_config(header="X-Gitlab-Event:Push Hook")
2018-11-04 21:48:29 +01:00
def push_hook(self):
if self.payload['project']['path_with_namespace'] in self.whitelist and self.request.headers['X-Gitlab-Token'] == self.secret:
2018-11-04 18:22:16 +01:00
self.gl.projects.get(self.payload['project']['path_with_namespace']).commits.get(self.payload['checkout_sha']).statuses.create({'state': 'pending', 'name': 'Python CI'})
2018-11-04 21:48:29 +01:00
pool.apply_async(gitlab_build, (self.payload, self.gl))
2018-11-04 12:05:00 +01:00
return "build started"
else:
raise HTTPNotFound
if __name__ == "__main__":
2018-11-04 18:22:16 +01:00
parser = argparse.ArgumentParser(description='CI server')
2018-11-04 21:48:29 +01:00
parser.add_argument('--address', help='listening address', default='127.0.0.1')
parser.add_argument('--port', type=int, help='listening port')
2018-11-04 18:22:16 +01:00
parser.add_argument('--output', help='output directory')
parser.add_argument('--secret', help='repo secret file')
parser.add_argument('--gitlab-token', help='gitlab token file')
args = parser.parse_args()
2018-11-04 12:05:00 +01:00
pool = Pool(1)
config = Configurator()
config.add_route("gitlab_payload", "/gitlab_payload")
config.scan()
app = config.make_wsgi_app()
2018-11-04 21:48:29 +01:00
server = make_server(args.address, args.port, app)
2018-11-04 14:51:04 +01:00
print('listening ...')
2018-11-04 12:05:00 +01:00
server.serve_forever()