Skip to content

Plugin Publishing Guide

How to package, release, and distribute a third-party Decode-Orc stage plugin so users can install it — either from a hand-written registry entry or, preferably, from the curated plugin index.

This is the release-side companion to the Plugin Author Guide (which covers building and loading a plugin locally). Reference material lives in Plugin SDK Developer Guide → Distribution and Plugin Architecture.


Prefer hosting your plugin in its own repository named with the orc-plugin_ prefix:

orc-plugin_<stage-name>     e.g.  orc-plugin_deinterlace

This convention matches the release-asset naming below and makes plugin repositories easy to recognise, but it is not enforced — a plugin may live in a repository with any name (or a subdirectory of a larger project) as long as its releases publish conforming assets and the release manifest in §3.


2. Release-asset naming

Publish platform binaries as GitHub release assets using:

orc-plugin_<stage-name>_<platform>[_abi<N>].<ext>

where <platform> is linux / macos / windows, <ext> is so / dylib / dll, and the optional _abi<N> token records the host ABI the binary was built against:

orc-plugin_deinterlace_linux_abi12.so
orc-plugin_deinterlace_macos_abi12.dylib
orc-plugin_deinterlace_windows_abi12.dll

The name is a validity convention (the host rejects downloads whose names do not match it); which asset a host actually installs is decided by the release manifest below, not by parsing names. Find the ABI number you built against in the SDK version history (host_abi_version).

The skeleton CI workflows produce and upload these artifacts automatically on tagged releases.


3. Release manifest (required)

Every release must include an orc-plugin-manifest.yaml asset declaring each binary's platform, host ABI, toolchain tag, and SHA-256 digest — a release without one cannot be browsed, installed, or updated to:

manifest_schema: 1
plugin_id: org.example.stage.deinterlace
plugin_version: 1.0.0
artifacts:
  - file: orc-plugin_deinterlace_linux_abi12.so
    platform: linux
    abi: 12
    toolchain_tag: gcc14/libstdc++
    sha256: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08

file, platform, and a non-zero abi are required per artifact; toolchain_tag (the ORC_SDK_TOOLCHAIN_TAG your build produced) and sha256 are strongly recommended — the host uses them to refuse installs that are guaranteed to fail at load, and to verify (and quarantine on mismatch) every download and cache hit. Compute digests with sha256sum <file> (macOS: shasum -a 256 <file>). See Release manifest for the full schema and matching rules.

Plugin binaries are not code-signed. See Distribution integrity for exactly what the digest does and does not guarantee, and the roadmap toward a signed index.


4. Rebuild expectations on host ABI bumps

The plugin boundary is a C++ ABI, not a C ABI — vtables, std::shared_ptr, std::string, and STL containers cross it. Matching version numbers are necessary but not sufficient: the plugin must be built with the same compiler family, C++ standard library, and build configuration as the host (encoded in the descriptor's toolchain_tag and checked for exact equality at load).

Consequences for publishing:

  • When host_abi_version increases, you must rebuild against the new SDK and publish a new asset tagged _abi<new>. The host refuses to load binaries built against an older ABI. Keep the older-ABI asset in the release so users on older hosts still have a compatible build.
  • When plugin_api_version increases, update your stage implementation to the new contract and recompile.
  • Neither increment happens without a corresponding Decode-Orc release and migration notes. Watch the version history and the ABI impact decision table.

Before tagging a release, run the SDK enforcement gates in standalone mode against your repository (see Plugin Author Guide §6).


5. Distribute via a hand-written registry entry

Users can register your plugin directly by adding an entry to their plugin registry YAML:

- plugin_id:          com.example.deinterlace
  plugin_version:     "1.0.0"
  source_repo_url:    https://github.com/example/orc-plugin_deinterlace
  artifact_source:    github_release_asset
  release_asset_url:  https://github.com/example/orc-plugin_deinterlace/releases/download/v1.0.0/orc-plugin_deinterlace_linux_abi12.so
  release_tag:        v1.0.0
  release_asset_name: orc-plugin_deinterlace_linux_abi12.so
  target_platform:    linux
  required_host_abi:  12
  enabled:            true
  trust_state:        untrusted
  license_spdx:       GPL-3.0-or-later
  sha256:             9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08

Set required_host_abi so an incompatible entry is reported (and neither downloaded nor loaded) instead of failing late at dlopen. Entries default to trust_state: untrusted; the host downloads and loads only after the user grants trust (ticking Enabled in the Plugin Manager, or orc-cli plugins trust <id>). See Registry entry.


The curated index is the list users browse under Plugin Manager → Browse Plugins… and query with orc-cli plugins search / info / install. It lives in orc-plugin-registry/ and the host fetches it from the default-branch head over HTTPS — a merged pull request publishes immediately, with no Decode-Orc release and no registry tag.

The index curates which plugins are offered, not their versions: the host resolves your repository's latest published release at browse and install time, and offers each new release to installed users as an update. Publishing a new release therefore requires no registry change — keep your latest release working and correctly named, because it is what users get.

Submit an entry:

  1. Fork the registry and append your plugin under plugins: in index.yaml, following registry_schema: 2:
- id: com.example.deinterlace
  display_name: Example Deinterlacer
  description: Motion-adaptive deinterlacing for PAL/NTSC
  maintainer: Example Author
  license_spdx: GPL-3.0-or-later
  source_repo_url: https://github.com/example/orc-plugin_deinterlace
  tags: [transform, video]
  1. Make sure your latest GitHub release publishes one conforming binary per platform you support and the orc-plugin-manifest.yaml from §3 — without the manifest the host refuses to browse, install, or update to the release. The host installs exactly what the manifest declares for the user's platform, and a user on an unsupported platform, ABI, or toolchain is told precisely why rather than downloading an incompatible binary. Tag releases v<version> so the host can report and compare versions.

  2. Validate locally before opening the PR:

# Offline: schema, license, repository URL
python3 orc-plugin-registry/tools/validate_index.py orc-plugin-registry/index.yaml

# Online as well: latest release publishes a conforming plugin asset
python3 orc-plugin-registry/tools/validate_index.py --online orc-plugin-registry/index.yaml
  1. Open the pull request. CI validates schema conformance, a valid SPDX license_spdx, a GitHub source_repo_url, and that your latest release publishes a conforming plugin asset. Only GPLv3-compatible licenses are accepted.

A maintainer's merge is the curation decision and publishes the entry — it endorses your repository, so every release you publish afterwards is offered to users automatically. Users then install with:

$ orc-cli plugins search deinterlace
$ orc-cli plugins info com.example.deinterlace
$ orc-cli plugins install com.example.deinterlace   # latest release, untrusted
$ orc-cli plugins trust com.example.deinterlace      # user confirms trust

Installing from the index records an entry pointing at your latest release and leaves it untrusted until the user confirms — the same trust flow as the GUI Browse Plugins… dialog. Users are re-asked to confirm trust after every update, since each release is a new binary.


7. Checklist

  • Repository named orc-plugin_<stage-name> (recommended).
  • Release assets named orc-plugin_<stage>_<platform>_abi<N>.<ext>.
  • orc-plugin-manifest.yaml uploaded with the release, declaring every binary's file/platform/abi plus toolchain_tag and sha256.
  • Latest release is the one users should get (the index resolves it at install time); releases tagged v<version>.
  • Rebuilt (and manifest updated) for each host ABI bump.
  • instructions.md shipped beside each binary and up to date.
  • Enforcement gates pass in standalone mode.
  • Curated-index PR validated locally.