157 lines
4.1 KiB
Python
157 lines
4.1 KiB
Python
|
# -*- coding: utf-8 -*-
|
||
|
|
||
|
"""
|
||
|
(c) 2016 - Copyright Red Hat Inc
|
||
|
|
||
|
Authors:
|
||
|
Pierre-Yves Chibon <pingou@pingoured.fr>
|
||
|
|
||
|
"""
|
||
|
|
||
|
import flask_wtf as wtf
|
||
|
import sqlalchemy as sa
|
||
|
import wtforms
|
||
|
from sqlalchemy.orm import relation
|
||
|
from sqlalchemy.orm import backref
|
||
|
|
||
|
import pagure.lib
|
||
|
from pagure.hooks import BaseHook, RequiredIf
|
||
|
from pagure.lib.model import BASE, Project
|
||
|
from pagure import SESSION, APP
|
||
|
|
||
|
|
||
|
class PagureCITable(BASE):
|
||
|
""" Stores information about the CI linked to on a project.
|
||
|
|
||
|
Table -- hook_pagure_ci
|
||
|
"""
|
||
|
|
||
|
__tablename__ = 'hook_pagure_ci'
|
||
|
|
||
|
id = sa.Column(sa.Integer, primary_key=True)
|
||
|
project_id = sa.Column(
|
||
|
sa.Integer,
|
||
|
sa.ForeignKey(
|
||
|
'projects.id', onupdate='CASCADE', ondelete='CASCADE'),
|
||
|
nullable=False,
|
||
|
unique=True,
|
||
|
index=True)
|
||
|
pagure_ci_token = sa.Column(
|
||
|
sa.String(32),
|
||
|
nullable=True,
|
||
|
index=True)
|
||
|
ci_type = sa.Column(
|
||
|
sa.String(255),
|
||
|
nullable=True)
|
||
|
ci_url = sa.Column(
|
||
|
sa.String(255),
|
||
|
nullable=True,
|
||
|
unique=False)
|
||
|
active = sa.Column(sa.Boolean, nullable=False, default=False)
|
||
|
|
||
|
project = relation(
|
||
|
'Project', remote_side=[Project.id],
|
||
|
backref=backref(
|
||
|
'ci_hook', cascade="delete, delete-orphan",
|
||
|
single_parent=True, uselist=False)
|
||
|
)
|
||
|
|
||
|
|
||
|
tmpl = """
|
||
|
{% if repo | hasattr('ci_hook') and repo.ci_hook and
|
||
|
repo.ci_hook.pagure_ci_token %}
|
||
|
|
||
|
The token to be used by jenkins to trigger the build is:
|
||
|
<pre>
|
||
|
{{ repo.ci_hook.pagure_ci_token}}
|
||
|
</pre>
|
||
|
|
||
|
The URL to be used to POST the results of your build is:
|
||
|
<pre>
|
||
|
{{ (config['APP_URL'][:-1] if config['APP_URL'].endswith('/')
|
||
|
else config['APP_URL'])
|
||
|
+ url_for('api_ns.%s_ci_notification' % repo.ci_hook.ci_type,
|
||
|
repo=repo.name, username=username,
|
||
|
pagure_ci_token=repo.ci_hook.pagure_ci_token) }}
|
||
|
</pre>
|
||
|
|
||
|
{% else %}
|
||
|
Once this plugin has been activated, reload this tab or this page to access
|
||
|
the URL to which your CI service should send its info.
|
||
|
{% endif %}
|
||
|
"""
|
||
|
|
||
|
|
||
|
class PagureCiForm(wtf.Form):
|
||
|
''' Form to configure the CI hook. '''
|
||
|
ci_type = wtforms.SelectField(
|
||
|
'Type of CI service',
|
||
|
[RequiredIf('active')],
|
||
|
choices=[]
|
||
|
)
|
||
|
ci_url = wtforms.TextField(
|
||
|
'URL to the project on the CI service',
|
||
|
[RequiredIf('active'), wtforms.validators.Length(max=255)],
|
||
|
)
|
||
|
active = wtforms.BooleanField(
|
||
|
'Active',
|
||
|
[wtforms.validators.Optional()]
|
||
|
)
|
||
|
|
||
|
def __init__(self, *args, **kwargs):
|
||
|
""" Calls the default constructor with the normal argument but
|
||
|
uses the list of collection provided to fill the choices of the
|
||
|
drop-down list.
|
||
|
"""
|
||
|
super(PagureCiForm, self).__init__(*args, **kwargs)
|
||
|
|
||
|
types = APP.config.get('PAGURE_CI_SERVICES', [])
|
||
|
self.ci_type.choices = [
|
||
|
(ci_type, ci_type) for ci_type in types
|
||
|
]
|
||
|
|
||
|
|
||
|
class PagureCi(BaseHook):
|
||
|
''' Mail hooks. '''
|
||
|
|
||
|
name = 'Pagure CI'
|
||
|
description = 'Integrate continuous integration (CI) services into your '\
|
||
|
'pagure project, providing you notifications for every pull-request '\
|
||
|
'opened in the project.'
|
||
|
extra_info = tmpl
|
||
|
form = PagureCiForm
|
||
|
db_object = PagureCITable
|
||
|
backref = 'ci_hook'
|
||
|
form_fields = ['ci_type', 'ci_url', 'active']
|
||
|
|
||
|
@classmethod
|
||
|
def set_up(cls, project):
|
||
|
''' Install the generic post-receive hook that allow us to call
|
||
|
multiple post-receive hooks as set per plugin.
|
||
|
'''
|
||
|
pass
|
||
|
|
||
|
@classmethod
|
||
|
def install(cls, project, dbobj):
|
||
|
''' Method called to install the hook for a project.
|
||
|
|
||
|
:arg project: a ``pagure.model.Project`` object to which the hook
|
||
|
should be installed
|
||
|
|
||
|
'''
|
||
|
if not dbobj.pagure_ci_token:
|
||
|
dbobj.pagure_ci_token = pagure.lib.login.id_generator(32)
|
||
|
SESSION.commit()
|
||
|
|
||
|
@classmethod
|
||
|
def remove(cls, project):
|
||
|
''' Method called to remove the hook of a project.
|
||
|
|
||
|
:arg project: a ``pagure.model.Project`` object to which the hook
|
||
|
should be installed
|
||
|
|
||
|
'''
|
||
|
for hook in project.ci_hook:
|
||
|
hook.pagure_ci_token = None
|
||
|
SESSION.commit()
|