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

40 lines
3.6 KiB
Markdown

# 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.