Publishing to the Store
Your CI workflow submits an unsigned artifact to the Creator Portal, and the Portal signs and publishes it - you never hold a signing key.
Before you publish
Section titled “Before you publish”Run each check on the build output, not the project directory:
-
Store metadata is complete -
description,icon,license,repository,compatibilityandpublisher.nameare filled in (manifest reference):Terminal window macrodeck-plugin validate --level publication --artifact ./artifacts/com.example.hello-deck-1.0.0-linux-x64.macroDeckPluginExit
1means a field is missing.buildandpackonly warn about these fields; the Creator Portal applies the same check at upload. -
The artifact passes conformance (conformance suite):
Terminal window macrodeck-plugin test --artifact ./artifacts/com.example.hello-deck-1.0.0-linux-x64.macroDeckPlugin -
publishernames your Creator or Organization account. At upload the Portal checks thatpublisher.namematches the authenticated account and thatpublisher.id, if present, is that account’s id.validatecannot check this locally because it never contacts a server.
Publish with Trusted Publishing
Section titled “Publish with Trusted Publishing”Save as .github/workflows/release.yml. It uses the same build, validate and conformance steps as
CI and automation and runs when you push a version tag:
name: Release
on: push: tags: ['v*']
jobs: build: strategy: fail-fast: false matrix: include: - os: windows-latest rid: win-x64 - os: macos-latest rid: osx-arm64 - os: ubuntu-latest rid: linux-x64 runs-on: ${{ matrix.os }} defaults: run: shell: bash steps: - uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4 with: dotnet-version: 10.0.x
- name: Install the CLI run: dotnet tool install --global MacroDeck.Plugin.Cli --prerelease
- name: Unit tests run: dotnet test
- name: Build the artifact run: macrodeck-plugin build --source src/HelloDeck --rid ${{ matrix.rid }} --output ./artifacts
- name: Validate for publication run: macrodeck-plugin validate --level publication --artifact ./artifacts/*.macroDeckPlugin
- name: Conformance run: macrodeck-plugin test --artifact ./artifacts/*.macroDeckPlugin
- uses: actions/upload-artifact@v4 with: name: plugin-${{ matrix.rid }} path: artifacts/*.macroDeckPluginThe workflow stops at an unsigned, validated artifact. Once the Creator Portal publishes its interface, a submit step goes after these steps. Until then there is nothing to add, and no key or secret goes in your repository.
How the trust chain works:
- You configure your repository and its workflow as the trusted publisher for your plugin in the Creator Portal. The configuration steps are not published yet.
- The workflow authenticates with the short-lived workload identity its CI platform issues. That identity proves which repository and which workflow is running. It is not a secret you store.
- The Portal checks that the workflow is a trusted publisher for that plugin and verifies the run’s provenance.
- The Portal signs the artifact server-side. The signed artifact is published once it passes the Store’s content review.
What the workflow must never do:
- Sign anything. No signing key, certificate or signing credential belongs in your repository, your CI configuration or your CI provider’s secret store. If a publishing setup asks you for one, it is not this one.
- Replace Trusted Publishing with a manual upload. Uploading an artifact by hand is not a way to publish or sign a plugin.
Release a new version
Section titled “Release a new version”{ "id": "com.example.hello-deck", "version": "1.1.0"}git commit -am "Release 1.1.0"git tag v1.1.0git push origin main v1.1.0- The artifact version comes from the manifest’s
version(SemVer 2.0), not from the tag. Bump it before tagging.buildnames the artifact<id>-<version>-<rid>.macroDeckPlugin. - Every release goes through the whole process again. Because the Store distributes the artifact the Portal signed, nobody can silently replace or modify an approved package.
What the Store signs
Section titled “What the Store signs”macrodeck-plugin verify ./downloads/com.example.hello-deck-1.1.0-linux-x64.macroDeckPlugin- The Creator Portal is the only component that signs Store artifacts. It signs server-side, with keys that
exist only in Macro Deck infrastructure. It also issues and revokes certificates. Plugin authors do
neither, and the
macrodeck-pluginCLI cannot do either. - An artifact you pack is unsigned. That is what the Store expects to receive.
verifychecks a signed artifact against the pinned Macro Deck root. It works offline and needs no credentials. Avalidverdict is a cryptographic fact about the signature at signing time, not a live trust decision, and it does not check revocation. See the security model.keygenandsignare for artifacts distributed outside the Store and for Macro Deck’s own infrastructure. They are not part of publishing. Signing a plugin locally does not make it a Store artifact.
How updates reach users
Section titled “How updates reach users”installed 1.0.0 < Store 1.1.0 -> shown as an update- When the Store catalogue refreshes, Macro Deck compares the installed version with the latest Store version by SemVer. It offers an update only if the Store version is higher. It never offers an update when either version fails to parse.
- An update is only reported to the user. It is never installed unsigned on their behalf. Once a plugin is installed as signed, an unsigned update to it is refused, even if the user consents.
- The host verifies every package before install and again before every launch. Editing files after installation stops the plugin from loading.
Removing a plugin from the Store
Section titled “Removing a plugin from the Store”The signed registry lists removed packages. Macro Deck hides a removed plugin from the Store, stops offering it as an update, and fails any new Store install of it. This applies to the plugin id as a whole. How an author asks for a removal, and whether a single version can be withdrawn, is not published yet. There is no CLI command for it.
See also
Section titled “See also”- CI and automation - the same workflow for pull requests.
macrodeck-plugin validate- levels and problem codes.- Signing packages -
verify, andkeygen/signoutside the Store. - Manifest reference -
publisherand the publication fields. - Security model - what a signature covers and what the host enforces.
- ADR 0042 - why signing is server-side and why creator keys never reach a developer machine or a CI runner.