### Summary
Fix https://github.com/elastic/kibana/issues/166688
Implements dynamic contract resolving for plugins, allowing to retrieve
contracts after their respective lifecycle is completed, and therefore
working around cyclic dependencies.
In term of workflow execution, we're basically going from
<img width="842" alt="Screenshot 2023-09-27 at 08 09 27"
src="251637d1-ec97-4071-a445-2f59512ce187">
to:
<img width="1092" alt="Screenshot 2023-09-27 at 08 09 32"
src="de466cda-7e43-4fd3-81ec-4339d05d279d">
### API
This functionality is exposed by the now publicly exposed `plugins`
service contracts:
```ts
setup(core) {
core.plugins.onSetup<{pluginA: SetupContractA, pluginB: SetupContractA}>('pluginA', 'pluginB')
.then(({ pluginA, pluginB }) => {
if(pluginA.found && pluginB.found) {
// do something with pluginA.contract and pluginB.contract
}
});
}
```
```ts
start(core) {
core.plugins.onStart<{pluginA: StartContractA, pluginB: StartContractA}>('pluginA', 'pluginB')
.then(({ pluginA, pluginB }) => {
if(pluginA.found && pluginB.found) {
// do something with pluginA.contract and pluginB.contract
}
});
}
```
**remark:** the `setup` contract exposed both `onSetup` and `onStart`,
while the `start` contract only exposed `onStart`. The intent is to
avoid fully disrupting the concept of lifecycle stages.
### Guardrails
To prevent developer from abusing this new API, or at least to add some
visibility on its adoption, plugins can only perforn dynamic contract
resolving against dependencies explicitly defined in their manifest:
- any required dependencies (*existing concept*)
- any optional dependencies (*existing concept*)
- any runtime dependencies (**new concept**)
Runtime dependencies must be specified using the new
`runtimePluginDependencies` field of a plugin's manifest.
```json
{
"type": "plugin",
"id": "@kbn/some-id",
"owner": "@elastic/kibana-core",
"plugin": {
"id": "some-id",
"...": "...",
"runtimePluginDependencies" : ["someOtherPluginId"]
}
}
```
Using the contract resolving API will throw at call time when trying to
resolve the contract for an undeclared dependency.
E.g this would throw at invocation time (not returning a rejected
promise - throw).
```ts
setup(core) {
core.plugins.onSetup<{undeclaredDependency: SomeContract}>('undeclaredDependency');
}
```
The reasoning behind throwing is that these errors should only occur
during the development process, and an hard fail is way more visible
than a promise rejection that should be more easily shallowed.
### Code reviews
This PR defines @elastic/kibana-core as codeowner of all `kibana.jsonc`
files in the `src/plugins` and `x-pack/plugins` directories, so that a
code review will be triggered whenever anyone changes something in any
manifest. The intent is to be able to monitor new usages of the feature,
via the addition of entries in the `runtimePluginDependencies` option of
the manifest.
### Remarks
Exposing this API, and therefore making possible cyclic dependencies
between plugins, opens the door to other questions.
For instance, cross-plugin type imports are not technically possible at
the moment, given that plugins are referencing each others via TS refs,
and refs forbid cyclic dependencies. Which means that to leverage this
to address cyclic dependency issues, the public types of **at least one
of the two** plugins will have to be extracted to a shared place (likely
a package).
Resolving, or trying to improve the developer experience around this
issue, is absolutely out of scope of the current PR (and the issue it
addresses).
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
## Summary
Addresses #157341
The error comes because STDERR by default is piped to the parent
process's stderr.
- Quench error output of git rev-parse
### Checklist
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This PR improves the detection of when a given plugin comes from inside
a build folder without including any external dependency for a local
package (not supported here due to kbn_pm).
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Fixes https://github.com/elastic/kibana/issues/149344
This PR migrates all plugins to packages automatically. It does this
using `node scripts/lint_packages` to automatically migrate
`kibana.json` files to `kibana.jsonc` files. By doing this automatically
we can simplify many build and testing procedures to only support
packages, and not both "packages" and "synthetic packages" (basically
pointers to plugins).
The majority of changes are in operations related code, so we'll be
having operations review this before marking it ready for review. The
vast majority of the code owners are simply pinged because we deleted
all `kibana.json` files and replaced them with `kibana.jsonc` files, so
we plan on leaving the PR ready-for-review for about 24 hours before
merging (after feature freeze), assuming we don't have any blockers
(especially from @elastic/kibana-core since there are a few core
specific changes, though the majority were handled in #149370).
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This PR updates the core discovery logic to support loading plugins from
packages. This logic is additive, so that the existing plugins in the
repo and third-party plugins can continue to be loaded via the existing
mechanism, but with https://github.com/elastic/kibana/pull/148130 we
will be automatically migrating all plugins in the repo to packages,
which will use this logic.
The logic is already in-use in that PR, and was developed there, but
extracted here for easier review.
The logic is relatively simple, where a list of packages in the repo are
attached to the core `Env` and then filtered by core before converting
all plugin packages to `PluginWrapper`. The `PluginWrapper` still
exposes the plugin manifest to the rest of the code, and it is used in
many places, so rather than making changes to the `PluginWrapper` I'm
faking a legacy plugin manifest with the plugin package manifest.
@elastic/kibana-core: I'm going to need some help identifying what we
need to get test coverage for. This is a pretty simple addition to the
core IMO, and if it didn't work then nothing would work, so I'm pretty
confident in it, but would still appreciate your feedback.
This PR ads a new cli package to allow us to search for package
locations by providing their IDs. I see this as useful as we start
adding more and more packages across different locations.
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This PR implements a linter like the TS Project linter, except for
packages in the repo. It does this by extracting the reusable bits from
the TS Project linter and reusing them for the project linter. The only
rule that exists for packages right now is that the "name" in the
package.json file matches the "id" in Kibana.jsonc. The goal is to use a
rule to migrate kibana.json files on the future.
Additionally, a new rule for validating the indentation of tsconfig.json
files was added.
Validating and fixing violations is what has triggered review by so many
teams, but we plan to treat those review requests as notifications of
the changes and not as blockers for merging.
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>