From 5963c1c09adee128d3a775ac1dd937d744b3f6c8 Mon Sep 17 00:00:00 2001 From: vapao Date: Thu, 10 Mar 2022 14:48:13 +0800 Subject: [PATCH] =?UTF-8?q?U=20Webhook=E8=A7=A6=E5=8F=91=E7=9A=84=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=8F=91=E5=B8=83=E8=AF=BB=E5=8F=96commit=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E4=BD=9C=E4=B8=BA=E7=94=B3=E8=AF=B7=E6=A0=87=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spug_api/apps/apis/deploy.py | 122 +++++++++++++++++++---------------- 1 file changed, 67 insertions(+), 55 deletions(-) diff --git a/spug_api/apps/apis/deploy.py b/spug_api/apps/apis/deploy.py index cc0067e..17289db 100644 --- a/spug_api/apps/apis/deploy.py +++ b/spug_api/apps/apis/deploy.py @@ -13,18 +13,17 @@ import json def auto_deploy(request, deploy_id, kind): - if not _is_valid_token(request): + repo, body = _parse_request(request) + if not repo: return HttpResponseForbidden() - try: - body = json.loads(request.body) - if not body['ref'].startswith('refs/'): # Compatible with gogs - body['ref'] = 'refs/tags/' + body['ref'] + try: _, _kind, ref = body['ref'].split('/', 2) if kind == 'branch' and _kind == 'heads': commit_id = body['after'] if commit_id != '0000000000000000000000000000000000000000' and ref == request.GET.get('name'): - Thread(target=_dispatch, args=(deploy_id, ref, commit_id)).start() + message = _parse_message(body, repo)[:20] + Thread(target=_dispatch, args=(deploy_id, ref, commit_id, message)).start() return HttpResponse(status=202) elif kind == 'tag' and _kind == 'tags': Thread(target=_dispatch, args=(deploy_id, ref)).start() @@ -34,70 +33,83 @@ def auto_deploy(request, deploy_id, kind): return HttpResponseBadRequest(e) -def _is_valid_token(request): +def _parse_request(request): api_key = AppSetting.get_default('api_key') - - # Gitlab Gitee Aliyun(Codeup) + token, repo, body = None, None, None token = request.headers.get('X-Gitlab-Token') - token = token or request.headers.get('X-Gitee-Token') - token = token or request.headers.get('X-Codeup-Token') - # Compatible the old version of gitlab - token = token or request.GET.get('token') - if token: - return token == api_key + if 'X-Gitlab-Token' in request.headers: + token = request.headers['X-Gitlab-Token'] + repo = 'Gitlab' + elif 'X-Gitee-Token' in request.headers: + token = request.headers['X-Gitee-Token'] + repo = 'Gitee' + elif 'X-Codeup-Token' in request.headers: + token = request.headers['X-Codeup-Token'] + repo = 'Codeup' + elif 'X-Gogs-Signature' in request.headers: + token = request.headers['X-Gogs-Signature'] + repo = 'Gogs' + elif 'X-Hub-Signature-256' in request.headers: + token = request.headers['X-Hub-Signature-256'].replace('sha256=', '') + repo = 'Github' + elif 'token' in request.GET: # Compatible the old version of gitlab + token = request.GET.get('token') + repo = 'Gitlab' - # Gogs Github - token = request.headers.get('X-Gogs-Signature') - token = token or request.headers.get('X-Hub-Signature-256', '').replace('sha256=', '') - if token: - return token == hmac.new(api_key.encode(), request.body, hashlib.sha256).hexdigest() - return False + if repo in ['Gitlab', 'Gitee', 'Codeup']: + if token != api_key: + return None, None + elif repo in ['Github', 'Gogs']: + en_api_key = hmac.new(api_key.encode(), request.body, hashlib.sha256).hexdigest() + if token != en_api_key: + return None, None + else: + return None, None + + body = json.loads(request.body) + if repo == 'Gogs' and not body['ref'].startswith('refs/'): + body['ref'] = 'refs/tags/' + body['ref'] + + return repo, body -def _dispatch(deploy_id, ref, commit_id=None): +def _parse_message(body, repo): + message = None + if repo in ['Gitee', 'Github']: + message = body.get('head_commit', {}).get('message', '') + elif repo in ['Gitlab', 'Codeup', 'Gogs']: + if body.get('commits'): + message = body['commits'][0].get('message', '') + else: + raise ValueError(f'repo {repo} is not supported') + return message + + +def _dispatch(deploy_id, ref, commit_id=None, message=None): deploy = Deploy.objects.filter(pk=deploy_id).first() if not deploy: raise Exception(f'no such deploy id for {deploy_id}') - if deploy.extend == '1': - _deploy_extend_1(deploy, ref, commit_id) - else: - _deploy_extend_2(deploy, ref, commit_id) - -def _deploy_extend_1(deploy, ref, commit_id=None): - if commit_id: - extra = ['branch', ref, commit_id] - version = f'{ref}#{commit_id[:6]}' - else: - extra = ['tag', ref, None] - version = ref - - req = DeployRequest.objects.create( + req = DeployRequest( type='3', status='0' if deploy.is_audit else '2', deploy=deploy, - name=version, - extra=json.dumps(extra), - version=version, - spug_version=Repository.make_spug_version(deploy.id), - host_ids=deploy.host_ids, - created_by=deploy.created_by - ) - if req.status == '2': - deploy_dispatch(req) - - -def _deploy_extend_2(deploy, ref, commit_id=None): - version = f'{ref}#{commit_id[:6]}' if commit_id else ref - req = DeployRequest.objects.create( - type='3', - status='0' if deploy.is_audit else '2', - deploy=deploy, - name=version, - version=version, spug_version=Repository.make_spug_version(deploy.id), host_ids=deploy.host_ids, created_by=deploy.created_by ) + + if commit_id: # branch + req.version = f'{ref}#{commit_id[:6]}' + req.name = message or req.version + if deploy.extend == '1': + req.extra = json.dumps(['branch', ref, commit_id]) + else: # tag + req.version = ref + req.name = ref + if deploy.extend == '1': + req.extra = json.dumps(['tag', ref, None]) + + req.save() if req.status == '2': deploy_dispatch(req)