Plugins: usage and development

Enabling plugins

Every available plugin needs to be enabled for each project in which it should be used. For that, access the Administration interface, edit the project, and add the wanted plugin names to the "Enabled plugin list" field.

Declaring plugins in your Python package

SQUAD plugins are Python classes that are a subclass of squad.core.plugins.Plugin, and can be provided by any Python package installed in the system. To register the plugin with SQUAD, you need to use the "entry points" system. In the setup.py for your package, use the following:

setup(
    # ...
    packages='mypluginpackage'
    # ...
    entry_points={
        # ...
        'squad_plugins': [
            'myplugin1=mypluginpackage.Plugin1',
            'myplugin2=mypluginpackage.Plugin2',
        ]
    },
    # ...
)

Now, the plugin itself can be implemented in mypluginpackage.py, like this:

from squad.core.plugins import Plugin

class Plugin1(Plugin):
    # implementation of the plugin methods ...

class Plugin2(Plugin):
    # implementation of the plugin methods ...

The next next section, "The plugin API" documents which methods can be defined in your plugin class in order to provide extra functionality to the SQUAD core.

The plugin API

class squad.core.plugins.Plugin[source]

This can be used to pass extra arguments to plugins

extra_args = {}

This class must be used as a superclass for all SQUAD plugins. All the methods declared here have empty implementations (i.e. they do nothing), and should be overriden in your plugin to provide extra functionality to the SQUAD core.

get_url(object_id)[source]

This method might return service specific URL with given object_id

has_subtasks()[source]

This method tells whether or not the plugin will use subtasks to complete work, meaning that the main function will return but more results are still working in parallel.

notify_patch_build_created(build)[source]

This method is called when a patch build is created. It should notify the corresponding patch source that the checks are in progress.

The build argument is an instance of squad.core.Build.

notify_patch_build_finished(build)[source]

This method is called when a patch build is finished. It should notify the patch source about the status of the tests (success, failure, etc).

The build argument is an instance of squad.core.Build.

postprocess_testjob(testjob)[source]

This method is called after a test job has been fetched by SQUAD, and the test run data (tests, metrics, metadata, logs, etc) have been saved to the database.

You can use this method to do any processing that is specific to a given CI backend (e.g. LAVA).

The testjob arguments is an instance of squad.ci.models.TestJob.

postprocess_testrun(testrun)[source]

This method is called after a test run has been received by SQUAD, and the test run data (tests, metrics, metadata, logs, etc) have been saved to the database.

You can use this method to parse logs, do any special handling of metadata, test results, etc.

The testrun arguments is an instance of squad.core.models.TestRun.

Adding plugin usage to the SQUAD core

Code from the SQUAD core that wants to invoke functionality from plugins should use the apply_plugins function.

squad.core.plugins.apply_plugins(plugin_names)[source]

This function should be used by code in the SQUAD core to trigger functionality from plugins.

The plugin_names argument is list of plugins names to be used. Most probably, you will want to pass the list of plugins enabled for a given project, e.g. project.enabled_plugins.

Example:

from squad.core.plugins import apply_plugins

# ...

for plugin in apply_plugins(project.enabled_plugins):
    plugin.method(...)

Full plugin package example

This section presents a minimal, working example of a Python package that provides one SQUAD plugin. It is made of only two files: setup.py and examplepluginpackage/__init__.py.

setup.py:

from setuptools import setup, find_packages

setup(
    name='examplepluginpackage',
    version='1.0',
    author='Plugin Writer',
    author_email='plugin.writer@example.com',
    url='https://example.com/examplepluginpackage',
    packages=find_packages(),
    include_package_data=True,
    entry_points={
        'squad_plugins': [
            'externalplugin=examplepluginpackage:MyPlugin',
        ]
    },
    license='GPLv3+',
    description="An example Plugin pacakge",
    long_description="""
    The Example Plugin package is a sample plugin for SQUAD that
    shows how to write SQUAD plugins
    """,
    platforms='any',
)

examplepluginpackage/__init__.py:

from squad.core.plugins import Plugin

class MyPlugin(Plugin):

    def postprocess_testrun(self, testrun):
    # do something interesting with the the testrun ...
        pass

Built-in notification plugins

SQUAD comes with two bult-in plugins available for immediate use.

Github

The Github plugin allows patches (Pull Requests) originated from Github to be notified whenever a build has been created or finished.

Here is an example API call that supposedly came from a Jenkins job, triggered by a freshly opened Github Pull Request:

$ curl \
    -X POST \
    --header "Authorization: token $SQUAD_TOKEN" \
    -d patch_source=your-github-patch-source \
    -d patch_baseline=build-v1 \
    -d patch_id=the_owner/the_repo/8223a534d7bf \
    https://squad.example.com/api/createbuild/my-group/my-project/build-v2
Where:
  • patch_source is the name of a "Patch Source" previously added in squad in "Administration > Core > Patch sources > Add patch source", where you should select "github" for "implementation". NOTE the Github plugin requires a token for authentication, so please ignore the "password" field.

  • patch_baseline is an optional parameter that indicated that the build being created is a new version of "patch_baseline" build.

  • patch_id is a string in a form like "owner/repository/commit" of the respective Github repository.

If everything was successfully submitted, you should see a notification in the Github page for that Pull Request. Subsequent tests on that build are going to be performed and as SQUAD detects that all tests are done, another notification should be sent out on that Pull Request, informing that the build is finished.

Gerrit

The Gerrit plugin allows changes originated from a Gerrit instance to be notified whenever a build has been created or finished.

Here is an example API call that supposedly came from a Jenkins job, triggered by a freshly created change:

$ curl \
    -X POST \
    --header "Authorization: token $SQUAD_TOKEN" \
    -d patch_source=your-gerrit-patch-source \
    -d patch_baseline=build-v1 \
    -d patch_id=change-id/patchset \
    https://squad.example.com/api/createbuild/my-group/my-project/build-v2
Where:
  • patch_source is the name of a "Patch Source" previously added in squad in "Administration > Core > Patch sources > Add patch source", where you should select "gerrit" for "implementation". NOTE 1 the Gerrit plugin requires a password (configured as HTTP Password in Gerrit) for authentication, so please ignore the "token" field. NOTE 2 the Gerrit plugin also allows SSH based notifications by using "ssh://" instead of "https://" in the "url" field. NOTE 3 SSH connections are made only through key exchange, so please set it up before attempting to use this feature

  • patch_baseline is an optional parameter that indicated that the build being created is a new version of "patch_baseline" build.

  • patch_id is a string in a form like "change-id/patchset" of the respective Gerrit repository.

NOTE

By default, the plugin will only apply "Code-Review -1" for builds that errored. Custom labels are supported if specified in project settings. Here is a example on how to specify custom labels for gerrit:

plugins:
  gerrit:
    build_finished:
      success:
        Code-Review: "+1"
        Validation-Bot-Review: "+1"
      error:
        Code-Review: "-1"
        My-Custom-Bot-Review: "-1"

If everything was successfully submitted, you should see a notification in the Gerrit page for that Change. Subsequent tests on that build are going to be performed and as SQUAD detects that all tests are done, another notification should be sent out on that Change, informing that the build is finished.