Pipedash
Resources

Plugin development

Adding a CI/CD provider to Pipedash. Covers the Plugin trait, metadata types, the crate layout, registration and the shared retry policy.

A provider in Pipedash is a Rust crate that implements the Plugin trait from pipedash-plugin-api. The trait has 21 methods. 7 are required and 14 have default bodies.

The Plugin trait

Plugin: Send + Sync uses #[async_trait].

MethodRequired or default
metadata(&self) -> &PluginMetadataRequired
initialize(&mut self, provider_id, config, http_client) -> PluginResult<()>Required
validate_credentials(&self) -> PluginResult<bool>Required
fetch_pipelines(&self) -> PluginResult<Vec<Pipeline>>Required
fetch_run_history(&self, pipeline_id, limit)Required
fetch_run_details(&self, pipeline_id, run_number)Required
trigger_pipeline(&self, params: TriggerParams) -> PluginResult<String>Required
fetch_available_pipelines(&self, params)Default: an empty response
fetch_organizations(&self)Default: an empty list
fetch_available_pipelines_filtered(&self, org, search, params)Default: filters the discovery response by exact organization and a case-insensitive match on name, ID or description
fetch_pipelines_paginated(&self, page, page_size)Default: slices the complete pipeline list
cancel_run(&self, pipeline_id, run_number)Default: returns NotSupported
fetch_workflow_parameters(&self, workflow_id)Default: an empty list
fetch_agents(&self)Default: returns NotSupported
fetch_artifacts(&self, run_id)Default: returns NotSupported
fetch_queues(&self)Default: returns NotSupported
get_migrations(&self) -> Vec<String>Default: an empty list
provider_type(&self) -> &strDefault: the provider_type from the metadata
get_field_options(&self, field_key, config)Default: an empty list
check_permissions(&self) -> PluginResult<PermissionStatus>Default: marks the permissions in the metadata as granted
get_feature_availability(&self, status)Default: compares each feature requirement with the granted permission names

Errors use PluginError, which has the variants AuthenticationFailed, ApiError, InvalidConfig, PipelineNotFound, ProviderNotSupported, NetworkError, SerializationError, DatabaseError, NotSupported and Internal.

Metadata types

metadata() returns a PluginMetadata. The plugin builds it once and stores it.

FieldType
nameString
provider_typeString
versionString
descriptionString
authorOption<String>
iconOption<String>
config_schemaConfigSchema
table_schemaTableSchema
capabilitiesPluginCapabilities
required_permissionsVec<Permission>, default empty
featuresVec<Feature>, default empty

PluginCapabilities has 7 Boolean flags, all false by default: pipelines, pipeline_runs, trigger, agents, artifacts, queues and custom_tables.

ConfigSchema holds a fields: Vec<ConfigField> list. The setup dialog renders one input per field.

ConfigField fieldType
keyString
labelString
descriptionOption<String>
field_typeConfigFieldType
requiredbool
default_valueOption<serde_json::Value>
optionsOption<Vec<String>>
validation_regexOption<String>
validation_messageOption<String>

ConfigFieldType has 7 values: Text, Password, TextArea, Boolean, Select, MultiSelect and Number.

The GitHub plugin builds its metadata like this:

pub fn create_metadata() -> PluginMetadata {
    PluginMetadata {
        name: "GitHub Actions".to_string(),
        provider_type: "github".to_string(),
        version: "0.1.0".to_string(),
        description: "Monitor and trigger GitHub Actions workflows".to_string(),
        author: Some("Pipedash Team".to_string()),
        icon: Some("https://cdn.simpleicons.org/github/white".to_string()),
        config_schema: create_config_schema(),
        table_schema: schema::create_table_schema(),
        capabilities: create_capabilities(),
        required_permissions: create_required_permissions(),
        features: create_features(),
    }
}

Crate layout

Each plugin lives in crates/pipedash-plugin-{name}/src/ and splits its code into these files. The GitHub crate also has a permissions.rs.

FileContent
schema.rsTable and column definitions for the provider
metadata.rsPlugin metadata, config schema and capabilities
plugin.rsThe Plugin trait implementation
client.rsThe API client for the provider
mapper.rsConversion between provider API data and domain models
types.rsProvider-specific types
config.rsConfig parsing helpers

Registration

A new plugin needs 4 changes:

  1. The root Cargo.toml lists the crate in members and in [workspace.dependencies].
  2. pipedash-core depends on the crate.
  3. The plugins module of pipedash-core registers it. The registry builder calls registry.register(Box::new(...)) for each plugin, and the plugin factory has a match arm on the provider_type string.
  4. The frontend holds any provider-specific UI.

PluginRegistry exposes register and is_registered.

Retry policy

RetryPolicy in pipedash-plugin-api retries an async operation. Its defaults are below.

FieldDefault
max_retries3
initial_delay100 ms
exponential_backofftrue, so the delay doubles after each failed attempt

The policy retries only NetworkError and ApiError. Any other error returns at once.

Next step

The existing plugins serve as references. The providers index lists them, and the contributing page covers how a change reaches the repository.