mirror of
https://github.com/odoo/runbot.git
synced 2025-03-27 13:25:47 +07:00
[ADD] runbot_cla
remove useless status in runbot add author and committer email clean up repo form view add runbot cla module
This commit is contained in:
parent
8b7c17ca68
commit
de54d4a78c
@ -182,7 +182,7 @@ class runbot_repo(osv.osv):
|
|||||||
'jobs': fields.char('Jobs'),
|
'jobs': fields.char('Jobs'),
|
||||||
'nginx': fields.boolean('Nginx'),
|
'nginx': fields.boolean('Nginx'),
|
||||||
'auto': fields.boolean('Auto'),
|
'auto': fields.boolean('Auto'),
|
||||||
'duplicate_id': fields.many2one('runbot.repo', 'Repository for finding duplicate builds'),
|
'duplicate_id': fields.many2one('runbot.repo', 'Duplicate repo', help='Repository for finding duplicate builds'),
|
||||||
'modules': fields.char("Modules to Install", help="Comma-separated list of modules to install and test."),
|
'modules': fields.char("Modules to Install", help="Comma-separated list of modules to install and test."),
|
||||||
'dependency_ids': fields.many2many(
|
'dependency_ids': fields.many2many(
|
||||||
'runbot.repo', 'runbot_repo_dep_rel',
|
'runbot.repo', 'runbot_repo_dep_rel',
|
||||||
@ -221,26 +221,28 @@ class runbot_repo(osv.osv):
|
|||||||
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
|
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
|
||||||
p2.communicate()[0]
|
p2.communicate()[0]
|
||||||
|
|
||||||
def github(self, cr, uid, ids, url, payload=None, delete=False, context=None):
|
def github(self, cr, uid, ids, url, payload=None, ignore_errors=False, context=None):
|
||||||
"""Return a http request to be sent to github"""
|
"""Return a http request to be sent to github"""
|
||||||
for repo in self.browse(cr, uid, ids, context=context):
|
for repo in self.browse(cr, uid, ids, context=context):
|
||||||
if not repo.token:
|
try:
|
||||||
raise Exception('Repository does not have a token to authenticate')
|
match_object = re.search('([^/]+)/([^/]+)/([^/.]+(.git)?)', repo.base)
|
||||||
match_object = re.search('([^/]+)/([^/]+)/([^/.]+(.git)?)', repo.base)
|
if match_object:
|
||||||
if match_object:
|
url = url.replace(':owner', match_object.group(2))
|
||||||
url = url.replace(':owner', match_object.group(2))
|
url = url.replace(':repo', match_object.group(3))
|
||||||
url = url.replace(':repo', match_object.group(3))
|
url = 'https://api.%s%s' % (match_object.group(1),url)
|
||||||
url = 'https://api.%s%s' % (match_object.group(1),url)
|
session = requests.Session()
|
||||||
session = requests.Session()
|
session.auth = (repo.token,'x-oauth-basic')
|
||||||
session.auth = (repo.token,'x-oauth-basic')
|
session.headers.update({'Accept': 'application/vnd.github.she-hulk-preview+json'})
|
||||||
session.headers.update({'Accept': 'application/vnd.github.she-hulk-preview+json'})
|
if payload:
|
||||||
if payload:
|
response = session.post(url, data=simplejson.dumps(payload))
|
||||||
response = session.post(url, data=simplejson.dumps(payload))
|
else:
|
||||||
elif delete:
|
response = session.get(url)
|
||||||
response = session.delete(url)
|
return response.json()
|
||||||
|
except Exception:
|
||||||
|
if ignore_errors:
|
||||||
|
_logger.exception('Ignored github error %s %r', url, payload)
|
||||||
else:
|
else:
|
||||||
response = session.get(url)
|
raise
|
||||||
return response.json()
|
|
||||||
|
|
||||||
def update(self, cr, uid, ids, context=None):
|
def update(self, cr, uid, ids, context=None):
|
||||||
for repo in self.browse(cr, uid, ids, context=context):
|
for repo in self.browse(cr, uid, ids, context=context):
|
||||||
@ -261,14 +263,14 @@ class runbot_repo(osv.osv):
|
|||||||
repo.git(['fetch', '-p', 'origin', '+refs/heads/*:refs/heads/*'])
|
repo.git(['fetch', '-p', 'origin', '+refs/heads/*:refs/heads/*'])
|
||||||
repo.git(['fetch', '-p', 'origin', '+refs/pull/*/head:refs/pull/*'])
|
repo.git(['fetch', '-p', 'origin', '+refs/pull/*/head:refs/pull/*'])
|
||||||
|
|
||||||
fields = ['refname','objectname','committerdate:iso8601','authorname','subject','committername']
|
fields = ['refname','objectname','committerdate:iso8601','authorname','authoremail','subject','committername','committeremail']
|
||||||
fmt = "%00".join(["%("+field+")" for field in fields])
|
fmt = "%00".join(["%("+field+")" for field in fields])
|
||||||
git_refs = repo.git(['for-each-ref', '--format', fmt, '--sort=-committerdate', 'refs/heads', 'refs/pull'])
|
git_refs = repo.git(['for-each-ref', '--format', fmt, '--sort=-committerdate', 'refs/heads', 'refs/pull'])
|
||||||
git_refs = git_refs.strip()
|
git_refs = git_refs.strip()
|
||||||
|
|
||||||
refs = [[decode_utf(field) for field in line.split('\x00')] for line in git_refs.split('\n')]
|
refs = [[decode_utf(field) for field in line.split('\x00')] for line in git_refs.split('\n')]
|
||||||
|
|
||||||
for name, sha, date, author, subject, committer in refs:
|
for name, sha, date, author, author_email, subject, committer, committer_email in refs:
|
||||||
# create or get branch
|
# create or get branch
|
||||||
branch_ids = Branch.search(cr, uid, [('repo_id', '=', repo.id), ('name', '=', name)])
|
branch_ids = Branch.search(cr, uid, [('repo_id', '=', repo.id), ('name', '=', name)])
|
||||||
if branch_ids:
|
if branch_ids:
|
||||||
@ -292,7 +294,9 @@ class runbot_repo(osv.osv):
|
|||||||
'branch_id': branch.id,
|
'branch_id': branch.id,
|
||||||
'name': sha,
|
'name': sha,
|
||||||
'author': author,
|
'author': author,
|
||||||
|
'author_email': author_email,
|
||||||
'committer': committer,
|
'committer': committer,
|
||||||
|
'committer_email': committer_email,
|
||||||
'subject': subject,
|
'subject': subject,
|
||||||
'date': dateutil.parser.parse(date[:19]),
|
'date': dateutil.parser.parse(date[:19]),
|
||||||
'modules': ','.join(filter(None, [branch.repo_id.modules, branch.modules])),
|
'modules': ','.join(filter(None, [branch.repo_id.modules, branch.modules])),
|
||||||
@ -468,7 +472,9 @@ class runbot_build(osv.osv):
|
|||||||
'domain': fields.function(_get_domain, type='char', string='URL'),
|
'domain': fields.function(_get_domain, type='char', string='URL'),
|
||||||
'date': fields.datetime('Commit date'),
|
'date': fields.datetime('Commit date'),
|
||||||
'author': fields.char('Author'),
|
'author': fields.char('Author'),
|
||||||
|
'author_email': fields.char('Author Email'),
|
||||||
'committer': fields.char('Committer'),
|
'committer': fields.char('Committer'),
|
||||||
|
'committer_email': fields.char('Committer Email'),
|
||||||
'subject': fields.text('Subject'),
|
'subject': fields.text('Subject'),
|
||||||
'sequence': fields.integer('Sequence', select=1),
|
'sequence': fields.integer('Sequence', select=1),
|
||||||
'modules': fields.char("Modules to Install"),
|
'modules': fields.char("Modules to Install"),
|
||||||
@ -505,8 +511,6 @@ class runbot_build(osv.osv):
|
|||||||
if len(duplicate_ids):
|
if len(duplicate_ids):
|
||||||
extra_info.update({'state': 'duplicate', 'duplicate_id': duplicate_ids[0]})
|
extra_info.update({'state': 'duplicate', 'duplicate_id': duplicate_ids[0]})
|
||||||
self.write(cr, uid, [duplicate_ids[0]], {'duplicate_id': build_id})
|
self.write(cr, uid, [duplicate_ids[0]], {'duplicate_id': build_id})
|
||||||
if self.browse(cr, uid, duplicate_ids[0]).state != 'pending':
|
|
||||||
self.github_status(cr, uid, [build_id])
|
|
||||||
self.write(cr, uid, [build_id], extra_info, context=context)
|
self.write(cr, uid, [build_id], extra_info, context=context)
|
||||||
|
|
||||||
def reset(self, cr, uid, ids, context=None):
|
def reset(self, cr, uid, ids, context=None):
|
||||||
@ -734,36 +738,27 @@ class runbot_build(osv.osv):
|
|||||||
"""Notify github of failed/successful builds"""
|
"""Notify github of failed/successful builds"""
|
||||||
runbot_domain = self.pool['runbot.repo'].domain(cr, uid)
|
runbot_domain = self.pool['runbot.repo'].domain(cr, uid)
|
||||||
for build in self.browse(cr, uid, ids, context=context):
|
for build in self.browse(cr, uid, ids, context=context):
|
||||||
if build.state != 'duplicate' and build.duplicate_id:
|
|
||||||
self.github_status(cr, uid, [build.duplicate_id.id], context=context)
|
|
||||||
desc = "runbot build %s" % (build.dest,)
|
desc = "runbot build %s" % (build.dest,)
|
||||||
real_build = build.duplicate_id if build.state == 'duplicate' else build
|
if build.state in ('running', 'done'):
|
||||||
if real_build.state == 'testing':
|
state = 'error'
|
||||||
state = 'pending'
|
if build.result == 'ok':
|
||||||
elif real_build.state in ('running', 'done'):
|
state = 'sucess'
|
||||||
state = {
|
if build.result == 'ko':
|
||||||
'ok': 'success',
|
state = 'failure'
|
||||||
'killed': 'error',
|
|
||||||
}.get(real_build.result, 'failure')
|
|
||||||
desc += " (runtime %ss)" % (real_build.job_time,)
|
desc += " (runtime %ss)" % (real_build.job_time,)
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
status = {
|
status = {
|
||||||
"state": state,
|
"state": state,
|
||||||
"target_url": "http://%s/runbot/build/%s" % (runbot_domain, build.id),
|
"target_url": "http://%s/runbot/build/%s" % (runbot_domain, build.id),
|
||||||
"description": desc,
|
"description": desc,
|
||||||
"context": "continuous-integration/runbot"
|
"context": "continuous-integration/runbot"
|
||||||
}
|
}
|
||||||
try:
|
_logger.debug("github updating status %s to %s", build.name, state)
|
||||||
build.repo_id.github('/repos/:owner/:repo/statuses/%s' % build.name, status)
|
build.repo_id.github('/repos/:owner/:repo/statuses/%s' % build.name, status, ignore_errors=True)
|
||||||
_logger.debug("github status %s update to %s", build.name, state)
|
|
||||||
except Exception:
|
|
||||||
_logger.exception("github status error")
|
|
||||||
|
|
||||||
def job_10_test_base(self, cr, uid, build, lock_path, log_path):
|
def job_10_test_base(self, cr, uid, build, lock_path, log_path):
|
||||||
build._log('test_base', 'Start test base module')
|
build._log('test_base', 'Start test base module')
|
||||||
build.github_status()
|
|
||||||
# checkout source
|
# checkout source
|
||||||
build.checkout()
|
build.checkout()
|
||||||
# run base test
|
# run base test
|
||||||
@ -966,6 +961,7 @@ class runbot_build(osv.osv):
|
|||||||
|
|
||||||
def _log(self, cr, uid, ids, func, message, context=None):
|
def _log(self, cr, uid, ids, func, message, context=None):
|
||||||
assert len(ids) == 1
|
assert len(ids) == 1
|
||||||
|
_logger.debug("Build %s %s %s", ids[0], func, message)
|
||||||
self.pool['ir.logging'].create(cr, uid, {
|
self.pool['ir.logging'].create(cr, uid, {
|
||||||
'build_id': ids[0],
|
'build_id': ids[0],
|
||||||
'level': 'INFO',
|
'level': 'INFO',
|
||||||
@ -1269,8 +1265,6 @@ class RunbotController(http.Controller):
|
|||||||
return request.not_found()
|
return request.not_found()
|
||||||
return werkzeug.utils.redirect(url)
|
return werkzeug.utils.redirect(url)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# kill ` ps faux | grep ./static | awk '{print $2}' `
|
# kill ` ps faux | grep ./static | awk '{print $2}' `
|
||||||
# ps faux| grep Cron | grep -- '-all' | awk '{print $2}' | xargs kill
|
# ps faux| grep Cron | grep -- '-all' | awk '{print $2}' | xargs kill
|
||||||
# psql -l | grep " 000" | awk '{print $1}' | xargs -n1 dropdb
|
# psql -l | grep " 000" | awk '{print $1}' | xargs -n1 dropdb
|
||||||
|
@ -24,9 +24,7 @@
|
|||||||
<field name="jobs"/>
|
<field name="jobs"/>
|
||||||
<field name="nginx"/>
|
<field name="nginx"/>
|
||||||
<field name="duplicate_id"/>
|
<field name="duplicate_id"/>
|
||||||
<field name="dependency_ids">
|
<field name="dependency_ids" widget="many2many_tags"/>
|
||||||
<tree><field name="name"/></tree>
|
|
||||||
</field>
|
|
||||||
<field name="modules"/>
|
<field name="modules"/>
|
||||||
<field name="token"/>
|
<field name="token"/>
|
||||||
</group>
|
</group>
|
||||||
@ -122,7 +120,9 @@
|
|||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
<field name="date"/>
|
<field name="date"/>
|
||||||
<field name="author"/>
|
<field name="author"/>
|
||||||
|
<field name="author_email"/>
|
||||||
<field name="committer"/>
|
<field name="committer"/>
|
||||||
|
<field name="committer_email"/>
|
||||||
<field name="subject"/>
|
<field name="subject"/>
|
||||||
<field name="port"/>
|
<field name="port"/>
|
||||||
<field name="dest"/>
|
<field name="dest"/>
|
||||||
|
1
runbot_cla/__init__.py
Normal file
1
runbot_cla/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
import runbot
|
10
runbot_cla/__openerp__.py
Normal file
10
runbot_cla/__openerp__.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
'name': 'Runbot CLA',
|
||||||
|
'category': 'Website',
|
||||||
|
'summary': 'Runbot CLA',
|
||||||
|
'version': '1.1',
|
||||||
|
'description': "Runbot CLA",
|
||||||
|
'author': 'Odoo SA',
|
||||||
|
'depends': ['runbot'],
|
||||||
|
'data': [ ],
|
||||||
|
}
|
38
runbot_cla/runbot.py
Normal file
38
runbot_cla/runbot.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
|
import glob
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
import openerp
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class runbot_build(openerp.models.Model):
|
||||||
|
_inherit = "runbot.build"
|
||||||
|
|
||||||
|
def job_15_check_cla(self, cr, uid, build, lock_path, log_path):
|
||||||
|
cla_glob = build.path("doc/cla/*/*.md")
|
||||||
|
if cla_glob:
|
||||||
|
cla = ''.join(open(f).read() for f in glob.glob(cla_glob))
|
||||||
|
cla = cla.lower()
|
||||||
|
mo = re.search('[^ <@]+@[^ @>]+', build.author_email or '')
|
||||||
|
state = "failure"
|
||||||
|
if mo:
|
||||||
|
email = mo.group(0).lower()
|
||||||
|
if re.match('.*(odoo|openerp|tinyerp).com$',email):
|
||||||
|
state = "success"
|
||||||
|
if cla.find(mo.group(0).lower()) != -1:
|
||||||
|
state = "success"
|
||||||
|
status = {
|
||||||
|
"state": state,
|
||||||
|
"target_url": "http://www.odoo.com/sign-cla",
|
||||||
|
"description": "Odoo CLA",
|
||||||
|
"context": "legal/cla"
|
||||||
|
}
|
||||||
|
build._log('check_cla', 'Check CLA %s' % state)
|
||||||
|
build.repo_id.github('/repos/:owner/:repo/statuses/%s' % build.name, status, ignore_errors=True)
|
||||||
|
# 0 is myself, -1 is everybody else, -2 nothing
|
||||||
|
return -2
|
||||||
|
|
Loading…
Reference in New Issue
Block a user