Skip to content

feat: generic plugin protocol with dgoss as builtin plugin#406

Merged
ianpittwood merged 20 commits intomainfrom
feature/plugin-protocol
Apr 2, 2026
Merged

feat: generic plugin protocol with dgoss as builtin plugin#406
ianpittwood merged 20 commits intomainfrom
feature/plugin-protocol

Conversation

@ianpittwood
Copy link
Copy Markdown
Contributor

@ianpittwood ianpittwood commented Mar 30, 2026

Summary

  • Introduces a BakeryToolPlugin protocol that defines a generic contract for tool plugins (CLI registration, execution, and optional tool configuration)
  • Refactors dgoss as the first builtin plugin at posit_bakery/plugins/builtin/dgoss/, fully self-contained with its own command model, suite orchestrator, report models, error types, and YAML tool options
  • Adds plugin discovery via Python entry points (bakery.plugins group), supporting both builtin and future external plugins
  • Moves the canonical CLI path to bakery dgoss run with a deprecation bridge at bakery run dgoss
  • Implements dynamic tool options registration — plugins expose a tool_options_class that is automatically wired into bakery.yaml deserialization via pydantic model_rebuild

Test plan

  • All 1211 existing tests pass (verified locally, 26 slow tests deselected)
  • bakery dgoss run --help shows the new command group
  • bakery run dgoss --help shows deprecation notice and still works
  • Plugin registry discovers dgoss via entry points
  • GossOptions from bakery.yaml parses correctly through the plugin's dynamic tool field
  • Run bakery dgoss run against a product repo to verify end-to-end

🤖 Generated with Claude Code

ianpittwood and others added 16 commits March 30, 2026 12:50
Documents the design for refactoring dgoss as a builtin plugin
implementing the BakeryToolPlugin protocol, including plugin discovery
via entry points, CLI registration, and deprecation bridge.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
13-task plan covering protocol update, registry, dgoss plugin
migration, CLI wiring, deprecation bridge, and cleanup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…time_checkable

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements discover_plugins() with entry-point-based loading and caching,
and get_plugin() with a KeyError for unknown names. Adds TestDiscoverPlugins
and TestGetPlugin test classes (dgoss-dependent tests will pass in Task 7+8).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove posit_bakery/image/goss/ and test/image/goss/ now that all
functionality has been migrated to the dgoss plugin. Update image/__init__.py
to drop the DGossSuite re-export, and update test/test_error.py to import
BakeryDGossError from its new location in the dgoss plugin.
…stry

Plugins can now provide tool configuration by exposing a
tool_options_class attribute. The config system dynamically builds
the discriminated union for YAML deserialization from registered
plugin tool options, with model_rebuild after plugin discovery.

- Move GossOptions to plugins/builtin/dgoss/options.py
- Add config/tools/registry.py for tool options registration
- Update config/tools/__init__.py with dynamic ToolField building
- Plugin registry registers tool options and rebuilds config models
- Break circular import in protocol.py with TYPE_CHECKING guard

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 30, 2026

Test Results

1 237 tests  +8   1 237 ✅ +8   13m 3s ⏱️ +28s
    1 suites ±0       0 💤 ±0 
    1 files   ±0       0 ❌ ±0 

Results for commit cd43674. ± Comparison against base commit ea57e2b.

♻️ This comment has been updated with latest results.

ianpittwood and others added 2 commits March 31, 2026 07:54
Plugin invocation is handled by the plugin's CLI command or by
calling get_plugin().execute() directly. No config wrapper needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tion bridge

The dgoss result display logic now lives in DGossPlugin.display_results().
Both the plugin CLI command and the deprecation bridge call it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
:param cls: The ToolOptions subclass to register.
"""
if name in _tool_options_classes:
log.warning(f"Tool options for '{name}' already registered, overwriting.")
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm debating whether this should warn or raise.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm... At this point I think it is fine to warn, but if we want to open this up to make it easier to register plugins, we will definitely want to raise.

ianpittwood and others added 2 commits March 31, 2026 08:13
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@ianpittwood ianpittwood marked this pull request as ready for review March 31, 2026 14:25
@ianpittwood ianpittwood requested a review from bschwedler as a code owner March 31, 2026 14:25
Copy link
Copy Markdown
Contributor

@bschwedler bschwedler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am really liking this approach.

My only comment/concern is the difference in CLI structure between core bakery commands and the plugins. I am not suggesting any changes now.

"""Runs dgoss tests against images in the context path

\b
DEPRECATED: Use 'bakery dgoss run' instead.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is moving more towards a mixed convention the CLI UX

For bakery operations we use the verb-noun pattern (similar to kubectl). The plugin operations follow more of a namespace-verb pattern (similar to docker and podman).
We already kind of already straddle this with bakery ci.

What are your thoughts here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The benefit would be a clear delineation if every plugin is nested under run, but I'm concerned we may go away from that being our desired approach at some point.

:param cls: The ToolOptions subclass to register.
"""
if name in _tool_options_classes:
log.warning(f"Tool options for '{name}' already registered, overwriting.")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm... At this point I think it is fine to warn, but if we want to open this up to make it easier to register plugins, we will definitely want to raise.

"""

import logging
from typing import TYPE_CHECKING
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably start enforcing type checking, but not in this PR. 😀

@ianpittwood ianpittwood added this pull request to the merge queue Apr 2, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Apr 2, 2026
@ianpittwood ianpittwood added this pull request to the merge queue Apr 2, 2026
Merged via the queue into main with commit 6990052 Apr 2, 2026
16 checks passed
@ianpittwood ianpittwood deleted the feature/plugin-protocol branch April 2, 2026 18:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants