Files
summercms/.planning/notes/core-plugins-own-repos.md
Jakub Zych 947aabee93 docs: move golem15.user to sm-user-plugin and supersede the Phase 1 extraction deferral
- new note .planning/notes/core-plugins-own-repos.md: shared core plugins live in sm-<name>-plugin repos mounted as submodules
- 01-CONTEXT deferral points to the note; PROJECT constraint and Key Decisions row
- ROADMAP Phase 12 repos and the 12-01 entry, and Phase 12 plans 12-01, 12-02, 12-05 name sm-user-plugin and the submodule commit workflow
2026-10-02 11:02:07 +02:00

3.6 KiB

Decision: Shared core plugins live in their own sm-*-plugin repos

Date: 2026-10-02
Status: Accepted
Context: quick task 261002-esz (extract golem15.user from fonoteka.go)
Supersedes: the Phase 1 deferred item "Extraction of shared stack plugins into their own repos — only when a second app (keios.eu) needs one" (.planning/phases/01-framework-kernel-foundation/01-CONTEXT.md)

Decision

Shared core plugins live in their own repositories, git.golem15.com/golem15/sm-<name>-plugin, starting with the user plugin and followed by blog, pages, payment and the other cross-project Golem15 plugins as they are ported.

  • The Go module path equals the repo path: git.golem15.com/golem15/sm-<name>-plugin. The Go package and the plugin ID keep their plain names, so the user plugin is still package user and plugin golem15.user.
  • Each application mounts them as git submodules at plugins/<vendor>/<name>, lists them in go.work and adds a require plus a local replace git.golem15.com/golem15/sm-<name>-plugin => ./plugins/<vendor>/<name> to its go.mod, and names the module in summer.yaml.
  • The plugin's own go.mod replaces the framework with ../../../../summercms.go, which resolves when the plugin is mounted at <app>/plugins/<vendor>/<name> next to the framework checkout.
  • Application-specific plugins, such as golem15.fonoteka, stay in the application repository.

Trigger

The Phase 1 deferral waited for a second application. One now exists: sm-summercmsio-app, which already mounts its site plugin sm-summercmsio-plugin as a submodule at plugins/golem15/summercms (the layout precedent this note generalises). The Journal port is next and needs the same user plugin. Keeping one copy per core plugin avoids forks between applications.

How it was done for golem15.user

  • The plugin's history was split out of fonoteka.go with git subtree split --prefix=plugins/golem15/user (21 commits, tree byte-identical to the in-tree directory) and pushed as master of git@git.golem15.com:golem15/sm-user-plugin.git.
  • fonoteka.go mounts it back as a submodule at the same path, plugins/golem15/user, so go.work did not change.
  • The module was renamed to git.golem15.com/golem15/sm-user-plugin in the plugin repo, and every importer in fonoteka.go (app, parity, the fonoteka plugin, both go.mod files, summer.yaml, the regenerated plugins.gen.go) followed.
  • No behaviour change: plugin ID, tables, migration IDs, config keys golem15.user.*, routes and payloads are unchanged. The plugin gained a go mod tidy for standalone module mode and a README.

Workflow

  • Change a submodule plugin inside its checkout (git -C <app>/plugins/<vendor>/<name>): commit there and push its master first, then commit the bumped pointer in the application repo as a separate commit.
  • Never stage files inside a submodule from the application repo.
  • Core plugin contracts (routes, payloads, tables, migration IDs, config keys) stay non-breaking unless the user asks, because several applications mount the same plugin.

Consequences and follow-ups

  • A plugin README never names a consuming application; it says "the application" or "host application" and uses neutral examples.
  • TestRegisterCORSPath in the user plugin reads the host application's config/http.yaml, so the plugin's full test suite runs only inside an application checkout. Making it self-contained is a follow-up.
  • Two code comments in the user plugin (models/organisation.go, updates/10_organisations.go) still name the first consuming application; they were left unchanged in the pure move.
  • fonoteka.go itself becoming sm-fonoteka-app is a separate pending rename.