relicta-plugin-sdk

module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 17, 2025 License: MIT

README

Relicta Plugin SDK

Official SDK for building Relicta plugins.

Overview

Relicta plugins extend the release workflow with custom functionality. Plugins can:

  • Create releases on platforms (GitHub, GitLab, etc.)
  • Send notifications (Slack, Discord, etc.)
  • Update issue trackers (Jira, Linear, etc.)
  • Upload artifacts
  • Run custom automation

Quick Start

1. Create a new plugin
mkdir my-plugin && cd my-plugin
go mod init github.com/yourname/relicta-plugin-myplugin
go get github.com/relicta-tech/relicta-plugin-sdk
2. Implement the Plugin interface
package main

import (
    "context"
    "github.com/relicta-tech/relicta-plugin-sdk/plugin"
)

func main() {
    plugin.Serve(&MyPlugin{})
}

type MyPlugin struct{}

func (p *MyPlugin) GetInfo() plugin.Info {
    return plugin.Info{
        Name:        "my-plugin",
        Version:     "1.0.0",
        Description: "My custom plugin",
        Author:      "Your Name",
        Hooks:       []plugin.Hook{plugin.HookPostPublish},
    }
}

func (p *MyPlugin) Execute(ctx context.Context, req plugin.ExecuteRequest) (*plugin.ExecuteResponse, error) {
    // Your plugin logic here
    return &plugin.ExecuteResponse{
        Success: true,
        Message: "Done!",
    }, nil
}

func (p *MyPlugin) Validate(ctx context.Context, config map[string]any) (*plugin.ValidateResponse, error) {
    return &plugin.ValidateResponse{Valid: true}, nil
}
3. Build and install
go build -o my-plugin
relicta plugin install ./my-plugin
relicta plugin enable my-plugin

Available Hooks

Plugins can respond to these workflow hooks:

Hook When it runs
pre-init Before initialization
post-init After initialization
pre-plan Before analyzing changes
post-plan After analyzing changes
pre-version Before version bump
post-version After version bump
pre-notes Before generating notes
post-notes After generating notes
pre-approve Before approval
post-approve After approval
pre-publish Before publishing
post-publish After publishing
on-success When release succeeds
on-error When release fails

Configuration

Plugins receive configuration from relicta.config.yaml:

plugins:
  - name: my-plugin
    enabled: true
    config:
      api_key: ${MY_API_KEY}
      webhook_url: https://example.com/webhook

Access configuration in your plugin:

func (p *MyPlugin) Execute(ctx context.Context, req plugin.ExecuteRequest) (*plugin.ExecuteResponse, error) {
    cfg := helpers.NewConfigParser(req.Config)

    // Get with environment variable fallback
    apiKey := cfg.GetString("api_key", "MY_API_KEY", "")

    // Get with default value
    timeout := cfg.GetInt("timeout", 30)

    // ...
}

Helper Utilities

The SDK includes helpers for common tasks:

Config Parser
import "github.com/relicta-tech/relicta-plugin-sdk/helpers"

cfg := helpers.NewConfigParser(req.Config)

// String with env fallback
token := cfg.GetString("token", "GITHUB_TOKEN", "")

// Boolean with default
draft := cfg.GetBool("draft", false)

// String slice
assets := cfg.GetStringSlice("assets", nil)

// Unmarshal to struct
var myConfig MyConfig
cfg.Unmarshal(&myConfig)
Validation Builder
func (p *MyPlugin) Validate(ctx context.Context, config map[string]any) (*plugin.ValidateResponse, error) {
    v := helpers.NewValidationBuilder()

    // Require fields (with optional env fallback)
    v.RequireString(config, "api_key", "MY_API_KEY")

    // Validate URL format
    v.ValidateURL(config, "webhook_url")

    // Validate against allowed values
    v.ValidateOneOf(config, "level", []string{"info", "warn", "error"})

    // Custom validation
    if cfg, ok := config["max_retries"]; ok {
        if n, ok := cfg.(float64); ok && n < 0 {
            v.AddError("max_retries", "must be non-negative")
        }
    }

    return v.Build(), nil
}
Asset Validation
// Validate file paths are safe
for _, path := range cfg.GetStringSlice("assets", nil) {
    if err := helpers.ValidateAssetPath(path); err != nil {
        return nil, err
    }
}

// Expand glob patterns
files, err := helpers.ExpandGlob("dist/*.tar.gz")

Release Context

Plugins receive rich context about the release:

func (p *MyPlugin) Execute(ctx context.Context, req plugin.ExecuteRequest) (*plugin.ExecuteResponse, error) {
    ctx := req.Context

    // Version info
    ctx.Version          // "1.2.3"
    ctx.PreviousVersion  // "1.2.2"
    ctx.TagName          // "v1.2.3"
    ctx.ReleaseType      // "minor"

    // Repository info
    ctx.RepositoryOwner  // "relicta-tech"
    ctx.RepositoryName   // "relicta"
    ctx.Branch           // "main"
    ctx.CommitSHA        // "abc123..."

    // Generated content
    ctx.Changelog        // Full changelog markdown
    ctx.ReleaseNotes     // Public release notes

    // Categorized changes
    ctx.Changes.Features // []ConventionalCommit
    ctx.Changes.Fixes
    ctx.Changes.Breaking

    // Filtered environment
    ctx.Environment      // Safe env vars
}

Dry Run Mode

Plugins should respect dry-run mode:

func (p *MyPlugin) Execute(ctx context.Context, req plugin.ExecuteRequest) (*plugin.ExecuteResponse, error) {
    if req.DryRun {
        return &plugin.ExecuteResponse{
            Success: true,
            Message: "Would create release (dry-run)",
        }, nil
    }

    // Actual implementation...
}

Artifacts

Plugins can report created artifacts:

return &plugin.ExecuteResponse{
    Success: true,
    Artifacts: []plugin.Artifact{
        {
            Name:     "release.tar.gz",
            Path:     "https://github.com/.../release.tar.gz",
            Type:     "url",
            Size:     1024000,
            Checksum: "sha256:abc123...",
        },
    },
}, nil

Testing

Use ServeTest for integration testing:

func TestMyPlugin(t *testing.T) {
    reattach, cleanup := plugin.ServeTest(&MyPlugin{})
    defer cleanup()

    // Create client and test...
}

Examples

See the examples directory for complete plugin implementations:

  • hello - Minimal example plugin

Protocol Version

The SDK uses protocol version 1. Plugins built with incompatible protocol versions will fail to load.

import "github.com/relicta-tech/relicta-plugin-sdk/plugin"

fmt.Println(plugin.ProtocolVersion) // 1
fmt.Println(plugin.Version)         // "1.0.0"

License

MIT License - see LICENSE for details.

Directories

Path Synopsis
examples
hello command
Package main demonstrates a simple Relicta plugin.
Package main demonstrates a simple Relicta plugin.
Package helpers provides utility functions for building Relicta plugins.
Package helpers provides utility functions for building Relicta plugins.
Package plugin provides the interface and types for building Relicta plugins.
Package plugin provides the interface and types for building Relicta plugins.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL