Compare commits

..

5 Commits

Author SHA1 Message Date
8091be197d
Fixed change and property
All checks were successful
buildbot/multibuild_parent Build done.
buildbot/travis_bionic Build done.
2023-01-13 12:30:22 +05:30
ab6d1083ec
Updated method names
All checks were successful
buildbot/multibuild_parent Build done.
buildbot/travis_bionic Build done.
2023-01-12 16:06:01 +05:30
89305ec602
Update Webhook response variabel
All checks were successful
buildbot/multibuild_parent Build done.
buildbot/travis_bionic Build done.
2023-01-06 20:49:37 +05:30
1b29a5639c
WIP[downloadTranslatedLanguage() and updateLocalTranslationDestination()]
All checks were successful
buildbot/multibuild_parent Build done.
buildbot/travis_bionic Build done.
2023-01-05 22:25:01 +05:30
f2587e071d
Update webhook and setup 2023-01-04 12:08:55 +05:30
2 changed files with 90 additions and 152 deletions

View File

@ -1,8 +1,13 @@
"""Transifex webhook handler """
import base64 import base64
import json
import re
import hmac
import hashlib import hashlib
import hmac
import json
import os
import requests
import re
import time
from buildbot.process.properties import Properties from buildbot.process.properties import Properties
from buildbot.util import bytes2unicode, unicode2bytes from buildbot.util import bytes2unicode, unicode2bytes
from buildbot.www.hooks.base import BaseHookHandler from buildbot.www.hooks.base import BaseHookHandler
@ -10,134 +15,95 @@ from buildbot.www.hooks.base import BaseHookHandler
from twisted.internet import defer from twisted.internet import defer
from twisted.python import log from twisted.python import log
from dateutil.parser import parse as dateparse
_HEADER_USER_AGENT = 'User-Agent' _HEADER_USER_AGENT = 'User-Agent'
_HEADER_SIGNATURE = 'X-TX-Signature' _HEADER_SIGNATURE = 'X-TX-Signature'
_HEADER_URL_PATH = 'X-TX-Url'
_HTTP_DATE = 'date'
_EVENT_KEY = 'event' _EVENT_KEY = 'event'
author = 'buildbot-transifex'
class TransifexHandler(BaseHookHandler): class TransifexHandler(BaseHookHandler):
def process_translation_completed(self, payload, event_type, codebase): def __init__(self, master, secret, transifex_to_github_map, options=None):
refname = payload["ref"] if not options:
options = {}
self.secret = secret
self.master = master
self.options = options
self.transifex_to_github_map = transifex_to_github_map
def returnMessage(self, status = False, message = "Unimplemented"):
output = json.dumps({"status": "OK" if status else "FAIL", "message": message})
return [output, [('Content-type', 'application/json')]]
def _verifyTransifexSignature(
self, request, content, signature, header_signature
):
http_verb = 'POST'
http_url_path = request.getHeader(_HEADER_URL_PATH)
http_gmt_date = request.getHeader(_HTTP_DATE)
content_md5 = hashlib.md5(content).hexdigest()
msg = b'\n'.join([
http_verb, http_url_path, http_gmt_date, content_md5
])
tx_signature = base64.b64encode(
hmac.new(
key=self.rendered_secret,
msg=msg,
digestmod=hashlib.sha256
).digest()
)
if tx_signature != header_signature:
raise ValueError("Tx Signature mismatch")
if signature != request.getHeader(_HEADER_SIGNATURE):
raise ValueError("Signature mismatch")
return True
def process_translation_completed(self, payload, codebase):
changes = [] changes = []
translated_request = self._transform_variables(payload['project'], payload['resource'])
# We only care about regular heads or tags ts = int(time.time())
match = re.match(r"^refs/(heads|tags)/(.+)$", refname)
if not match:
log.msg("Ignoring refname '{}': Not a branch or tag".format(refname))
return changes
branch = match.group(2)
repository = payload['repository']
repo_url = repository['ssh_url']
project = repository['full_name']
commits = payload['commits']
if isinstance(self.options, dict) and self.options.get('onlyIncludePushCommit', False):
commits = commits[:1]
for commit in commits:
files = []
for kind in ('added', 'modified', 'removed'):
files.extend(commit.get(kind, []) or [])
timestamp = dateparse(commit['timestamp'])
change = { change = {
'author': '{} <{}>'.format(commit['author']['name'], 'author': author,
commit['author']['email']), 'branch': translated_request["branch"],
'files': files, 'branch': translated_request["repository"],
'comments': commit['message'], 'project': translated_request["project"],
'revision': commit['id'],
'when_timestamp': timestamp,
'branch': branch,
'revlink': commit['url'],
'repository': repo_url,
'project': project,
'category': event_type,
'properties': { 'properties': {
'event': event_type, "transifex_language": payload.get("language", "None"),
'repository_name': repository['name'], "transifex_event": payload.get("event", "None"),
'owner': repository["owner"]["username"] "transifex_project": payload.get("project", "None"),
}, "transifex_resource": payload.get("resource", "None"),
"transifex_branch": "translate_" + payload['language'] + "_" + str(ts)
}
} }
if codebase is not None: if codebase is not None:
change['codebase'] = codebase change['codebase'] = codebase
changes.insert(0, change) changes.insert(0, change)
return changes return changes
def process_review_compoleted(self, payload, event_type, codebase): def _transform_variables(self, transifex_project):
action = payload['action'] if transifex_project is None:
raise ValueError("Unknown project %s from transifex".format(transifex_project))
# Only handle potential new stuff, ignore close/. key = transifex_project
# Merge itself is handled by the regular branch push message _map = self.map[key]
if action not in ['opened', 'synchronized', 'edited', 'reopened']: repository = _map["repository"]
log.msg("Gitea Pull Request event '{}' ignored".format(action)) project = re.sub(r'^.*/(.*?)(\.git)?$', r'\1', repository)
return [] return{
pull_request = payload['pull_request'] 'project': project,
if not pull_request['mergeable']: 'repository': repository,
log.msg("Gitea Pull Request ignored because it is not mergeable.") 'branch': _map["branch"],
return []
if pull_request['merged']:
log.msg("Gitea Pull Request ignored because it is already merged.")
return []
timestamp = dateparse(pull_request['updated_at'])
base = pull_request['base']
head = pull_request['head']
repository = payload['repository']
change = {
'author': '{} <{}>'.format(pull_request['user']['full_name'],
pull_request['user']['email']),
'comments': 'PR#{}: {}\n\n{}'.format(
pull_request['number'],
pull_request['title'],
pull_request['body']),
'revision': base['sha'],
'when_timestamp': timestamp,
'branch': base['ref'],
'revlink': pull_request['html_url'],
'repository': base['repo']['ssh_url'],
'project': repository['full_name'],
'category': event_type,
'properties': {
'event': event_type,
'base_branch': base['ref'],
'base_sha': base['sha'],
'base_repo_id': base['repo_id'],
'base_repository': base['repo']['clone_url'],
'base_git_ssh_url': base['repo']['ssh_url'],
'head_branch': head['ref'],
'head_sha': head['sha'],
'head_repo_id': head['repo_id'],
'head_repository': head['repo']['clone_url'],
'head_git_ssh_url': head['repo']['ssh_url'],
'head_owner': head['repo']['owner']['username'],
'head_reponame': head['repo']['name'],
'pr_id': pull_request['id'],
'pr_number': pull_request['number'],
'repository_name': repository['name'],
'owner': repository["owner"]["username"],
},
} }
if codebase is not None:
change['codebase'] = codebase
return [change]
def _transform_variables(payload):
retval = {
project: payload.get('project'),
repository = [payload.get('resource')],
branch = payload.get('language')
}
return retval
@defer.inlineCallbacks @defer.inlineCallbacks
def getChanges(self, request): def getChanges(self, request):
secret = None change = {}
self.secret = None
if isinstance(self.options, dict): if isinstance(self.options, dict):
secret = self.options.get('secret') self.secret = self.options.get('secret')
try: try:
content = request.content.read() content = request.content.read()
content_text = bytes2unicode(content) content_text = bytes2unicode(content)
@ -145,36 +111,19 @@ class TransifexHandler(BaseHookHandler):
except Exception as exception: except Exception as exception:
raise ValueError('Error loading JSON: ' + str(exception)) raise ValueError('Error loading JSON: ' + str(exception))
if self.secret is not None:
if secret is not None:
p = Properties() p = Properties()
p.master = self.master p.master = self.master
rendered_secret = yield p.render(secret) option = self.options
rendered_secret = yield p.render(self.secret)
signature = hmac.new( signature = hmac.new(
unicode2bytes(rendered_secret), unicode2bytes(rendered_secret),
unicode2bytes(content_text.strip()), unicode2bytes(content_text.strip()),
digestmod=hashlib.sha256) digestmod=hashlib.sha256)
header_signature = bytes2unicode( header_signature = bytes2unicode(
request.getHeader(_HEADER_SIGNATURE)) request.getHeader(_HEADER_SIGNATURE))
self._verifyTransifexSignature(request, content, rendered_secret, signature, header_signature)
http_verb = 'POST' event_type = payload.get("event", "None")
http_url_path = request.headers('X-TX-Url')
http_gmt_date = request.headers('Date')
content_md5 = hashlib.md5(content).hexdigest()
msg = b'\n'.join([
http_verb, http_url_path, http_gmt_date, content_md5
])
tx_signature = base64.b64encode(
hmac.new(
key=rendered_secret,
msg=msg,
digestmod=hashlib.sha256
).digest()
)
if tx_signature() != header_signature:
raise ValueError('Invalid secret')
event_type = bytes2unicode(payload.get(_EVENT_KEY), "None")
log.msg("Received event '{}' from transifex".format(event_type)) log.msg("Received event '{}' from transifex".format(event_type))
codebase = "" codebase = ""
@ -188,6 +137,4 @@ class TransifexHandler(BaseHookHandler):
return (changes, 'transifex') return (changes, 'transifex')
# Plugin name
transifex = TransifexHandler transifex = TransifexHandler

View File

@ -6,32 +6,23 @@ from setuptools import setup
with open("README.md", "r") as fh: with open("README.md", "r") as fh:
long_description = fh.read() long_description = fh.read()
VERSION = "1.7.2" VERSION = "0.1"
setup(name='buildbot-gitea', setup(name='buildbot-transifex',
version=VERSION, version=VERSION,
description='buildbot plugin for integration with Gitea.', description='buildbot plugin for integration with transifex.',
author='Marvin Pohl', author='',
author_email='hello@lab132.com', author_email='',
url='https://github.com/lab132/buildbot-gitea', url='',
long_description=long_description, long_description='Transifex webhook',
long_description_content_type="text/markdown", long_description_content_type="text/markdown",
packages=['buildbot_gitea'], packages=['buildbot_transifex'],
install_requires=[ install_requires=[
"buildbot>=3.0.0" "buildbot>=3.0.0"
], ],
entry_points={ entry_points={
"buildbot.webhooks": [ "buildbot.webhooks": [
"gitea = buildbot_gitea.webhook:gitea" "transifex = buildbot_transifex.webhook:transifex"
],
"buildbot.steps": [
"Gitea = buildbot_gitea.step_source:Gitea"
],
"buildbot.reporters": [
"GiteaStatusPush = buildbot_gitea.reporter:GiteaStatusPush"
],
"buildbot.util": [
"GiteaAuth = buildbot_gitea.auth:GiteaAuth"
] ]
}, },
classifiers=[ classifiers=[