Open
Description
What should it be?
- it should allow adding additional functionality to Gitea without bloating the main binary or being responsible for maintaining it
- it should not allow to modify the core functionality of Gitea
Architecture
Plugins are called using(see discussion below, was generally disliked)Go
splugin
package.- Plugins are called over RCP using the go-plugin package.
- Reasons:
- active community to maintain the package
- works on every platform and even across languages
- minimalistic and understandable -> no technical debt to have to consider
- OS is responsible for setting plugin resource limits, not Gitea
- Protocol versioning built-in
- Reasons against that architecture:
- requests over RCP make everything slow
- extra dependency
- vendor lock-in for plugins to
go-plugin
Communication: Gitea ➡️ plugin ➡️ Gitea
- common data structures and methods needed
- recommendation: an extra package that both Gitea and the plugins use
- during application startup, Gitea should use the package from the receiver side and the plugins from the sender side
- while dispatching calls to the plugins, the roles should be switched around so that Gitea becomes the sender and the plugins the receivers
- things that plugins, as well as Gitea, should have access to (at best only as a wrapper that is set once at runtime because the underlying implementation can change quite often):
- especially things located in
modules/
: - logger
- context
- i18n
- especially things located in
- again, to avoid vendor lock-in, this package cannot depend on anything that it doesn't define on its own, or is provided by Go itself
- to reduce the chance of plugins breaking with a new Gitea release, this extra package should be developed to be "all-inclusive" from the beginning meaning that it entails everything a plugin might wish to configure
- it is recommended that the extra package uses easily extendable data structures, i.e.
map[string]?
, where possible to avoid breaking changes
- it is recommended that the extra package uses easily extendable data structures, i.e.
Communication: plugin ➡️ Gitea ➡️ plugin
- Let Plugins use the Gitea API when requesting additional information from Gitea. Reasons:
- easy to implement (literally NO work at all 😃 )
- easy to maintain (again, because there is literally NO code to maintain 😃 )
- safe to use for the plugins because the API guarantees stability
- API gets used more, hence more people want to see it well-maintained and there is an actual incentive to add an API for a feature that at that moment only exists for the web UI
- Reasons against this approach:
- slow, because it will always require HTTP requests
- plugins need to parse the answer instead of simply being able to use a predefined method/ datatype
Plugin Lifecycle (What the plugins can set/ "use")
- Plugin Initialization
-
Application is completely initialized and running
- Hook - Plugin Dependencies (to Gitea (versions), to other plugins?)
- Setting Plugin-wide settings as well while parsing the server-wide settings (requires (a) section(s) reserved for plugins)
- Custom translation keys to allow for localized new features
- Adding custom tabs to different units:
- most basic:
- user
- org
- user+org
- all repos
- public repo
- private repo
- additionally possible:
- issue
- PR
- projects
- packages
- ...
- to make parsing this easier, it would probably be good to use an approach that allows setting a list of tags where this tab will be shown. Problem: How to handle
OR
/AND
relations (depending on the chosen algorithm)?
- Adding consistency checks
- Cron Job Hooks?
- Shutdown Hook
What data is needed by every/ some plugin(s)?
- unique plugin name (i.e. by following reverse naming such as
io.gitea.example_plugin
) - human printable plugin name (i.e.
Example Plugin V1
) - plugin version in semver form
- list of core units affected by this plugin (rather as a code of honor the plugin intends to keep than a security feature)
- dependencies to other plugins
- custom translations/ translation files
- custom settings/ setting files
- custom web routes
- custom API routes (problem: how to update the swagger file with the new operations?)
- provided hooks
- minimum Gitea version the plugin needs
Why this long text rambling?
- Everyone should know without a doubt how it should look like in the end
- To make the work for the (eventual) reviewers easier by simply letting them cross-check the actual functionality with its intention
- Most of the text I wrote here can be copy-pasted into the docs, making it easier for me to write the docs
- To allow for discussion if I missed something while planning this feature
- To see if the scope others expect from this feature differs from what I imagine from it