Skip to content

Releasing Plugins

Do not publish a plugin version unless the release has been requested and you have permission to publish it.

Version bump

Use the repo tooling to bump released plugin versions:

make bump PLUGIN=data-designer-my-plugin PART=patch

PART can be patch, minor, or major. Commit the resulting pyproject.toml change:

git add plugins/data-designer-my-plugin/pyproject.toml
git commit -m "chore(data-designer-my-plugin): bump version to 0.2.0"

Pre-release versions such as 0.2.0a1 are not supported by ddp bump; edit the plugin pyproject.toml manually only when a pre-release is explicitly needed.

First-release catalog registration

Register a package in catalog/plugins.json only when preparing that package's first release. Do not register scaffolded or experimental packages before they are ready to be installable from the published catalog.

make catalog PLUGIN=data-designer-my-plugin
git add catalog/plugins.json
git commit -m "feat(data-designer-my-plugin): register catalog entry"

Subsequent version releases reuse the existing registration. If package registration metadata must be corrected later, use uv run ddp catalog register data-designer-my-plugin --replace deliberately and commit the catalog change.

Release from main

After the version bump is merged to main, create the release tag:

make release PLUGIN=data-designer-my-plugin

For the lowest-touch path, let the target push the tag and publish the GitHub Release after local checks pass:

make release PLUGIN=data-designer-my-plugin PUBLISH=1

Release tags are per plugin package and use this format:

{package}/v{version}

For example, package data-designer-my-plugin version 0.2.0 releases from tag data-designer-my-plugin/v0.2.0. The tag format comes from [tool.ddp.catalog].release-ref-template, which defaults to {package}/v{version}.

The release target:

  • verifies that the worktree is clean and HEAD matches the current origin/main tip;
  • runs that plugin's isolated tests;
  • validates release metadata;
  • builds the wheel and source distribution;
  • creates a tag named data-designer-my-plugin/v<version>.

When run without PUBLISH=1, push the tag printed by the release command:

git push origin data-designer-my-plugin/v0.2.0

Then publish a GitHub Release for that tag. Publishing the release is the explicit maintainer action that starts package publication:

gh release create data-designer-my-plugin/v0.2.0 \
  --title "data-designer-my-plugin v0.2.0" \
  --notes "Release data-designer-my-plugin v0.2.0" \
  --latest=false \
  --verify-tag

Catalog discoverability

A released plugin becomes discoverable through a catalog when the published catalog/plugins.json on the published catalog site includes a package object for the package and its runtime entry points. For the NVIDIA catalog, that means the GitHub Pages catalog at:

https://nvidia-nemo.github.io/DataDesignerPlugins/catalog/plugins.json

must include entry-point metadata, compatibility metadata, docs URL, and an install object. The checked-in raw JSON catalog is the reviewed package registry, but the Pages URL is the canonical installer surface because it is deployed with the docs and static package index. Data Designer can discover the package from the catalog before installation, install it from the package's install.requirement, and finally discover the runtime plugin from the installed package's data_designer.plugins entry point.

Catalog discovery is not runtime discovery. A catalog package makes plugins visible as installable metadata; it does not make them available in a Python environment until the package is installed.

Install metadata

The NVIDIA catalog uses unpinned package-name requirements plus the static Simple API package index:

{
  "name": "data-designer-my-plugin",
  "install": {
    "requirement": "data-designer-my-plugin",
    "index_url": "https://nvidia-nemo.github.io/DataDesignerPlugins/simple/"
  }
}

Consumers pass install.requirement to their installer and add install.index_url as an extra package index. For uv:

uv pip install \
  --default-index https://pypi.org/simple/ \
  --index https://nvidia-nemo.github.io/DataDesignerPlugins/simple/ \
  data-designer-my-plugin

External catalogs can use direct references when packages are hosted elsewhere:

data-designer-my-plugin @ git+https://github.com/acme/DataDesignerPlugins.git@data-designer-my-plugin/v0.2.0#subdirectory=plugins/data-designer-my-plugin
data-designer-my-plugin @ https://packages.example.test/data_designer_my_plugin-0.2.0-py3-none-any.whl

The NVIDIA catalog should use unpinned package-name requirements pointing at the DataDesignerPlugins package index. Package versions stay in the package artifacts and the Simple API index, and package managers resolve the version to install.

Multi-plugin packages

One Python package may expose more than one Data Designer runtime plugin entry point. Such packages release as a unit: one package version, one release tag, one wheel/sdist, and one publish event cover all entry points in that package. The catalog represents this as one package entry with multiple runtime plugin entries in that package's plugins array.

Release CI

Publishing a GitHub Release whose tag matches {package}/vX.Y.Z triggers the publish workflow. It verifies that:

  • the plugin directory exists;
  • the tagged commit is reachable from main;
  • the tag version matches plugin metadata;
  • required PyPI metadata is present, including description, license, readme, and authors;
  • the package declares requires-python and a direct versioned data-designer dependency;
  • all declared data_designer.plugins entry points are represented in the catalog for the releasing package;
  • catalog package description, compatibility metadata, docs URL, install metadata, and release ref match package metadata and catalog config;
  • plugin tests pass in an isolated virtual environment;
  • the package builds successfully;
  • twine check accepts the wheel and source distribution;
  • existing GitHub Release assets are not overwritten with different bytes;
  • the static package index can be regenerated from packages.json.

If all checks pass, CI uploads the wheel and source distribution to the ddp-package-assets GitHub Release, updates the mutable packages.json metadata asset, and dispatches the Documentation workflow on main. The Documentation workflow is the only workflow that deploys GitHub Pages: it downloads ddp-package-assets/packages.json, rebuilds the dumb-pypi Simple API index, and deploys the complete Pages site with docs, catalog JSON, and the package index in one pass.

Package publication is serialized with a workflow concurrency group because each release updates the shared ddp-package-assets/packages.json asset. If multiple plugin releases are published close together, GitHub queues the publish jobs instead of letting them overwrite each other's package-list updates.