Publishing a provider#
Once your provider works, users need a way to install and use it. Today that means: give them a binary and have them reference it by path. A registry is future work.
Consumption model#
Scenarios reference providers by source string:
required_providers {
stripe = { source = "exec:./bin/orchard-stripe" }
}The path is resolved relative to the scenario file that declares the provider. Absolute paths work too. The binary must be executable.
There is no auto-discovery from $PATH, no version pinning, and no registry
today. The source string points at one specific binary.
Packaging#
For a single team#
The simplest approach: commit the provider source to the same repo as the
scenarios that use it, add a Makefile target that builds the binary, and
have developers run make providers before orchard run.
my-project/
├── Makefile
├── providers/
│ └── stripe/
│ ├── go.mod
│ └── main.go
├── bin/
│ └── orchard-stripe # built, gitignored
└── scenarios/
└── demo.hcl # source = "exec:../bin/orchard-stripe".PHONY: providers
providers:
cd providers/stripe && go build -o ../../bin/orchard-stripe .
For cross-team distribution#
Publish a release (GitHub Releases, an internal artifact repo) with per-platform binaries:
orchard-stripe-0.3.0-darwin-arm64
orchard-stripe-0.3.0-darwin-amd64
orchard-stripe-0.3.0-linux-amd64
orchard-stripe-0.3.0-linux-arm64Consumers pin a version, download the binary to a known location, and reference it from their scenarios:
required_providers {
stripe = { source = "exec:./vendor/orchard-providers/stripe" }
}A make install or shell script that downloads and vendors the right binary
keeps this repeatable across machines.
Versioning#
- Use semver for the provider’s
versionfield in its schema. - Bump the major version when you make breaking changes to action names, required attributes, or output shapes.
- Protocol version (the
protocolfield) should stay at"1"unless Orchard itself ships a new protocol version. It tracks the wire protocol, not the provider’s own API.
Orchard does not currently enforce version constraints — a scenario cannot declare “stripe ≥ 0.3.0”. Users who need constraint checking should build it into their packaging layer (e.g. a script that refuses to install a binary whose schema reports the wrong version).
Testing before publishing#
A published provider should pass at least:
- Schema probe.
./orchard-stripe schema | jq .produces a valid schema JSON document. - Plan against a scenario.
orchard plan scenario.hclsucceeds without configure/execute errors. - Run against a real target.
orchard run scenario.hclagainst a sandbox / test account. - Shutdown. The process exits cleanly within 5 seconds of the shutdown
RPC. Check with
orchard runand watch for leftover processes.
A small Go test that spawns the binary and drives it through a full
describe/configure/execute/shutdown handshake will catch most regressions.
See pkg/provider/external/external_test.go in the Orchard repo for the
in-tree equivalent.
Roadmap#
A future release will add:
- A registry. Providers published by name (e.g.
stripeinstead ofexec:./bin/orchard-stripe), with signed releases and version resolution. - Version constraints.
required_providers { stripe = { source = "...", version = ">= 0.3" } }. - Checksum pinning. Trusted binary verification like Terraform’s
.terraform.lock.hcl.
Until then, treat external providers the way you’d treat any other vendored binary dependency: pick a distribution mechanism, pin a version, and be explicit about where the file lives.