Skip to content

[Bug]: bundle install does not scaffold extension config templates #4283

Description

@emdfonseca

What happened

specify bundle install installs an extension without scaffolding the config templates the extension declares in provides.config. Installing the same extension with specify extension add does scaffold them.

Extension manifest:

provides:
  config:
    - name: github-lifecycle-config.yml
      template: config-template.yml

After specify extension add --dev <path>:

Config scaffolded:
  • .specify/extensions/github-lifecycle/github-lifecycle-config.yml

After specify bundle install <bundle-id>, with the same extension resolved from a catalog:

$ ls .specify/extensions/github-lifecycle/
CHANGELOG.md  README.md  commands  config-template.yml  extension.yml  scripts

The template is present, but the config file it is meant to produce is not.

Cause

ExtensionManager.scaffold_config is called from the extension add command flow in src/specify_cli/extensions/_commands.py:

# Scaffold config templates automatically
deployed, skipped, failed = manager.scaffold_config(manifest.id)

ExtensionPrimitive in src/specify_cli/bundler/services/primitives.py calls install_from_directory / install_from_zip directly and never calls scaffold_config, so the bundler path skips it.

Version

Reproduced on v1.0.1 (macOS, Python 3.13).

Impact

An extension installed as part of a bundle silently has no configuration. Any command or script that reads the config finds nothing, and the difference is invisible unless the user compares the two install paths. It also means an extension behaves differently depending on how it was installed, which makes bundle installation not equivalent to installing its components individually.

Suggested fix

Call scaffold_config from ExtensionPrimitive after install, and surface the same deployed/skipped/failed reporting the command flow produces.

Related

The naming rule enforced by _target_follows_preserved_convention (a config target must be a top-level *-config.yml or *-config.local.yml) is not documented in EXTENSION-API-REFERENCE.md. A manifest that declares any other target name is accepted at publish time and silently never scaffolds, reporting only Warning: Config templates not scaffolded: <name> with no explanation of the constraint. Documenting the rule, or naming it in that warning, would make the failure self-explanatory.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions