Zum Inhalt springen

Plugin-SDK

Das Plugin-SDK (github.com/GoSemantics/semrel-plugins) stellt die erzeugten Protobuf-Typen und Hilfsgerüste für das Schreiben von semrel-Plugins in Go bereit. Plugins in anderen Sprachen können die rohe .proto-Datei aus dem Haupt-Repository verwenden.

  • Go ≥ 1.24
  • Vertrautheit mit gRPC und Protobuf
  1. Erstelle ein neues Modul

    Terminal-Fenster
    mkdir my-semrel-plugin
    cd my-semrel-plugin
    go mod init github.com/myorg/my-semrel-plugin
    go get github.com/GoSemantics/semrel-plugins
  2. Implementiere die Plugin-Schnittstelle

    Jeder Plugin-Typ entspricht einem gRPC-Service, der in semantic_release.proto definiert ist.

    Das folgende Beispiel implementiert ein CommitAnalyzerPlugin, das für jeden feat:-Commit auf minor erhöht und für alles andere patch verwendet:

    package main
    import (
    "context"
    "strings"
    semrelv1 "github.com/GoSemantics/semrel-plugins/gen/v1"
    )
    type myAnalyzer struct {
    semrelv1.UnimplementedCommitAnalyzerPluginServer
    }
    func (a *myAnalyzer) AnalyzeCommits(
    ctx context.Context,
    req *semrelv1.AnalyzeCommitsRequest,
    ) (*semrelv1.AnalyzeCommitsResponse, error) {
    bump := semrelv1.BumpLevel_BUMP_LEVEL_NONE
    for _, c := range req.Ctx.Commits {
    msg := c.RawMessage
    if strings.Contains(msg, "BREAKING CHANGE") {
    return &semrelv1.AnalyzeCommitsResponse{
    Bump: semrelv1.BumpLevel_BUMP_LEVEL_MAJOR,
    Reason: "breaking change detected",
    }, nil
    }
    if strings.HasPrefix(msg, "feat") {
    bump = semrelv1.BumpLevel_BUMP_LEVEL_MINOR
    } else if strings.HasPrefix(msg, "fix") && bump < semrelv1.BumpLevel_BUMP_LEVEL_MINOR {
    bump = semrelv1.BumpLevel_BUMP_LEVEL_PATCH
    }
    }
    return &semrelv1.AnalyzeCommitsResponse{Bump: bump}, nil
    }
  3. Über go-plugin bereitstellen

    Verwende plugin.Serve() – go-plugin verwaltet das Handshake-Protokoll über stdout automatisch. Nutze hclog für alle Logs, damit die Ausgabe nach stderr geht:

    package main
    import (
    "os"
    hclog "github.com/hashicorp/go-hclog"
    goplugin "github.com/hashicorp/go-plugin"
    semrelv1 "github.com/GoSemantics/semrel-plugins/gen/v1"
    )
    func main() {
    logger := hclog.New(&hclog.LoggerOptions{
    Name: "my-analyzer",
    Output: os.Stderr, // MUST be stderr — stdout is reserved for go-plugin handshake
    Level: hclog.Info,
    })
    goplugin.Serve(&goplugin.ServeConfig{
    HandshakeConfig: semrelv1.HandshakeConfig,
    Plugins: map[string]goplugin.Plugin{
    "commit-analyzer": &semrelv1.CommitAnalyzerPlugin{Impl: &myAnalyzer{}},
    },
    GRPCServer: goplugin.DefaultGRPCServer,
    Logger: logger,
    })
    }
  4. Baue und installiere das Plugin

    Terminal-Fenster
    go build -o .semrel/my-analyzer .
  5. Registriere es in .semrel.yaml

    plugins:
    - name: my-analyzer
    path: ./.semrel/my-analyzer

Eine einzelne Plugin-Binärdatei kann mehrere gRPC-Services auf demselben Server registrieren:

semrelv1.RegisterCommitAnalyzerPluginServer(srv, &myAnalyzer{})
semrelv1.RegisterChangelogGeneratorPluginServer(srv, &myChangelog{})

Jeder RPC erhält in seiner Anfrage einen ReleaseContext. Er enthält:

FeldTypBeschreibung
repo_owner / repo_namestringRepository-Identität
branchstringDie veröffentlichte Branch
last_versionSemanticVersionVorheriges Release-Tag
next_versionSemanticVersionBerechnete nächste Version
commits[]CommitCommits seit der letzten Release
dry_runboolWenn true, dürfen keine Seiteneffekte angewendet werden
configmap<string, string>Plugin-args aus .semrel.yaml