Skip to content

Manage resource types via OCI (create/get/list/publish/pull/delete/convert) - #249

Merged
chrisghill merged 19 commits into
mainfrom
resource-type-oci
Sep 2, 2026
Merged

Manage resource types via OCI (create/get/list/publish/pull/delete/convert)#249
chrisghill merged 19 commits into
mainfrom
resource-type-oci

Conversation

@chrisghill

Copy link
Copy Markdown
Member

The API now supports resource types being managed via OCI push/pull. This wires that up in the CLI, mirroring bundles but without any build/lint machinery, extracts the shared OCI plumbing into its own package so bundles and resource types share one code path, and moves resource-type reads onto the SDK so the local internal/api holding-pen package can be deleted entirely.

Shared OCI package

  • New internal/oci package holds the raw OCI logic: Publisher (Package with a caller-supplied artifact-type + per-file keep predicate, Publish) and Puller (Pull), plus the file/mime helpers.
  • internal/bundle keeps only its unique config (ArtifactType const + PackageKeep ignore-list predicate); internal/commands/bundle/{publish,pull} and internal/commands/instance/export.go now drive oci.Publisher/oci.Puller.
  • Bundle behavior is unchanged — same media type (application/vnd.massdriver.bundle.v1+json), same .mdignore keep semantics, same manifest/layers, same pull tag resolution.

Resource types → OCI (7 commands)

Command Behavior
create Creates a resource-type OCI repository; supports -a attributes
get Uses the SDK's ResourceTypes.Get (returns the resolved JSON schema); -o json prints the full object, new --schema prints only the schema (errors without -o json)
list Lists from the OCI-repo catalog filtered to resource-type artifacts, mirroring bundle list (columns: Name / Latest / Created At; supports -o json)
publish [path] Bundle-style directory (default .); requires version in massdriver.yaml; meta-schema validation; local duplicate-version check (stable only, no dev releases); packages only allowlisted files; rejects raw JSON schema files, pointing to convert
pull OCI pull (-d/-v/-f), latest resolves to the latest release channel or newest tag
delete Deletes the OCI repository, failing locally if it has published versions (immutable); keeps the type-the-name confirmation
convert Converts a raw JSON/YAML schema into a massdriver.yaml, extracting inlined instruction/export content back out to referenced files
  • Added a version field to the resource type massdriver.yaml.
  • Publish allowlist: massdriver.yaml, readme, changelog, icons, plus the instructions/ and exports/ directories a massdriver.yaml references (so convert → publish → pull round-trips). Everything else is silently skipped.
  • Raw JSON schema publishing is no longer supported.

Removed internal/api

  • Resource-type reads (Get, List) now go through the SDK (ResourceTypes.Get and OciRepos.Iter), so the temporary internal/api holding-pen package is deleted in full — no callers remain.
  • resourcetype.ResourceType is now an alias of the SDK's resourcetypes.ResourceType.

Tests & docs

  • New/updated tests: bundle packaging against the shared packager, OCI pull, publish validation (raw-schema rejection, missing name/version), packageKeep allowlist, convert round-trip (incl. duplicate-label collision and no-clobber), and resource-type get/list mocked via massdriver.WithGQLClient.
  • Added helpdocs for create/pull/convert, refreshed publish, and regenerated the committed CLI docs.

Notes

  • list table columns changed from ID / Name / Updated At to Name / Latest / Created At to match bundle list.
  • Requires the SDK bump to v0.2.18 (adds the ResourceTypes service).

@chrisghill

Copy link
Copy Markdown
Member Author

@claude review

@claude

This comment was marked as outdated.

@chrisghill

Copy link
Copy Markdown
Member Author

@claude review

@claude

This comment was marked as outdated.

@chrisghill

Copy link
Copy Markdown
Member Author

@claude review

@claude

claude Bot commented Sep 2, 2026

Copy link
Copy Markdown

Claude finished @chrisghill's task in 3m 37s —— View job


Review

Overall this is a clean, well-tested refactor. The internal/oci extraction is a genuine simplification (bundles and resource types now share one Publisher/Puller code path), the internal/api holding-pen package shrinks to just the still-needed legacy mutation, and the new resource-type commands mirror the bundle equivalents closely enough that reviewers/users get a consistent mental model. Test coverage for the new packaging/publish-validation/convert logic (keep_test.go, resolve_test.go, convert_test.go, oci/publish_test.go) is thorough, including the tricky edge cases (path traversal in referenced files, duplicate-version skip on 0.0.0, label-collision dedup in convert).

A couple of things worth double-checking before merge:

1. PR description vs. actual behavior: raw JSON schema publishing is still supported

The description states:

publish [path] ... rejects raw JSON schema files, pointing to convert
Raw JSON schema publishing is no longer supported.

But internal/commands/resourcetype/publish.go:186-192 (resolvePublishPath) still routes .json/.yaml/.yml files to a legacy: true target, and publishLegacySchema (line 196) publishes them through the deprecated api.PublishResourceType GraphQL mutation — it only prints a deprecation warning (warnLegacySchema, line 229) rather than rejecting. This is confirmed intentional by the test comment at publish_test.go:130: "The legacy path was dropped and re-added once already (1e16b3b)" — so it sounds like this was a deliberate reversal after the description was written. Worth updating the PR description so it doesn't mislead reviewers/changelog readers, unless the intent is still to remove this path in a follow-up.

2. Bundle DereferenceSchemas no longer processes Artifacts or UI

internal/bundle/dereference.go — the tasks list dropped the Artifacts (was stripID: false) and UI (was stripID: true) entries, leaving only Params and the new dependencySchema. This looks like a byproduct of the resources/dependencies migration earlier in this branch (commit d4e9921) rather than something introduced by the OCI work itself, but it's a behavior change for any bundle that puts a $ref inside its ui block or legacy artifacts block — those refs will no longer be resolved. Given the PR notes claim "bundle behavior is unchanged," it'd be good to confirm this was intentional (e.g. ui never legitimately contained $refs in practice) rather than an accidental regression carried along in the branch.

Minor/non-blocking:

  • internal/commands/resourcetype/publish.go:263 checkDuplicateVersion requires the OCI repo to already exist (via create) before a first publish — consistent with bundle's getVersion, so this is intentional, just flagging that it's a hard dependency on resource-type create having been run first.
  • Nothing else stood out as a correctness/security issue; convert's filename sanitization (sanitize/uniqueRel in convert.go) correctly prevents path traversal from schema-derived labels.

I wasn't able to run go build/go test in this sandbox (network/tool approval restrictions), so please make sure CI is green — the review above is based on static reading of the diff only.

@chrisghill
chrisghill merged commit 1c0d1d7 into main Sep 2, 2026
5 checks passed
@chrisghill
chrisghill deleted the resource-type-oci branch September 2, 2026 04:56
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