Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Bazel #92758

Merged
merged 11 commits into from
Mar 16, 2021
Merged

[RFC] Bazel #92758

merged 11 commits into from
Mar 16, 2021

Conversation

tylersmalley
Copy link
Contributor

@tylersmalley tylersmalley commented Feb 25, 2021

Request for comment for migrating Kibana to Bazel. Requests close March 9th, 2021

Rendered: https://github.com/tylersmalley/kibana/blob/rfc-bazel/rfcs/text/0015_bazel.md

#10908

@tylersmalley tylersmalley added RFC Team:Operations Team label for Operations Team labels Feb 25, 2021
@tylersmalley tylersmalley marked this pull request as ready for review February 25, 2021 06:42
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-operations (Team:Operations)

@tylersmalley tylersmalley added release_note:skip Skip the PR/issue when compiling release notes v8.0.0 labels Feb 25, 2021
Signed-off-by: Tyler Smalley <tyler.smalley@elastic.co>
Signed-off-by: Tyler Smalley <tyler.smalley@elastic.co>
rfcs/text/0015_bazel.md Outdated Show resolved Hide resolved
@mistic mistic mentioned this pull request Feb 26, 2021
23 tasks
rfcs/text/0015_bazel.md Outdated Show resolved Hide resolved
Co-authored-by: Jonathan Budzenski <jon@budzenski.me>
rfcs/text/0015_bazel.md Outdated Show resolved Hide resolved
Co-authored-by: Jonathan Budzenski <jon@budzenski.me>
Copy link
Contributor

@spalger spalger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks great, just a little note about running bazel and package builds in "parallel" via kbn/pm

rfcs/text/0015_bazel.md Outdated Show resolved Hide resolved
Co-authored-by: Spencer <email@spalger.com>
Copy link
Member

@mistic mistic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aside from my above comment on a typo I've found, LGTM

Signed-off-by: Tyler Smalley <tyler.smalley@elastic.co>

In this phase, we will be migrating each of the 135 plugins over to being built and unit tested using Bazel. During this time, the legacy systems will stay in place and run in parallel with Bazel. Once all plugins have been migrated, we can decommission the legacy systems.

The `BUILD.bazel` files will look similar to that of packages, there will be a target for `web`, `server`, and `jest`. Just like packages, as the Jest unit tests are migrated, they will need to be removed from the root `jest.config.js` file as described in the Unit Testing section.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it mean we are going to have different configuration files for every Environnement? tsconfig.server.js, tsconfig.web.js, tsconfig.jest.js, etc.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It only means we will have rules to build web and server separately as we currently have plugins who use different compilers for each target. The configuration part is up to us. Regarding jest target it will rely on the previous builds for web and server but it just means we will have a target to run tests all at once for a given package \cc @tylersmalley

Copy link
Contributor Author

@tylersmalley tylersmalley Mar 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, we only have a single tsconfig.js file so we can use its output as the source of multiple targets. However, if we find we need or want separate configurations for different actions we do have that flexibility.

rfcs/text/0015_bazel.md Outdated Show resolved Hide resolved
Copy link
Contributor

@joshdover joshdover left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Questions:

  • Will we integrate FTR with this? If so, what new things will we be able to do with e2e tests?
  • Can we have nested Bazel packages? If so, are there any caveats to be aware of with this and JavaScript?
  • How will we integrate the output of Bazel's webpack build with the Kibana server? For instance, right now we have the optimizer_mixin which exposes the routes for webpack outputs and will wait for this process to complete before attempting to serve these files. How will we do this when Bazel is building these webpack outputs?

rfcs/text/0015_bazel.md Outdated Show resolved Hide resolved
rfcs/text/0015_bazel.md Outdated Show resolved Hide resolved

The `BUILD.bazel` files will look similar to that of packages, there will be a target for `web`, `server`, and `jest`. Just like packages, as the Jest unit tests are migrated, they will need to be removed from the root `jest.config.js` file as described in the Unit Testing section.

Plugins are built in a sandbox, so they will no longer be able to use relative imports from one another. For Typescript, relative imports will be replaced with a path reference to the `bazel/bin`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add an example of what this would look like in code? I think how these imports work is an important aspect of how well this tool will fit into our repo. It may also impact how we consider implementing #71566 and enforce encapsulation between plugins & domains.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that we should elaborate on this change and discuss it with a wider audience. A dedicated e-mail to kibana-contributors@ would be great.

Copy link
Contributor Author

@tylersmalley tylersmalley Mar 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Started #94034 to attempt to get a consensus on this. Will pass it around to a few folks before blasting kibana-contributors.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @tylersmalley.

rfcs/text/0015_bazel.md Outdated Show resolved Hide resolved
tylersmalley and others added 2 commits March 8, 2021 15:18
Co-authored-by: Josh Dover <1813008+joshdover@users.noreply.github.com>
Co-authored-by: Josh Dover <1813008+joshdover@users.noreply.github.com>
Signed-off-by: Tyler Smalley <tyler.smalley@elastic.co>
@tylersmalley
Copy link
Contributor Author

@joshdover

Will we integrate FTR with this? If so, what new things will we be able to do with e2e tests?

This is something I have been giving thought to, but there are no concrete plans yet. Conceptually, we could entirely replace the FTR runner with Bazel to run Elasticsearch, Kibana, and the tests. There is an old video of Dropbox discussing this https://www.youtube.com/watch?v=muvU1DYrY0w

Can we have nested Bazel packages? If so, are there any caveats to be aware of with this and JavaScript?

None that I am aware of. - @mistic?

How will we integrate the output of Bazel's webpack build with the Kibana server? For instance, right now we have the optimizer_mixin which exposes the routes for webpack outputs and will wait for this process to complete before attempting to serve these files. How will we do this when Bazel is building these webpack outputs?

I think this is an important part that should be included in the RFC, will work on adding it now and will ping you when it's complete.

@mistic
Copy link
Member

mistic commented Mar 9, 2021

Can we have nested Bazel packages? If so, are there any caveats to be aware of with this and JavaScript?

On Bazel language there is nested packages all over the place. But probably you are thinking about other cases. Can you give a concrete example to see if we can spot any caveats? At my first thoughts I think there won't be any special ones. \cc @joshdover

Signed-off-by: Tyler Smalley <tyler.smalley@elastic.co>
rfcs/text/0015_bazel.md Outdated Show resolved Hide resolved
Co-authored-by: Spencer <email@spalger.com>
@tylersmalley
Copy link
Contributor Author

@joshdover, added a note regarding the handling updates in development: https://github.com/elastic/kibana/pull/92758/files#diff-d3251298ab06494dfe78a21d16139be95192295555d9a3115799a81a30415478R79

Building TypeScript reference definitions and using `@babel/register` will be negated by using the TypeScript compiler directly instead of using Babel. Currently, we use Babel for code generation and `tsc` for type check and type declaration output. Additionally, the TypeScript implementation in [rules_nodejs](https://bazelbuild.github.io/rules_nodejs/TypeScript.html) for Bazel handles incremental builds, resulting in faster re-builds.

In addition to the benefits of building code, there are also benefits regarding running unit tests. Developers currently need to understand what unit tests to run to validate changes or rely on waiting for CI, which has a long feedback loop. Since Bazel knows the dependency tree, it will only run unit tests for a package or plugin modified or dependent on those modifications. This optimization helps developers and will significantly reduce the amount of work CI needs to do. On CI, unit tests take 35 minutes to complete, where the average single Jest project takes just twenty seconds.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unit tests are our least problem. We can use the migration to bazel as an opportunity to finally start functional tests separation by domain structure. @elastic/kibana-operations Do you anticipate any problems with this? We can use Core as a guinea pig.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see no problem with this, and I plan to work towards moving functional tests to have a plugin owner where they will reside. There are a lot of benefits to this, including clear ownership for functional tests to assist with tooling and how we report failures. In addition, it would help get us on a path to reducing the number of functional tests we run by default on a pull request. Bazel provides the ability to query the action graph to understand what packages are affected by a change. We can use this, and additional configuration on the plugins to determine which functional tests should be run by default while allowing the PR to request additional tests to be run.


Developers currently use `yarn test:jest` to efficiently run tests in a given directory without remembering the command or path. This command will continue to work as it does today, but will begin running tests through Bazel for packages or plugins which have been migrated.

CI will have an additional job to run `bazel test //…:jest`. This will run unit tests for any package or plugin modified or dependent on modifications since the last successful CI run on that branch.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain "dependent on modifications"

Core (as well as other plugins) maintains many mocks that are used by other plugin's unit tests. Would a change in a mock result in unit tests being run for all the tests that import that mock?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As it currently stands, yes. The mocks are inputs into the test actions, and if those change the downstream tests will be re-run.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are ways to combat this by isolating the mocks with a separate filegroup which would be consumed by the downstream projects.

@joshdover
Copy link
Contributor

Can we have nested Bazel packages? If so, are there any caveats to be aware of with this and JavaScript?

On Bazel language there is nested packages all over the place. But probably you are thinking about other cases. Can you give a concrete example to see if we can spot any caveats? At my first thoughts I think there won't be any special ones. \cc @joshdover

I'm curious if we can support a nested structure like this:

x-pack/
  observability/
    BUILD <- where this package exposes a subset of APIs from `o11y_lib` and `apm` to other packages
    apm/
      BUILD
    logs/
      BUILD
    o11y_lib/
      BUILD

@tylersmalley
Copy link
Contributor Author

tylersmalley commented Mar 10, 2021

I'm curious if we can support a nested structure like this...

@joshdover, absolutely. We have discussed breaking out portions of plugins that have very little churn. If there is a large portion of code within a plugin that doesn't frequently change, it might make sense to add a BUILD.bazel file within that portion to create those assets separately. This would decrease the scope and in-turn the time it would take to build the plugin. Lots of options.

Copy link
Contributor

@joshdover joshdover left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super excited about this and looking forward to all the improvements. Thanks for taking the time to write all this out so we can clearly document our decisions!

@tylersmalley tylersmalley removed the request for review from stacey-gammon March 11, 2021 16:04
@tylersmalley
Copy link
Contributor Author

Seeing no pending feedback, I am going to merge the RFC. If any questions come up, don't hesitate to reach out.

@tylersmalley tylersmalley added the backport:skip This commit does not require backporting label Mar 16, 2021
@tylersmalley tylersmalley merged commit d02169e into elastic:master Mar 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:skip This commit does not require backporting release_note:skip Skip the PR/issue when compiling release notes RFC Team:Operations Team label for Operations Team v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.