Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

easy-csv-plugins

Plugin binaries and the signed catalog consumed by Easy CSV's in-app plugin installer (design 023 in the main repo: easy-csv/docs/design/023_plugin-repository-and-in-app-install.md).

Easy CSV ships no plugin binaries. The app fetches catalog.json from this repository's latest release, verifies its minisign signature, downloads the asset for the current platform, checks the sha256 pinned in the catalog, and only then writes it next to the app.

Layout

catalog.json            generated by scripts/build-catalog.mjs (release asset)
catalog.json.sig        base64 minisign signature of catalog.json (release asset)
schema/                 JSON Schema, validated in CI
plugins/<name>/
  plugin.json           metadata + per-platform upstream recipe (hand maintained)
  README.md             provenance, license, how the binary is obtained
scripts/
  build-catalog.mjs     dist/<platform>/* -> catalog.json (size + sha256)
  sign-catalog.mjs      catalog.json -> catalog.json.sig
.github/workflows/      build/stage -> sign -> publish

Catalog

One version per plugin, uniform across every platform it publishes — the app shows a single version per plugin, so a catalog must never mix versions. Each assets.<platform> entry pins file, size, sha256 and one or more urls (tried in order; the hash comes from the signed catalog, so mirrors and proxies cannot break integrity).

Platform keys are exactly the app's PLATFORM_DIR values and must not be invented:

windows-x86_64, macos-aarch64, macos-x86_64, linux-x86_64-gnu, linux-aarch64-gnu

Release procedure

  1. Bump version (and the upstream reference) in plugins/<name>/plugin.json.
  2. Run the release workflow (Actions → release → Run workflow). It stages binaries for all five platforms, builds catalog.json, signs it, and publishes:
    • <name>-v<version> releases holding the binaries,
    • a catalog-<date> release holding catalog.json + catalog.json.sig, created with --latest so the app's /releases/latest/download/catalog.json endpoint resolves to it.
  3. Publish the plugin releases before the catalog release — the catalog pins their asset URLs.

The repository must stay public: the app downloads release assets with no credentials. A private repository would require shipping a token inside the app.

Signing

先把密钥备份掉再谈别的:见 KEY-MANAGEMENT.md —— 它是这套链路里 唯一不可重建的东西,文档里有备份清单、换设备步骤和轮换流程。

The catalog is signed with a dedicated minisign key, separate from the app updater's key, so a compromise of this repository's CI cannot forge an application update.

  • Private key: ~/.tauri/easycsv-plugins.key on the maintainer's machine; in CI it is the PLUGIN_SIGNING_KEY secret (contents of that file). Losing the local file alone does not stop releases — CI can still sign — but its value can never be read back out of a secret, so a real backup is the only way to keep signing from a new machine.
  • Public key: committed by the app as src-tauri/plugin-signing.pub. It is what the app verifies against — treat it like the updater pubkey. It may hold several keys, one base64 line each, so a rotation can be shipped before it is needed.
  • Where is the key, and is it the right one? node scripts/key-status.mjs, and node scripts/key-status.mjs --prove to actually sign a probe and verify it against this repository's public key.
# sign locally (Tauri CLI writes the base64 form the app expects)
node scripts/sign-catalog.mjs --tauri ../../easy-csv/node_modules/.bin/tauri

# audit it with no extra tooling — the same crate the app verifies with
APP=../easy-csv
rustc --edition 2021 -L dependency=$APP/src-tauri/target/debug/deps \
      --extern minisign_verify=$(ls $APP/src-tauri/target/debug/deps/libminisign_verify-*.rlib | head -1) \
      scripts/verify-signature.rs -o /tmp/verify-signature
/tmp/verify-signature catalog.json catalog.json.sig plugin-signing.pub

# or with the minisign CLI (the .sig is base64-wrapped, so unpack it first)
base64 -d catalog.json.sig > /tmp/catalog.minisig
minisign -V -p plugin-signing.pub -m catalog.json -x /tmp/catalog.minisig

Local end-to-end test (no release needed)

# 1. stage binaries the app can actually download
mkdir -p dist/windows-x86_64
cp ../easy-csv/src-tauri/resources/plugins/windows-x86_64/*.exe dist/windows-x86_64/

# 2. build a catalog whose URLs point at a local server
node scripts/build-catalog.mjs --base-url http://127.0.0.1:8099 --out catalog.local.json
node scripts/sign-catalog.mjs catalog.local.json

# 3. serve it (dist/ and the catalog must be reachable)
python -m http.server 8099

The app only permits https plus a loopback exception in debug builds, so this path is for development only. For the same reason the schema requires https:// asset URLs: a locally built catalog is deliberately not schema-valid, and CI validates only the official one.

Manual install (no network)

Copy the binary into <data dir>/plugins/<platform>/ using exactly the file name from the catalog (xan.exe on Windows, xan elsewhere, executable bit set). The app prefers that directory over PATH. See the main repo's src-tauri/resources/plugins/readme.md.

Licenses

This repository redistributes third-party binaries. Every plugin directory records its upstream project and license; the redistributed files keep their original license terms (xan and DuckDB are MIT).

About

Plugins for easy-csv

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages