Skip to main content
Registry plugins ride the app’s release train. One v* tag builds TablePro and every registry plugin, the plugin zips land on the app’s GitHub release, and each plugin’s version and build equal the app’s. There are no plugin tags and no separate publish step. For what install and update look like to a user, see Plugins; to build the plugin in the first place, Plugin Development. The app reads the manifest to install a driver when someone picks a database type with no plugin loaded, to install an export format from the Export dialog, and to update installed registry plugins.

Getting a plugin into the registry

Contribute it to TablePro’s repository, as a target in the RegistryPlugins aggregate of apple/project.yml and an entry in .github/plugin-registry.json that gives its display name. The next release publishes it: a beta tag publishes to the beta channel, a stable tag to stable. A fix to a plugin ships the same way, in the next beta or patch. Bundled plugins ship inside the app and never appear in the manifest. The app never installs a registry copy over a bundled one.

The manifest

https://updates.tablepro.app/plugins/v3.json, served by GitHub Pages from the feeds branch that the release workflow writes through apple/scripts/release/registry.py. The schema version is part of the path, so a later schema ships beside this one instead of replacing it. Within v3, changes only add fields.
Plugins are sorted by id, and each plugin’s releases by build, highest first. The app refuses a document whose schemaVersion is not 3 and keeps the copy it already has. name, databaseTypeIds and exportFormatIds come from the plugin’s highest build, so an older release never rewrites them.

How the app picks a release

1

Channel

An app whose version carries -beta.N, and a local build, take stable and beta releases. A stable app takes stable only. A channel the app does not know is skipped, and the rest of the manifest still loads.
2

macOS

Releases whose minimumSystemVersion is above the running macOS are skipped.
3

PluginKit

pluginKit has to fall between TABLEPRO_PLUGINKIT_MINIMUM_VERSION and TABLEPRO_PLUGINKIT_VERSION in apple/Configs/PluginKit.xcconfig.
4

Build

The highest build left wins.
When nothing is left, the install fails with This plugin needs a newer version of TablePro. Update TablePro, then install it again. if a release with a newer PluginKit exists, and with No build of this plugin works with this version of TablePro. otherwise. The zip must match sha256, and the bundle inside must carry TablePro’s Team ID in its code signature.

Retention

registry.py keeps the two highest builds for each combination of channel, pluginKit and minimumSystemVersion. A beta goes once a stable with the same combination has a higher build, and a release whose pluginKit is below retainFromPluginKit goes too. A release that retention would drop on arrival is logged and not added. retainFromPluginKit is the PluginKit version of the oldest app version that still runs on at least 1% of the Macs seen in the last 30 days. It rises through a normal pull request, and the manifest keeps the higher of its current value and the one in the tag, so a patch on an older line never lowers it. Withdrawing a version removes its releases. The build retention kept before it comes back into selection.

PluginKit compatibility

A plugin loads when its TableProPluginKitVersion falls inside the app’s range. An additive change raises TABLEPRO_PLUGINKIT_VERSION; a breaking change raises TABLEPRO_PLUGINKIT_MINIMUM_VERSION with it. Every release rebuilds every registry plugin against the PluginKit it ships, so neither needs a separate re-release. An installed driver that predates a breaking bump is repaired in the background. See Updates.

Caching

GitHub Pages serves the manifest with Cache-Control: max-age=600. The app keeps the response in its HTTP cache on disk and decodes it at launch, so the catalog is there before any request. At launch and when Settings > Extensions opens, the cached response answers while it is fresh. Before an install reports a plugin missing, and when the app repairs an outdated plugin, it revalidates with the server. A new release reaches the app within about ten minutes.