Skip to content

feat: make catalog add idempotent across all catalog families (#4505) - #43

Closed
mnriem wants to merge 1 commit into
mainfrom
mnriem-catalog-add-upsert
Closed

mnriem wants to merge 1 commit into
mainfrom
mnriem-catalog-add-upsert

Conversation

@mnriem

@mnriem mnriem commented Sep 11, 2026

Copy link
Copy Markdown
Owner

Summary

Addresses #4505. Today every catalog add command fails when a matching entry already exists, which forces workflow authors to add their own duplicate-detection/remove-then-add logic around a command that may run repeatedly.

This makes catalog add idempotent, implementing the feature assessment's recommended Option A — "idempotent no-op for equivalent entries":

  • Identical rerun → successful no-op (exit code 0), so the same catalog add is safe inside a re-runnable workflow.
  • Same identity but different flags → conflict (exit code 1). We deliberately do not silently overwrite priority/install permissions — the user is told to remove the entry first. (Overwrite is Option B, explicitly out of scope for the recommended option.)
  • New entry → added, exactly as before.
  • Existing URL/config validation and safety failures are preserved unchanged.

Scope — all six catalog families

Command Identity key Equivalence compares
specify extension catalog add catalog name url, priority, install_allowed, description
specify preset catalog add catalog name url, priority, install_allowed, description
specify integration catalog add catalog url name (or none supplied)
specify workflow catalog add catalog url name (or none supplied)
specify workflow step catalog add catalog url name (or none supplied)
specify bundle catalog add source id or url policy, priority

Implementation notes

  • The URL-identity class methods (IntegrationCatalog/WorkflowCatalog/StepCatalog.add_catalog) now return "added" / "unchanged" so the CLI can report the no-op; a same-URL add with a different --name raises a conflict.
  • bundler.commands_impl.catalog_config.add_source now returns (CatalogSource, status).
  • Extension/preset CLI commands compare the requested flags against the stored entry inline and either no-op or error.

Tests & docs

  • Updated the former "duplicate rejected" tests to the new semantics and added no-op + conflict coverage per family (extension, preset, integration, workflow, step, bundle).
  • Documented the idempotent behavior in the five reference docs (extensions, presets, workflows, integrations, bundles).
  • Full relevant suites pass locally: 5147 passed, 5 skipped.

Family checklist

  • extension catalog
  • preset catalog
  • integration catalog
  • workflow catalog
  • step catalog
  • bundle catalog

This pull request was authored autonomously by GitHub Copilot (model: Claude Opus 4.8) on behalf of @mnriem.

…#4505)

Rerunning `catalog add` for an already-configured entry now succeeds as a
no-op instead of failing, so the command is safe inside re-runnable
workflows. This implements the assessment's recommended Option A
("idempotent no-op for equivalent entries"): an identical rerun exits 0,
while a request that matches an existing entry's identity but supplies
different settings is rejected as a conflict rather than silently
overwriting priority/install permissions.

Applied consistently to all six families:
- extension / preset  — identity = catalog name
- integration / workflow / step — identity = catalog URL
- bundle — identity = source id or url

The URL-identity class methods now return "added"/"unchanged" so the CLI
can report the no-op, and bundle add_source returns (source, status).
Updates duplicate-add tests to the new semantics, adds no-op + conflict
coverage per family, and documents the behavior in the reference docs.

Assisted-by: GitHub Copilot (model: Claude Opus 4.8, autonomous)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@mnriem

mnriem commented Sep 11, 2026

Copy link
Copy Markdown
Owner Author

Superseded by the upstream PR against github/spec-kit (this fork PR was created automatically against the fork's own main by mistake).

@mnriem mnriem closed this Sep 11, 2026
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.

1 participant