Publishing
How an extension gets into the store — source in, signed package out.
The store keeps one promise: the reviewed source is the shipped package. You submit source, pinned to a commit; the store's own build compiles it, packages it, signs it and publishes it. No binary you built is ever published, so nothing can be swapped after review.
That is also why a package you build yourself installs as not signed: only
the store's build signs, and Lumi says so rather than pretending otherwise.
(A package downloaded from the store and installed from a file keeps its
signature if its .sig file sits beside it, as <package>.sig.)
Submitting
Put the source in a public repository
A Rust crate depending on lumi-extension-api, with manifest.toml beside
its Cargo.toml. Anything under ui/ is packed exactly as it is in the
repository, so commit it as source — see
Building for the store.
Open a pull request against the store
The store lives at github.com/thiennguyen93/lumi-store. The pull request:
- adds your repository as a submodule under
ext/<your-extension-id>, pinned to the exact commit you are submitting, and - adds one entry to
extensions.toml:
[[extension]]
id = "dev.you.thing" # must equal the id in your manifest.toml
path = "ext/dev.you.thing" # the submodule
subdir = "." # where Cargo.toml and manifest.toml live inside itReview
Review is by a person, of the source: the capabilities the manifest declares against what the code actually calls, nothing phoning home, and no misbehaviour shipped as a feature. The pull request's checks also hold the manifest to the rules Lumi's installer applies, so a manifest Lumi would refuse fails there rather than on somebody's Mac.
Merge
Merging is publishing: the store rebuilds every listed extension from source, signs the packages and rewrites the index Lumi reads.
How people find it
Store, in the row above the list in Settings → Extensions, opens the store's page on lumikeys.app in the browser. Its Install button hands the extension back to Lumi, which downloads the signed package and shows the same review sheet a file install gets — this time saying the package came from the store and was verified against its key. Nothing installs until the person presses the sheet's button — Install, or Continue… when the extension ships an installer of its own.
Updates
An update is a pull request that moves your submodule to a new commit and
raises version in the manifest. The id never changes — it is how Lumi
knows the new package replaces the old one.
Lumi reads the store's index at launch, when its window comes forward, and
once an hour in the background, at most every six hours — and whenever the
person presses Check for updates… in Settings → Extensions. An update is
offered when the store's version is higher than the installed one, compared
as numbers, so 1.10.0 is newer than 1.9.0. Both must be written
major.minor.patch; a version of any other shape is never offered as an
update. An update whose min-lumi-version is above the running Lumi is
listed as needing a newer Lumi.
An update keeps the person's settings, and your
installer is not shown again.
If your extension is switched on, it is told with
Updated, carrying the version it
replaced.
Keep capabilities as narrow in an update as in the first release: a new capability is a new line on the review sheet.