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] Clarifying Semantic Versioning for OpenSearch Dashboards #9491

Open
ashwin-pc opened this issue Mar 5, 2025 · 6 comments
Open

[RFC] Clarifying Semantic Versioning for OpenSearch Dashboards #9491

ashwin-pc opened this issue Mar 5, 2025 · 6 comments

Comments

@ashwin-pc
Copy link
Member

Summary

This RFC proposes a refined Semantic Versioning (SemVer) policy for OpenSearch Dashboards. It explicitly separates internal npm dependencies from the semver public contract, reduces the likelihood that internal changes will cause breaking version bumps, and provides examples illustrating when a dependency update affects the public API (and thus semver) versus when it does not.

Background

OpenSearch Dashboards currently treats many aspects of its platform—including npm dependencies, server APIs, and the UI—as part of its semver contract. In particular:

  • Plugin Dependencies: Plugins share many core npm dependencies with the platform. Upgrading or changing a dependency version can cause plugin authors to modify their implementations, even if the public contract remains untouched.
  • Server APIs: The server exposes documented APIs used by plugins and external consumers.
  • UI Changes: Significant UI updates have also been considered potentially breaking, though the criteria for what qualifies as a breaking UI change is not always clear.
    This broad interpretation of what counts as a semver-breaking change has made it difficult to address security fixes and internal improvements without triggering a major version increment.

Motivation

  1. Security Fixes Without Major Releases: Enable prompt patching of vulnerabilities without forcing plugin developers to react to an unnecessary major version bump.
  2. Clear Separation of Internal vs. Public: Provide explicit guidance to distinguish changes that affect external plugin authors or users from internal implementation details.
  3. Predictable Release Cycles: Reduce friction and confusion for plugin maintainers, ensuring that semver-breaking updates only occur when a documented public interface truly changes.
  4. Better Communication: Clarify what “public contract” means, so contributors and users know precisely which changes are considered breaking, minor, or patches.

Proposal

1. Defining the Public Contract

Principle: A “public contract” is any interface or behavior that is:

  • Documented:
    Covered in official documentation or API references explicitly intended for external consumption (e.g., plugin APIs, server endpoints).
  • Stability-Promised:
    Declared stable and supported across releases unless a deliberate version bump is communicated.
  • Externally Consumed:
    Relied upon by third-party developers or users, such that any change would require them to alter their code or workflows.
  • Impactful When Altered:
    Modifications would force external consumers to update their implementations or significantly change their usage patterns.

Public Contract Checklist

Ask these questions when determining if a change affects the public contract:

  1. Is it explicitly documented as part of our public API or UI behavior?
  2. Is it intended for and used by plugin developers or end users (externally)?
  3. Would a change force external consumers to adjust their code or workflows?
  4. Have we promised stability for it across releases?
    If all answers above are “yes,” changes to that interface are semver-breaking. Otherwise, the change can be classified as internal.

2. Excluding npm Dependencies from Semantic Versioning

Because of the coupled architecture, npm dependencies are often shared between OpenSearch Dashboards and its plugins, causing updates to affect plugin builds. This policy explicitly excludes npm dependency changes from semver unless they alter a documented, stable public interface.

  1. Internal vs. Public Impact:
    • Internal Updates: Any upgrade or addition to npm dependencies that does not alter a documented API or plugin interface is considered an internal change.
      Example: Upgrading from [email protected] to [email protected] to address a security fix. The plugin API or behavior doesn’t change, so this is not a breaking change.
    • Public Interface Changes: If a dependency upgrade does modify a documented function, endpoint, or behavior on which plugins rely, it is a breaking change.
      Example: Migrating from lodash@4 to lodash@5 means that we cannot support a data plugin API that directly exposes a lodash API that changes with the version upgrade
  2. Handling New Dependencies: When core introduces a new npm dependency that plugins might already use, it is not considered breaking unless it forces changes in the documented public interface.

Objective: Decouple the semver contract from routine npm dependency updates, so only true API/behavioral changes trigger a major version bump.

3. Versioning Rules

OpenSearch Dashboards adopts Semantic Versioning 2.0.0 with the following structure:

  • Major Version (X): Introduces breaking changes to the documented public contract (e.g., plugin APIs, server APIs, or UI behaviors that are explicitly supported).
    • Deprecations planned for removal can also occur here.
  • Minor Version (Y): Adds new, non-breaking features or enhancements to the public contract.
    • Includes additions to server APIs, new plugin APIs, or UI enhancements that do not disrupt existing usage.
  • Patch Version (Z): Contains backward-compatible bug fixes, security patches, or internal improvements.
    • Npm dependency upgrades that do not alter the public contract fall into this category.

4. UI Versioning Considerations

While UI changes can sometimes be disruptive, the RFC distinguishes:

  • UI as a Public Contract: If the UI includes documented user experiences or extension points (e.g., plugin injection points, UI event hooks), then changes to these behaviors are considered breaking.
  • Cosmetic or Minor Changes: Layout or style updates that do not affect documented plugin interactions or user workflows should be classified as internal, and thus only require a patch or minor release if they are purely additive.

5. Deprecation Policy

To provide clarity on when features or interfaces will be removed:

  1. Announce Deprecation: Clearly mark deprecated features in release notes, documentation, and console/log warnings.
  2. Provide a Timeline: Maintain support for deprecated features for at least one minor release cycle before removal in the next major version.
  3. Migration Guidance: Offer instructions on how to transition away from deprecated features.

6. Implementation Plan

Once this RFC is closed we can add a SEMVER.md file in the repository to outline these rules, including the examples of internal vs. public changes.

Feedback required

The feedback that this RFC is looking for is

  1. Feedback from plugin developers, end users, and maintainers on the proposed policy
  2. Use cases to further refine the guidance around “public contract” boundaries
@ashwin-pc ashwin-pc pinned this issue Mar 5, 2025
@kavilla
Copy link
Member

kavilla commented Mar 5, 2025

Makes sense:

Is there a designated location we are planning where the public contract is documented and maintained? I see the SEMVER.md is an examples.

What is the process for determining if a change affects the public contract? And can plugins proposed something is a public contract or will it be only maintainers that determine the public contract. Will there be a regular review on the public contract?

For breaking changes as a maintainer, do we have a process? Should we get agreement among stakeholders or just maintainers that this breaking change makes sense? We should also label the PR with the breaking change label so it's easier to find these PRs at the time of major version release.

Should we have policies on deprecation and timelines? Since we have a lot of long running deprecated stuff.

@seraphjiang
Copy link
Member

i like the idea to remove treating npm/internal change as breaking

About doc:

regarding doc, we already using openapi to doc doc, we should continue to use it for all existing public api and new api

https://github.com/opensearch-project/OpenSearch-Dashboards/tree/9ecb66d46c7f07209db8076987fa4d2771379c71/docs/openapi

About dependencies/interface
as a frontend project, I would like to see we clarify what does UI behavior as contract mean.
what i mean, we should specific call out the global CSS, global variable, code level interface, public rest api, as well as key dependencies like Oui

about versioning Rules,
it should be suggested, but not mandatory, as far as today, OSD version bump up regardless major/minor/patch is driven by OpenSearch release instead of OSD's own need.
distribution is binded with OpenSearch, that means, even if there is no any change, we have to bump up OSD version. we should also address this in our roadmap. #9192

while the rfc is aim to discuss Semantic Versioning for OSD, from content it is mainly focus on developer's view, while we should be open to bump up version for new feature and change that don't introduce any break change.

@ashwin-pc
Copy link
Member Author

Is there a designated location we are planning where the public contract is documented and maintained? I see the SEMVER.md is an examples.

@kavilla Yes we will have a single place where this is documented. I think as @seraphjiang mentioned, the openapi doc has already been started, we will need to add to that. We can also just specify for now in a api.md file what the API's are and link to the openAPI docs where it makes sense.

What is the process for determining if a change affects the public contract? And can plugins proposed something is a public contract or will it be only maintainers that determine the public contract. Will there be a regular review on the public contract?

This will be defined in the semver.md file which requires approvals from maintainers before its changed

For breaking changes as a maintainer, do we have a process? Should we get agreement among stakeholders or just maintainers that this breaking change makes sense? We should also label the PR with the breaking change label so it's easier to find these PRs at the time of major version release.

Thats not something i want to cover here. This is just to clarify the semantic versioning definition for OSD. The process to enforce it can come later. Lets make sure we agree on the definition first.

Should we have policies on deprecation and timelines? Since we have a lot of long running deprecated stuff.

I have a section on that inthe RFC


as a frontend project, I would like to see we clarify what does UI behavior as contract mean.
what i mean, we should specific call out the global CSS, global variable, code level interface, public rest api, as well as key dependencies like Oui

Good callout. I can add that

about versioning Rules,
it should be suggested, but not mandatory, as far as today, OSD version bump up regardless major/minor/patch is driven by OpenSearch release instead of OSD's own need.
distribution is binded with OpenSearch, that means, even if there is no any change, we have to bump up OSD version. we should also address this in our roadmap. #9192

I agree on following OpenSearches definitions. Opensearch also follows senver2.0. I just restated them given that we are discussing semver here. I can remove it too. As for the roadmap. I dont want to mix the conversations. I agree with the other proposal to allow different versions but that can happen independent of this change.

while the rfc is aim to discuss Semantic Versioning for OSD, from content it is mainly focus on developer's view, while we should be open to bump up version for new feature and change that don't introduce any break change.

What version do you want us to be open about bumping up? That wasnt clear to me

@virajsanghvi
Copy link
Collaborator

  1. Defining the Public Contract

Is it intentional that this definition doesn't cover UI itself?

Public Contract Checklist
Would a change force external consumers to adjust their code or workflows?

Is it always clear what is being consumed? Should default assumption be that it is consumed?

  1. Excluding npm Dependencies from Semantic Versioning

How are plugins bound by OSD's npm dependencies? In what situation will OSD fail to build when dependencies are mismatched. There's a tension that Plugins may depend on a npm package version for particular logic, but are at the same time bound to the same version that OSD uses. If OSD updates the package, it potentially could be problematic for the plugin, and while the plugin probably shouldn't have depended on that functionality, they also didn't really have a choice in the versioning. I think we should at least call this out as a risk for plugins, and would be good to understand how we can further mitigate (not clear on what packages this would be an issue for).

UI as a Public Contract: If the UI includes documented user experiences or extension points (e.g., plugin injection points, UI event hooks), then changes to these behaviors are considered breaking.

Extension points are code, right? They don't need to be called out from a UI perspective, right?

Documented user experiences is quite broad. What does "documented" mean and what "changes to these behaviors" are considered breaking. Are we saying the functionality that is documented is breaking, but the UX can change? Is some amount of UX consistency expected? Agree that getting more specific per seraphjiang will help.

For breaking changes as a maintainer, do we have a process?

Saw you said we'd define later, but would be good to have a way to ensure correct calibration.

@ashwin-pc
Copy link
Member Author

@virajsanghvi :

Is it intentional that this definition doesn't cover UI itself?

Yes, The UI itself can be interpreted as literally any change on the UI even if it does not impact the user. By being explicit we make sure we leave ourselves freedom to fix the things that we think are good while also ensuring that things that we think should not change are explicitly written down and agreed upon.

Is it always clear what is being consumed? Should default assumption be that it is consumed?

We need to be explicit about whats consumed. Thats the goal of the SEMVER.md file i will raise if we agree to this. The default assumption is that its not consumed. Some basic defaults can be assumed to be consumed though like plugin start and setup menthds, exports, api. The rest are implicitly assumed not part of the public contract

How are plugins bound by OSD's npm dependencies? In what situation will OSD fail to build when dependencies are mismatched. There's a tension that Plugins may depend on a npm package version for particular logic, but are at the same time bound to the same version that OSD uses. If OSD updates the package, it potentially could be problematic for the plugin, and while the plugin probably shouldn't have depended on that functionality, they also didn't really have a choice in the versioning. I think we should at least call this out as a risk for plugins, and would be good to understand how we can further mitigate (not clear on what packages this would be an issue for).

I agree and this is the main reason we hesitated against updating dependencies. However what the last few years have thought us is that either we agree that this is an okay tradeoff to be on top of CVE's and other dependency related bottlenecks, or slow down or use hacky work arounds to build the features and fix CVE's (e.g. forking public npm repos and hostign them under our personal npm accounts). There my argument is for making the tradeoff for speed

Extension points are code, right? They don't need to be called out from a UI perspective, right?
Documented user experiences is quite broad. What does "documented" mean and what "changes to these behaviors" are considered breaking. Are we saying the functionality that is documented is breaking, but the UX can change? Is some amount of UX consistency expected? Agree that getting more specific per seraphjiang will help.

Yeah let me get back on something more specific here. My intention was that there will be no change from how we treat UX changes right now. But how we treat it today is also a grey area. I will clarify this more

For breaking changes as a maintainer, do we have a process?
Saw you said we'd define later, but would be good to have a way to ensure correct calibration.

My idea here was to have essentially a tiered system of reviews for changes. A few core maintainers with different expertise's are required for breaking change reviews. Then we have area specific maintainers who's review is required for changes that impact that area. Smaller changes can be reviewed by any maintainer. Does this answer that question @kavilla @virajsanghvi ?

@virajsanghvi
Copy link
Collaborator

Is it always clear what is being consumed? Should default assumption be that it is consumed?

We need to be explicit about whats consumed. Thats the goal of the SEMVER.md file i will raise if we agree to this. The default assumption is that its not consumed. Some basic defaults can be assumed to be consumed though like plugin start and setup menthds, exports, api. The rest are implicitly assumed not part of the public contract

How do we know something is consumed? Is consumption defined as consumed within opensearch-project? If its just best effort, it just brings into question the default assumption being not consumed.

For breaking changes as a maintainer, do we have a process?
Saw you said we'd define later, but would be good to have a way to ensure correct calibration.

My idea here was to have essentially a tiered system of reviews for changes. A few core maintainers with different expertise's are required for breaking change reviews. Then we have area specific maintainers who's review is required for changes that impact that area. Smaller changes can be reviewed by any maintainer. Does this answer that question @kavilla @virajsanghvi ?

That's fine, my main ask was just that we need to write this down and flesh it out. Even having tiers brings up the question of who assigns tiers. Fine not to do it as part of this RFC, but think we need it asap in order to be successful here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants