Skip to content

Gradle plugin support for dependencies in plugin descriptor properties#22426

Open
rursprung wants to merge 2 commits into
opensearch-project:mainfrom
rursprung:support-dependencies-in-gradle-opensearchplugin
Open

Gradle plugin support for dependencies in plugin descriptor properties#22426
rursprung wants to merge 2 commits into
opensearch-project:mainfrom
rursprung:support-dependencies-in-gradle-opensearchplugin

Conversation

@rursprung

Copy link
Copy Markdown
Contributor

Description

this is #17178 rebased and split in two commits, with better commit messages. all credits for the actual commit content go to @abseth-amzn (who doesn't seem to be working on OpenSearch anymore, thus the original PR has been abandoned for a long time).

the rest is copy & paste from the commit message:
PR #11441 added support for semver ranges in dependencies of plugins.
this now updates opensearchplugin (from
org.opensearch.gradle:build-tools) to support dependencies property
when building plugins. since most plugins do not create the
plugin-descriptor.properties file manually but instead use this gradle
plugin for it this means that so far dependencies was not really used.

dependencies also allows depending on opensearch (i.e. the core) and
it allows depending on a semver range - thus this finally allows
decoupling plugin releases from OpenSearch releases, i.e. plugins using
this instead of specifying an opensearch.version do not need a new
release for every new OpenSearch minor/patch release.

for existing plugins updating to the new gradle plugin version will just
generate an empty dependencies entry. so far, this would have then
caused the plugin to fail to load, however the previous commit has
modified this behaviour.
an alternative would be to not generate the entry at all if no
dependencies are specified, but then dependencies would be handled
differently to all other entries in the properties file. since the
gradle plugin is generally only updated together with the OpenSearch
version which the plugins support this should be ok to do (it's unlikely
that a plugin will use the gradle plugin 3.8.0 and generate a plugin
release for e.g. 3.7.0).


plugin info: support empty dependencies

so far, if a plugin provides a plugin-descriptor.properties with an
empty dependencies entry this will fail if opensearch.version is
also specified. however, an empty dependencies entry should not fail
this - it should behave as if it were not present.

Related Issues

resolves #13187
related to #11441

Check List

  • Functionality includes testing.
  • API changes companion pull request created, if applicable.
  • Public documentation issue/PR created, if applicable.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

so far, if a plugin provides a `plugin-descriptor.properties` with an
empty `dependencies` entry this will fail if `opensearch.version` is
also specified. however, an empty `dependencies` entry should not fail
this - it should behave as if it were not present.

Signed-off-by: Abhilasha Seth <abseth@amazon.com>
Signed-off-by: Ralph Ursprung <Ralph.Ursprung@avaloq.com>
PR opensearch-project#11441 added support for semver ranges in dependencies of plugins.
this now updates `opensearchplugin` (from
`org.opensearch.gradle:build-tools`) to support `dependencies` property
when building plugins. since most plugins do not create the
`plugin-descriptor.properties` file manually but instead use this gradle
plugin for it this means that so far `dependencies` was not really used.

`dependencies` also allows depending on `opensearch` (i.e. the core) and
it allows depending on a semver range - thus this finally allows
decoupling plugin releases from OpenSearch releases, i.e. plugins using
this instead of specifying an `opensearch.version` do not need a new
release for every new OpenSearch minor/patch release.

for existing plugins updating to the new gradle plugin version will just
generate an empty `dependencies` entry. so far, this would have then
caused the plugin to fail to load, however the previous commit has
modified this behaviour.
an alternative would be to not generate the entry at all if no
dependencies are specified, but then `dependencies` would be handled
differently to all other entries in the properties file. since the
gradle plugin is generally only updated together with the OpenSearch
version which the plugins support this should be ok to do (it's unlikely
that a plugin will use the gradle plugin 3.8.0 and generate a plugin
release for e.g. 3.7.0).

resolves opensearch-project#13187

Signed-off-by: Abhilasha Seth <abseth@amazon.com>
Signed-off-by: Ralph Ursprung <Ralph.Ursprung@avaloq.com>
@rursprung rursprung requested a review from a team as a code owner July 9, 2026 11:23
@github-actions github-actions Bot added Build Build Tasks/Gradle Plugin, groovy scripts, build tools, Javadoc enforcement. Build Libraries & Interfaces enhancement Enhancement or improvement to existing feature or request Plugins labels Jul 9, 2026
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

🧪 PR contains tests
🔒 No security concerns identified
✅ No TODO sections
🔀 No multiple PR themes
⚡ Recommended focus areas for review

Always-emitted empty dependencies

The descriptor template now unconditionally writes dependencies=${dependencies}, which for existing plugins that don't set dependencies will produce dependencies= in the generated plugin-descriptor.properties. Combined with PluginInfo.readFromProperties treating a blank dependencies value as absent (via the new isBlank check), this works for the default case; however, if a plugin already sets opensearch.version via the extension AND leaves dependencies empty, the generated descriptor will contain both keys (one non-empty, one empty). The new logic handles this because isBlank is used, but note that any tooling consuming plugin-descriptor.properties externally may now see an unexpected empty dependencies= line. Confirm downstream tools tolerate the extra empty property.

# 'dependencies': any dependencies specified by the plugin
dependencies=${dependencies}
Possible Issue

When a plugin sets dependencies via the extension, opensearchVersion is forcibly cleared to ''. However, if a user has also set opensearch.version explicitly (e.g. via extension defaults), no error is raised at build time — the Gradle plugin silently drops it. This can mask misconfiguration; at minimum this should log a warning or fail the build, matching the runtime check in PluginInfo.readFromProperties which rejects specifying both.

// Clear opensearch version if dependencies are specified
if (extension1.dependencies != null && !extension1.dependencies.trim().isEmpty()) {
    properties.put('opensearchVersion', '');
}

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
General
Warn when overriding opensearchVersion silently

When dependencies are specified, the code clears opensearchVersion but the
plugin-descriptor.properties template still emits opensearch.version= with an empty
value. Combined with a non-empty dependencies value, this correctly hits the new
isBlank check in PluginInfo.readFromProperties. However, if a user provides both
non-empty dependencies and an explicit opensearchVersion override at the extension
level (currently sourced from VersionProperties), the silent overwrite may hide
misconfigurations. Consider logging a warning when overriding, or fail the build if
both are explicitly set by the user, to avoid surprising behavior.

buildSrc/src/main/groovy/org/opensearch/gradle/plugin/PluginBuildPlugin.groovy [120-123]

 // Clear opensearch version if dependencies are specified
 if (extension1.dependencies != null && !extension1.dependencies.trim().isEmpty()) {
+    project.logger.info("Plugin '${extension1.name}' specifies 'dependencies'; clearing 'opensearchVersion' in plugin descriptor.")
     properties.put('opensearchVersion', '');
 }
Suggestion importance[1-10]: 4

__

Why: Adding a log message when clearing opensearchVersion is a minor improvement for observability but doesn't address functional issues. The suggestion is reasonable but low impact.

Low
Normalize blank strings to null early

Since opensearchVersionString may now be an empty/blank string (not just null),
ensure downstream code paths and any later usages of opensearchVersionString treat
blank as absent. The current branch is fine, but pass a normalized value (null when
blank) to avoid subtle bugs in future maintenance.

server/src/main/java/org/opensearch/plugins/PluginInfo.java [306-310]

-if (!isBlank(opensearchVersionString)) {
-    opensearchVersionRanges.add(SemverRange.fromString(opensearchVersionString));
+final String normalizedOpenSearchVersion = isBlank(opensearchVersionString) ? null : opensearchVersionString;
+if (normalizedOpenSearchVersion != null) {
+    opensearchVersionRanges.add(SemverRange.fromString(normalizedOpenSearchVersion));
 } else {
     Map<String, String> dependenciesMap;
     try (
Suggestion importance[1-10]: 3

__

Why: Normalizing blank to null is a minor code quality improvement. The existing code with isBlank check is already correct, so this is a stylistic preference with limited impact.

Low

@cwperks

cwperks commented Jul 9, 2026

Copy link
Copy Markdown
Member

Thank you for this PR @rursprung ! I have something similar open at #19680 and I think between the 2 of these they can help ease the maintenance burden on plugins.

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

✅ Gradle check result for f013b87: SUCCESS

@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 60.00000% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 73.58%. Comparing base (264b119) to head (f013b87).
⚠️ Report is 7 commits behind head on main.

Files with missing lines Patch % Lines
.../opensearch/gradle/plugin/PluginBuildPlugin.groovy 0.00% 1 Missing and 1 partial ⚠️
...earch/gradle/plugin/PluginPropertiesExtension.java 50.00% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main   #22426      +/-   ##
============================================
+ Coverage     73.44%   73.58%   +0.13%     
- Complexity    76423    76543     +120     
============================================
  Files          6102     6102              
  Lines        346523   346530       +7     
  Branches      49875    49876       +1     
============================================
+ Hits         254504   254992     +488     
+ Misses        71800    71256     -544     
- Partials      20219    20282      +63     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Build Libraries & Interfaces Build Build Tasks/Gradle Plugin, groovy scripts, build tools, Javadoc enforcement. enhancement Enhancement or improvement to existing feature or request Plugins

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request] missing gradle plugin support for dependencies in plugin descriptor properties with semver range

3 participants