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 theRegistryPlugins 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.
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.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 itsTableProPluginKitVersion 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 withCache-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.
