Skip to content

Commit b4692c8

Browse files
authored
Reconsider the breaking changes check policy to detect breaking changes against released versions (opensearch-project#13292)
* Reconsider the breaking changes check policy to detect breaking changes against released versions Signed-off-by: Andriy Redko <[email protected]> * Add an ability to provide the target version to compare with for japicmp tasks Signed-off-by: Andriy Redko <[email protected]> * Add documentation for japicmp tasks Signed-off-by: Andriy Redko <[email protected]> --------- Signed-off-by: Andriy Redko <[email protected]>
1 parent 0282e64 commit b4692c8

File tree

3 files changed

+56
-25
lines changed

3 files changed

+56
-25
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
4545
- Improve built-in secure transports support ([#12907](https://github.com/opensearch-project/OpenSearch/pull/12907))
4646
- Update links to documentation in rest-api-spec ([#13043](https://github.com/opensearch-project/OpenSearch/pull/13043))
4747
- Refactoring globMatch using simpleMatchWithNormalizedStrings from Regex ([#13104](https://github.com/opensearch-project/OpenSearch/pull/13104))
48+
- [BWC and API enforcement] Reconsider the breaking changes check policy to detect breaking changes against released versions ([#13292](https://github.com/opensearch-project/OpenSearch/pull/13292))
4849

4950
### Deprecated
5051

DEVELOPER_GUIDE.md

+15
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
- [Developer API](#developer-api)
5858
- [User API](#user-api)
5959
- [Experimental Development](#experimental-development)
60+
- [API Compatibility Checks](#api-compatibility-checks)
6061
- [Backports](#backports)
6162
- [LineLint](#linelint)
6263
- [Lucene Snapshots](#lucene-snapshots)
@@ -607,6 +608,20 @@ a LTS feature but with additional guard rails and communication mechanisms to si
607608
release, or be removed altogether. Any Developer or User APIs implemented along with the experimental feature should be marked with `@ExperimentalApi` (or documented as
608609
`@opensearch.experimental`) annotation to signal the implementation is not subject to LTS and does not follow backwards compatibility guidelines.
609610

611+
#### API Compatibility Checks
612+
613+
The compatibility checks for public APIs are performed using [japicmp](https://siom79.github.io/japicmp/) and are available as separate Gradle tasks (those are run on demand at the moment):
614+
615+
```
616+
./gradlew japicmp
617+
```
618+
619+
By default, the API compatibility checks are run against the latest released version of the OpenSearch, however the target version to compare to could be provided using system property during the build, fe.:
620+
621+
```
622+
./gradlew japicmp -Djapicmp.compare.version=2.14.0-SNAPSHOT
623+
```
624+
610625
### Backports
611626

612627
The Github workflow in [`backport.yml`](.github/workflows/backport.yml) creates backport PRs automatically when the original PR with an appropriate label `backport <backport-branch-name>` is merged to main with the backport workflow run successfully on the PR. For example, if a PR on main needs to be backported to `1.x` branch, add a label `backport 1.x` to the PR and make sure the backport workflow runs on the PR along with other checks. Once this PR is merged to main, the workflow will create a backport PR to the `1.x` branch.

server/build.gradle

+40-25
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,22 @@ tasks.named("testingConventions").configure {
173173
}
174174
}
175175

176+
// Set to current version by default
177+
def japicmpCompareTarget = System.getProperty("japicmp.compare.version")
178+
if (japicmpCompareTarget == null) { /* use latest released version */
179+
// Read the list from maven central.
180+
// Fetch the metadata and parse the xml into Version instances, pick the latest one
181+
japicmpCompareTarget = new URL('https://repo1.maven.org/maven2/org/opensearch/opensearch/maven-metadata.xml').openStream().withStream { s ->
182+
new XmlParser().parse(s)
183+
.versioning.versions.version
184+
.collect { it.text() }.findAll { it ==~ /\d+\.\d+\.\d+/ }
185+
.collect { org.opensearch.gradle.Version.fromString(it) }
186+
.toSorted()
187+
.last()
188+
.toString()
189+
}
190+
}
191+
176192
def generateModulesList = tasks.register("generateModulesList") {
177193
List<String> modules = project(':modules').subprojects.collect { it.name }
178194
File modulesFile = new File(buildDir, 'generated-resources/modules.txt')
@@ -380,60 +396,59 @@ tasks.named("sourcesJar").configure {
380396
}
381397
}
382398

383-
/** Compares the current build against a snapshot build */
399+
/** Compares the current build against a laltest released version or the version supplied through 'japicmp.compare.version' system property */
384400
tasks.register("japicmp", me.champeau.gradle.japicmp.JapicmpTask) {
385-
oldClasspath.from(files("${buildDir}/snapshot/opensearch-${version}.jar"))
401+
logger.info("Comparing public APIs from ${version} to ${japicmpCompareTarget}")
402+
oldClasspath.from(files("${buildDir}/japicmp-target/opensearch-${japicmpCompareTarget}.jar"))
386403
newClasspath.from(tasks.named('jar'))
387404
onlyModified = true
388405
failOnModification = true
389406
ignoreMissingClasses = true
390407
annotationIncludes = ['@org.opensearch.common.annotation.PublicApi', '@org.opensearch.common.annotation.DeprecatedApi']
391408
txtOutputFile = layout.buildDirectory.file("reports/java-compatibility/report.txt")
392409
htmlOutputFile = layout.buildDirectory.file("reports/java-compatibility/report.html")
393-
dependsOn downloadSnapshot
410+
dependsOn downloadJapicmpCompareTarget
394411
}
395412

396413
/** If the Java API Comparison task failed, print a hint if the change should be merged from its target branch */
397414
gradle.taskGraph.afterTask { Task task, TaskState state ->
398415
if (task.name == 'japicmp' && state.failure != null) {
399-
def sha = getGitShaFromJar("${buildDir}/snapshot/opensearch-${version}.jar")
400-
logger.info("Incompatiable java api from snapshot jar built off of commit ${sha}")
401-
402-
if (!inHistory(sha)) {
403-
logger.warn('\u001B[33mPlease merge from the target branch and run this task again.\u001B[0m')
404-
}
416+
logger.info("Public APIs changes incompatiable with ${japicmpCompareTarget} target have been detected")
405417
}
406418
}
407419

408-
/** Downloads latest snapshot from maven repository */
409-
tasks.register("downloadSnapshot", Copy) {
420+
/** Downloads latest released version from maven repository */
421+
tasks.register("downloadJapicmpCompareTarget", Copy) {
410422
def mavenSnapshotRepoUrl = "https://aws.oss.sonatype.org/content/repositories/snapshots/"
411423
def groupId = "org.opensearch"
412424
def artifactId = "opensearch"
413425

414-
def repos = project.getRepositories();
415-
MavenArtifactRepository opensearchRepo = repos.maven(repo -> {
416-
repo.setName("opensearch-snapshots");
417-
repo.setUrl(mavenSnapshotRepoUrl);
418-
});
419-
420-
repos.exclusiveContent(exclusiveRepo -> {
421-
exclusiveRepo.filter(descriptor -> descriptor.includeGroup(groupId));
422-
exclusiveRepo.forRepositories(opensearchRepo);
423-
});
426+
// Add repository for snapshot artifacts if japicmp compare target version is snapshot
427+
if (japicmpCompareTarget.endsWith("-SNAPSHOT")) {
428+
def repos = project.getRepositories();
429+
MavenArtifactRepository opensearchRepo = repos.maven(repo -> {
430+
repo.setName("opensearch-snapshots");
431+
repo.setUrl(mavenSnapshotRepoUrl);
432+
});
433+
434+
repos.exclusiveContent(exclusiveRepo -> {
435+
exclusiveRepo.filter(descriptor -> descriptor.includeGroup(groupId));
436+
exclusiveRepo.forRepositories(opensearchRepo);
437+
});
438+
}
424439

425440
configurations {
426-
snapshotArtifact {
441+
japicmpCompareTargetArtifact {
427442
exclude group: 'org.apache.lucene'
428443
}
429444
}
430445

431446
dependencies {
432-
snapshotArtifact("${groupId}:${artifactId}:${version}:")
447+
japicmpCompareTargetArtifact("${groupId}:${artifactId}:${japicmpCompareTarget}:")
433448
}
434449

435-
from configurations.snapshotArtifact
436-
into "$buildDir/snapshot"
450+
from configurations.japicmpCompareTargetArtifact
451+
into "$buildDir/japicmp-target"
437452
}
438453

439454
/** Check if the sha is in the current history */

0 commit comments

Comments
 (0)