# 10 · Plug‑in SDK Guide — **Stella Ops** *(v 1.5 — 11 Jul 2025 · template install, no reload, IoC)* --- ## 0 Audience & Scope Guidance for developers who extend Stella Ops with schedule jobs, scanner adapters, TLS providers, notification channels, etc. Everything here is OSS; commercial variants simply ship additional signed plug‑ins. --- ## 1 Prerequisites | Tool | Min Version | | ----------------------- | ----------------------------------------------------------------- | | .NET SDK | 9.0.200 | | **StellaOps templates** | install once via `bash dotnet new install StellaOps.Templates::*` | | **Cosign** | 2.3 + — used to sign DLLs | | xUnit | 2.6 | | Docker CLI | only if your plug‑in shells out to containers | --- ## 2 Repository & Build Output Every plug‑in is hosted in **`git.stella‑ops.org`**. At publish time it must copy its signed artefacts to: ~~~text src/backend/Stella.Ops.Plugin.Binaries// ├── MyPlugin.dll └── MyPlugin.dll.sig ~~~ The back‑end scans this folder on start‑up, verifies the **Cosign** signature, confirms the `[StellaPluginVersion]` gate, then loads the DLL inside an **isolated AssemblyLoadContext** to avoid dependency clashes --- ## 3 Project Scaffold Generate with the installed template: ~~~bash dotnet new stellaops-plugin-schedule \ -n MyPlugin.Schedule \ --output src ~~~ Result: ~~~text src/ ├─ MyPlugin.Schedule/ │ ├─ MyJob.cs │ └─ MyPlugin.Schedule.csproj └─ tests/ └─ MyPlugin.Schedule.Tests/ ~~~ --- ## 4 MSBuild Wiring Add this to **`MyPlugin.Schedule.csproj`** so the signed DLL + `.sig` land in the canonical plug‑in folder: ~~~xml $(SolutionDir)src/backend/Stella.Ops.Plugin.Binaries/$(MSBuildProjectName) ~~~ --- ## 5 Dependency‑Injection Entry‑point Back‑end auto‑discovers the static method below: ~~~csharp namespace StellaOps.DependencyInjection; public static class IoCConfigurator { public static IServiceCollection Configure(this IServiceCollection services, IConfiguration cfg) { services.AddSingleton(); // schedule job services.Configure(cfg.GetSection("Plugins:MyPlugin")); return services; } } ~~~ --- ## 6 Schedule Plug‑ins ### 6.1 Minimal Job ~~~csharp using StellaOps.Scheduling; // contract [StellaPluginVersion("2.0.0")] public sealed class MyJob : IJob { public async Task ExecuteAsync(CancellationToken ct) { Console.WriteLine("Hello from plug‑in!"); await Task.Delay(500, ct); } } ~~~ ### 6.2 Cron Registration ```csharp services.AddCronJob("0 15 * * *"); // everyday ``` 15:00 Cron syntax follows Hangfire rules  ## 7 Scanner Adapters Implement IScannerRunner. Register inside Configure: ```csharp services.AddScanner("alt"); // backend ``` selects by --engine alt If the engine needs a side‑car container, include a Dockerfile in your repo and document resource expectations. ## 8 Packaging & Signing ```bash dotnet publish -c Release -p:PublishSingleFile=true -o out cosign sign --key $COSIGN_KEY out/MyPlugin.Schedule.dll # sign binary only sha256sum out/MyPlugin.Schedule.dll > out/.sha256 # optional checksum zip MyPlugin.zip out/* README.md ``` Unsigned DLLs are refused when StellaOps:Security:DisableUnsigned=false. ## 9 Deployment ```bash docker cp MyPlugin.zip :/opt/plugins/ && docker restart ``` Check /health – "plugins":["MyPlugin.Schedule@2.0.0"]. (Hot‑reload was removed to keep the core process simple and memory‑safe.) ## 10 Configuration Patterns | Need | Pattern | | ------------ | --------------------------------------------------------- | | Settings | Plugins:MyPlugin:* in appsettings.json. | | Secrets | Redis secure:: (encrypted per TLS provider). | | Dynamic cron | Implement ICronConfigurable; UI exposes editor. | ## 11 Testing & CI | Layer | Tool | Gate | | ----------- | -------------------------- | ------------------- | | Unit | xUnit + Moq | ≥ 50 % lines | | Integration | Testcontainers ‑ run in CI | Job completes < 5 s | | Style | dotnet | format 0 warnings | Use the pre‑baked workflow in StellaOps.Templates as starting point. ## 12 Publishing to the Community Marketplace Tag Git release plugin‑vX.Y.Z and attach the signed ZIP. Submit a PR to stellaops/community-plugins.json with metadata & git URL. On merge, the plug‑in shows up in the UI Marketplace. ## 13 Common Pitfalls | Symptom | Root cause | Fix | | ------------------- | -------------------------- | ------------------------------------------- | | NotDetected | .sig missing | cosign sign … | | VersionGateMismatch | Backend 2.1 vs plug‑in 2.0 | Re‑compile / bump attribute | | FileLoadException | Duplicate | StellaOps.Common Ensure PrivateAssets="all" | | Redis | timeouts Large writes | Batch or use Mongo |