Releasing
This page covers packaging and publishing custom providers. If you only need to
consume an already-published provider package, use Providers and
reference it with a provider-release.yaml metadata URL.
Once a provider or UI package works locally, you can publish a release archive for distribution. Release archives are self-contained and include a manifest, the executable artifacts for packaged providers, and optional static assets.
What can be released
Gestalt uses the same release system for executable provider packages, authentication and datastore component packages, and packaged UI bundles. Every package is described by a provider manifest file: manifest.yaml, manifest.yml, or manifest.json.
Source manifests vs release manifests
During local development and gestaltd provider release, source manifests can
omit artifacts and executable entrypoints. Release packaging materializes
those fields for you.
Minimal executable source manifest
kind: plugin
source: github.com/acme/plugins/my-plugin
version: 0.0.1-alpha.1
spec:
connections:
default:
auth:
type: noneExecutable source packages stay language-native. Gestalt loads the provider from the package root or the language-specific target declaration, then synthesizes the runnable wrapper during local source execution and release packaging.
Go
my-plugin/
go.mod
manifest.yaml
provider.gomodule github.com/acme/plugins/my-plugin
go 1.26
require github.com/valon-technologies/gestalt/sdk/go v0.0.1-alpha.1Source release builds
Source manifests may optionally define a release.build command. Gestalt runs
it before source-manifest preparation, which lets UI packages generate
static assets and lets provider/authentication/datastore packages generate support files
such as config schemas before packaging.
kind: ui
source: github.com/acme/plugins/gestalt-ui
version: 1.2.0
release:
build:
workdir: ui
command:
- npm
- run
- build
spec:
assetRoot: ui/outRelease manifest for an executable provider
Released executable plugin providers add concrete entrypoint and
artifacts entries:
kind: plugin
source: github.com/acme/plugins/my-plugin
version: 0.0.1-alpha.1
spec: {}
entrypoint:
artifactPath: artifacts/linux/amd64/provider
artifacts:
- os: linux
arch: amd64
libc: musl
path: artifacts/linux/amd64/provider
sha256: "..."UI bundle manifest
UI packages use the same manifest system:
kind: ui
source: github.com/acme/plugins/ui/default
version: 1.2.0
spec:
assetRoot: ui/out
configSchemaPath: schemas/ui-config.schema.jsongestaltd init prepares the released UI and records it in gestalt.lock.json. gestaltd serve --locked then serves the prepared asset root at whatever public path the deployment config binds for that UI bundle. Omit providers.ui to run headless with no public UI bundles. The built-in admin UI remains available at /admin regardless.
Build a release
Use gestaltd provider release to build a provider release and produce release archives:
gestaltd provider release --version 0.0.1-alpha.1Run this from the provider source directory. It produces release archives and writes a checksums file.
Release tags are derived from the package path after the repository. For example, source: github.com/acme/plugins/catalog/support-api releases from the tag plugins/catalog/support-api/v0.1.0.
For executable Go, Rust, Python, and TypeScript source providers,
provider release materializes the executable catalog automatically and builds
the host-platform artifact by default. Go, Rust, and TypeScript auth/datastore
source packages use the same release flow without catalog generation. Pass
--platform with a comma-separated list such as
--platform linux/amd64,darwin/arm64 to build explicit targets. Pass --platform all in CI release jobs to build the
full supported platform matrix for source builds.
Executable source plugins declare hosted HTTP routes in the manifest with
spec.securitySchemes and spec.http. During local source execution and
provider release, Gestalt preserves those manifest blocks in the effective
manifest and released archive:
spec:
securitySchemes:
signed:
type: hmac
secret:
env: REQUEST_SIGNING_SECRET
signatureHeader: X-Request-Signature
signaturePrefix: v0=
payloadTemplate: "v0:{header:X-Request-Timestamp}:{raw_body}"
timestampHeader: X-Request-Timestamp
maxAgeSeconds: 300
http:
command:
path: /command
method: POST
security: signed
target: handle_command
requestBody:
required: true
content:
application/x-www-form-urlencoded: {}
ack:
status: 200
body:
status: acceptedFor non-host Python targets, point Gestalt at a matching interpreter with
GESTALT_PYTHON_<GOOS>_<GOARCH> or a target-specific virtualenv such as
.venv-<goos>-<goarch>/.
TypeScript source plugins require Bun for local source execution and packaging. The SDK uses Bun’s compile flow to build standalone provider binaries during release.
Reference releases from config
During development
Use source.path to point at the source tree directly. Gestalt synthesizes the executable wrapper and materializes the catalog automatically:
plugins:
my-plugin:
source: ./plugins/my-plugin/manifest.yamlUI bundles work the same way:
providers:
ui:
dashboard:
source: ./gestalt-ui/manifest.yaml
path: /dashboardFor production
Reference a published release by metadata URL:
plugins:
my-plugin:
source: https://artifacts.example.com/plugin/my-plugin/v0.0.1-alpha.1/provider-release.yamlUI bundles use the same pattern under providers.ui.<name>:
providers:
ui:
dashboard:
source: https://artifacts.example.com/ui/default/v1.2.0/provider-release.yaml
path: /dashboard
config:
brand_name: AcmeWhen a config references published releases, run gestaltd init to resolve and prepare them:
gestaltd init --config ./config.yamlThis writes lock state (gestalt.lock.json) and extracts prepared artifacts under .gestaltd/. After init, gestaltd serve --locked starts the server from that lock state. If the prepared files are already present, Gestalt uses them directly. If they are missing, Gestalt can materialize them from the lockfile at runtime. See Configuration for the full startup model and the tradeoffs between vendored artifacts and lockfile-only startup.
Release archive layout
A typical release archive contains:
manifest.yaml
artifacts/
my-plugin-linux-amd64
my-plugin-darwin-arm64
schemas/
config.schema.json
assets/
icon.svgThe exact structure is determined by the manifest. schemas/ is optional and
used for provider config validation. assets/ is optional and used for icons or
other static files.
Use Provider Manifests for the canonical manifest reference.
What to read next
- Provider Manifests: full manifest field reference
- Helm Deployment: deploying with Helm and referencing published releases
- Configuration:
gestaltd init, lock state, and the full startup model