Documentation / Développement / Guides pratiques / Publish to the registry

Publish to the registry

This recipe ships a built plugin to a plugin registry with meridian-plugin publish, so operators can declare it in an instance manifest by version range instead of hand-copying a dist/ folder. It assumes you already have a working dist/ (see Build and bundle) and a registry you can write to (see Set up a plugin registry).

Prerequisites

  • A built plugin: dist/plugin.yaml exists, with name and version set (libs/plugin-cli/src/registry/registry.ts, publishPlugin reads both from the manifest — nothing is taken from the command line).
  • A reachable registry — a GCS bucket (gs://bucket[/prefix]) or a local/NFS directory — with write access for your identity.
  • meridian-plugin available: through the scaffold's node_modules/.bin (npm run …) or via npx @meridian/plugin-cli.

1. Point the CLI at the registry

publish and versions both take the registry from --registry <url> or, if that flag is absent, from the MERIDIAN_REGISTRY environment variable — the flag always wins when both are set (libs/plugin-cli/src/commands/publish.ts, registryUrl). Neither present is a hard error (registre non configuré : passez --registry <url> ou définissez MERIDIAN_REGISTRY).

export MERIDIAN_REGISTRY=gs://meridian-plugins   # or a local directory / file:// URL
# — or, per invocation:
meridian-plugin publish --registry gs://meridian-plugins

2. Publish the built plugin

cd vitals
npm run build              # meridian-plugin build → dist/ (bundled, self-contained)
meridian-plugin publish    # registry from MERIDIAN_REGISTRY, or add --registry <url>

publish [dir=.] is convenient about where you point it (publishCommand): if <dir>/dist/plugin.yaml exists, that dist/ is what gets published; otherwise <dir> itself is published as-is. In practice this means running the command from the plugin's project root (after build) and running it from inside dist/ both work — meridian-plugin publish and meridian-plugin publish dist are equivalent there. The directory argument and --registry <value> can appear in either order on the command line.

A successful publish reports the name, version and file count that landed on the store:

✓ @acme/vitals@0.1.0 published to gs://meridian-plugins (7 file(s)).

Internally, every file under dist/ is uploaded first, and plugin.yaml is written last — its presence is the marker that a version is complete, so a download in progress never sees a half-published version (registry.ts, publishPlugin).

3. Verify what's published

List the versions the registry currently has for that name:

meridian-plugin versions @acme/vitals --registry gs://meridian-plugins
0.1.0
0.2.0

Versions print oldest first — resolved with the npm semver package (compare), with any non-semver folder name pushed to the end rather than failing the listing (registry.ts, listVersions). An empty result prints @acme/vitals : aucune version publiée sur … rather than an error, which still confirms the registry is reachable and readable.

To confirm an operator can actually pick it up, see Declare and install plugins — version ranges (^0.1.0, ~0.1.0, an exact version, *) are resolved against this same list with maxSatisfying.

Re-release after a change (versions are immutable)

A published name@version can never be overwritten. Publishing the same version again is refused outright:

✗ @acme/vitals@0.1.0 is already published on gs://meridian-plugins — versions
  are immutable, bump it.

(registry.ts, publishPlugin — the check is a plain existence test on that version's plugin.yaml before anything is written.) To ship a new build:

  1. Bump version in plugin.yaml (semver). This is the only place the version comes from — there is no --version flag on publish.
  2. Rebuild: npm run build copies the bumped manifest into dist/.
  3. Publish again. The new version is added; every previous one is untouched and still resolvable by any range that matched it before.

If a publish is interrupted

Because files land before plugin.yaml, an interrupted publish (network drop, killed process) can leave stray files under that version's prefix even though the version is not "complete" (no plugin.yaml yet, so versions still won't list it). Retrying the exact same version isn't guaranteed to be clean in that case — each file is written with a create-if-absent guard, so a file that already landed makes the retry fail on that file rather than with the friendly "already published" message above. If a retry fails oddly right after an interruption, that's almost certainly why; publishing under a bumped version sidesteps it entirely.

75 documents7 sectionssource : /docs · généré au build