Skip to content

Added minimum version fields to the plugin manifest - #522

Closed
jaysuk wants to merge 1 commit into
Duet3D:v3.7-devfrom
jaysuk:feature/plugin-min-versions
Closed

jaysuk wants to merge 1 commit into
Duet3D:v3.7-devfrom
jaysuk:feature/plugin-min-versions

Conversation

@jaysuk

@jaysuk jaysuk commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

Problem

PLUGINS.md documents dwcVersion, rrfVersion and sbcDsfVersion as minimum versions, but checkVersion (src/plugins/index.ts) only tests that the version segments up to the shorter string are equal. So they are "same version prefix" checks:

running field value today as a minimum
3.7.0-rc.2 3.7 ok ok
3.8.0 3.7 rejected ok
3.7.1 3.7.0 rejected ok
3.5.4 (RRF) 3.5.1 rejected ok
3.7.0-rc.2 3.7.0-rc.1 rejected ok

That is a reasonable default for dwcVersion (plugins compile against DWC internals and the externalised chunks, and auto-major relies on it). But there is currently no way for a plugin to say "3.6 or newer".

Change

Adds three optional manifest fields, checked with a real "this version or newer" comparison, and leaves the existing three fields exactly as they are, so no installed plugin changes behaviour:

  • dwcMinVersion, rrfMinVersion, sbcDsfMinVersion
  • src/plugins/version.ts (new, no imports): compareVersions, checkMinVersion, getMinVersion. A minimum without a prerelease tag is met by prereleases of that release line (so a plugin requiring 3.7 installs on 3.7.0-rc.2); only a minimum that names a prerelease is compared prerelease by prerelease. Unparsable input fails.
  • PluginInstallDialog.vue: reads the fields from the raw plugin.json, shows a "Requires X or newer" line under the RRF/DWC/DSF version, blocks the install when unmet. Combines with the existing prefix field if both are set.
  • machineStore.installPlugin: rejects a plugin that needs a newer DWC.
  • scripts/build-plugin.js: auto / auto-major / auto-minor are resolved in the new fields too.
  • PLUGINS.md: new "Version requirements" section explaining prefix fields vs minimum fields.
  • en.json / de.json: one new string.

Limitation: this needs @duet3d/objectmodel and DSF changes to be complete

PluginManifest in @duet3d/objectmodel only keeps properties it declares (ModelObject.update skips any key not in this). So a *MinVersion field is dropped as soon as the manifest becomes a Plugin model object:

  • Standalone: PollConnector.installPlugin does initObject(Plugin, ...) and saves JSON.stringify(plugins) to the plugins file, so the fields are not persisted.
  • SBC: the ZIP is PUT to DSF, which (as far as I can tell; I have not read the DSF source) parses plugin.json itself and serves the object model back.

What that means for this PR:

  • Works now: the install-time checks (dialog and installPlugin), because they read the raw plugin.json from the ZIP.
  • Written but inert until upstream changes: the check in loadExternalPlugin and the requirements line in Settings → Plugins. Both read from the object model via getMinVersion, so they start working as soon as the fields exist there. Nothing breaks in the meantime; they just find nothing to check.

The upstream work is small: declare dwcMinVersion, rrfMinVersion and sbcDsfMinVersion (string | null, default null) on PluginManifest in @duet3d/objectmodel, and, on the DSF side, add the same three properties to the plugin manifest so it keeps and serves them (and, if you want it, checks them when installing a plugin itself). I have not looked at the DSF code yet, so the exact change there is for me to confirm. I'm happy to open PRs for both (and bump the @duet3d/objectmodel dependency here once it is released) if you want this direction. If you would rather keep the manifest as it is, or prefer a different shape (e.g. range syntax, or changing what the existing fields mean), tell me and I will rework it.

Testing

  • vue-tsc --noEmit is clean for everything touched (checked it catches a deliberately wrong field name).
  • version.ts was exercised with 44 cases (rc ordering such as rc.10 vs rc.2, 3.10 vs 3.9, the old 3.4.0b3 firmware spelling, empty/garbage input, the table above) and each of the comparison direction, the prerelease rule and the empty-minimum handling was broken in turn to confirm the cases fail. DWC has no unit-test runner, so these were ad hoc scripts and are not in the PR.
  • resolveVersionPlaceholders checked for the three new fields.
  • Not done: I have not clicked through the install dialog in a browser.

Targets v3.7-dev. It is additive and touches nothing in the load path for existing plugins, but I understand 3.7 is in its rc phase, so say if you would rather hold it.

🤖 Generated with Claude Code

dwcVersion, rrfVersion and sbcDsfVersion are documented as minimums but
checkVersion only tests for an equal version prefix, so "3.7" rejects 3.8
and "3.5.1" rejects 3.5.4. Rather than change what those fields mean for
existing plugins, add dwcMinVersion, rrfMinVersion and sbcDsfMinVersion,
checked with a real "this version or newer" comparison (src/plugins/version.ts).

A minimum without a prerelease tag is met by the prereleases of that release
line, so "3.7" installs on 3.7.0-rc.2. The install dialog and installPlugin
read the fields from the raw plugin.json. The load-time check and the plugin
list read them from the object model, which drops fields PluginManifest does
not declare, so those two stay inert until @duet3d/objectmodel (and DSF for
SBC installs) declare them.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@chrishamm

Copy link
Copy Markdown
Collaborator

I am sorry but I cannot approve this PR at this point. We are very close to 3.7.0 stable and I cannot make deeper changes at this point. In addition, I will not accept minVersions because 3.7 and 3.8 are not guaranteed to be fully compatible.

We can consider to allow a range of supported versions (changing the type of dwcVersion etc. from an atomic value to an array with the same check mechanism) but not more. TBD.

@chrishamm chrishamm closed this Sep 29, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 29, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants