Publish a plugin to a registry¶
Publishing lists a version of your plugin in the platform's Community registry, as
namespace/plugin, for any deployment to find and install. You never build or push an image:
you sign a release tag, and the platform builds it, checks it and lists it. What the registries
are, and what each checks, is in Registries.
In short:
- Once:
meridian plugin key setup. - Each release: raise the version in the change's own pull request, merge it, then
meridian plugin release X.Y.Z.
Signing the tag yourself and running meridian plugin publish is the other way,
below.
Who publishes
The Community registry lists Open Meridian's own plugins, under the open-meridian/
namespace; the platform refuses another publisher's publish, saying so.
Before you start¶
- CLI 0.1.60, and git 2.34 or later, which signs tags with SSH keys.
- To release in one command, your GitHub sign-in:
GH_TOKENorGITHUB_TOKEN, or the credential git keeps for github.com (gh auth setup-gitgives git one). It must be able to read checks on the plugin's repository. - The plugin passes
meridian plugin check, with its documentation (see Write a plugin's documentation). - Its repository is on GitHub and public, and the plugin's own code is under Apache-2.0.
- Your organisation on open-meridian.com holds publisher status on open-meridian.com.
- You are an Owner or Admin of the organisation. A member who is not needs may publish on the plugin's Publishers tab, which an Owner or Admin grants.
Until your organisation's first publish, its Plugins page shows a To your first publish checklist: each step below, ticked as it is done.
Set up once, on the platform¶
An Owner or Admin does these on the organisation's publishing pages at open-meridian.com.
- Set the namespace. On the Plugins page, Set the namespace: lower-case letters, digits and hyphens, at most 39 characters. It is the first half of every listing's name, and it is fixed at the first publish.
- Connect GitHub. On the Repositories page, Connect GitHub signs you in with GitHub, then links the platform's GitHub App, Open Meridian Registry, or installs it on the repositories you choose. The first publish fixes the listing's repository.
- Register a signing key.
meridian plugin key setup, below, does it from your computer. Or, on the Signing keys page, Register a key, and paste the public half of the key you will sign release tags with. The platform holds public halves only.
The signing key¶
Once, from the plugin's directory:
It makes the key ready in one step:
- The key. Where git already signs with an SSH key, that key is used. Otherwise
ssh-keygenmakes one on your computer,~/.ssh/id_ed25519_meridian(ed25519), and asks you for its passphrase itself. With--hardware, the key is held on a FIDO security key instead (ed25519-sk), andssh-keygenasks you to touch it. - git is set to sign with it (
gpg.format ssh,user.signingkey). Where git already signs with a GPG key, only in the plugin's repository. - The platform. If you are an Owner or Admin, it registers the public half on the organisation. If you are not, it tells you to ask one, with the line to give them.
The first command that needs the platform signs you in in your browser; the sign-in is kept 30
days. --organisation takes the organisation's namespace. It defaults to the organisation the
plugin's git remote names, where the platform knows it; otherwise the command says to name it.
meridian plugin new offers key setup where git has no SSH signing key yet.
A signing key stays with a person or a device. Never put it in CI. An organisation can register several keys, one for each person or device that signs releases.
To register a key you already have, or to list the organisation's keys:
meridian plugin key register ~/.ssh/release.pub --organisation acme
meridian plugin key list --organisation acme
Each release¶
The version goes up in the change itself. The pull request that makes the change also raises
version in pyproject.toml and adds the change to CHANGELOG.md under a heading for that
version, with no date and no "(unreleased)": the date lives on the tag and the listing.
Once that pull request is merged and main's CI is green, from the plugin's directory, on main, clean and up to date:
It checks, signs and publishes. It opens no pull request and changes no file:
- Checks. The checkout is on the default branch, clean and up to date with
origin; the version is higher than the last release tag;pyproject.tomlsays0.18.0;CHANGELOG.mdhas the heading## 0.18.0, undated; and main's last CI run is green. Each refusal says what to do next: a version not yet raised, for example, is raised in a pull request, merged, and the command run again. - The tag. It signs
v0.18.0on main's head with your key, and pushes it. - Publishing. It asks the platform to build the tag, and follows the build, as
meridian plugin publishdoes.
If it stops following after --timeout (default 30 minutes), the build carries on. Running the
same command again finds the tag on origin and publishes it.
While the build runs it prints one line a check, cut to your terminal's width, until the version is listed or refused, then the listing's address:
acme/venue-desk 0.18.0 (community): listed
image: sha256:…
ok <check>: <what it found>
warn <check>: <what it found>
…
(--details prints each check's full text)
log: https://github.com/open-meridian/plugin-builder/actions/runs/…
listing: https://open-meridian.com/plugins/acme/venue-desk
--details prints each check's full text. The build carries on if you stop following it.
Or tag and publish by hand¶
The same release, step by step. Any SSH key registered on the organisation signs it. Point git at
it once, if meridian plugin key setup has not:
Then, for each release:
- Raise
versioninpyproject.tomland merge the change, through its pull request as usual. -
Tag the merged release commit with that version,
vand its SemVer, signed with your key: -
From the plugin's directory, ask the platform to build it:
The tag's version must equal the version in pyproject.toml. Before it asks for anything,
plugin publish refuses here what the builder would refuse: a tag that is not v and that
version, a tag not signed with an SSH key, an origin that is not a GitHub repository, or a
plugin failing meridian plugin check. Then it asks the platform to build the tag, with a token
good for that one plugin, and follows the build, printing its report as above. --timeout sets
how long it follows the build (default 30 minutes).
What the platform checks¶
In short: the tag's signature against your organisation's keys; that it is built on
plugin-python; the plugin's own dependencies, screened against its licence and for
vulnerabilities; secrets and malware; the role's conformance suite and the plugin's own tests, run
inside the built image; the image's size; meridian plugin check; and the attestations, signed by
the platform's key. See The automatic checks.
Each build has its own page, reached from the plugin's Versions tab: one short line per check, with its full text a click away, and a Packages table, the image's bill of
materials. An agent you connect reads the same with read_plugin_build.
A refused build does not hold its version: once you have fixed what it names, that version is still free to publish.
The display name. From CLI 0.1.51 a publish sends the display name your code declares,
meridian.Interface(title=...), and the builder refuses a build whose image declares another,
saying both names: make the two agree in the tagged code and publish a new tag. Your listing's row
shows the name while the version builds.
Queued, not refused. While two of your organisation's builds are running, a third publish is
queued, and meridian plugin publish says so once and follows it until it settles. A publish
refused with status 429 has met the organisation's daily cap of publishes: nothing was built, and
the next goes ahead once a day has passed since the earliest of them.
Look after a listing¶
- Withdraw a version on the plugin's Versions tab, Withdraw. It is no longer offered for install or update and stays pullable by digest, with no warning to those who installed it.
- Attributes and support contact on the Attributes tab: the regions (ISO 3166 country codes) and asset classes the plugin serves, and how to reach you. Each is shown as the vendor's.
- Who may publish it, on the Publishers tab: an Owner or Admin grants and revokes may publish for a member. That is a page act, never an agent's.
- Usage, on the Usage tab: totals per version and week, once three or more deployments contribute.
Revoke a signing key¶
If a key may have leaked, revoke it on the Signing keys page, or with the CLI, saying when it stopped being trusted:
meridian plugin key revoke SGK-01JB8Z3K6Q --organisation acme \
--reason "laptop lost" --not-trusted-after 2026-10-16T12:00Z
--not-trusted-after defaults to now. A tag the key signed before that time still verifies; a
build after it, of a tag it signed, is refused. Deployments learn of the revocation with their next
catalogue pull.
Related¶
- Registries: the checks and what a deployment verifies.
- Command line:
plugin release,plugin publishandplugin key. - Release a plugin version: to your own deployment.