Skip to content

File tree

4 files changed

+59
-20
lines changed

4 files changed

+59
-20
lines changed
 

‎.github/workflows/detect-breaking-change.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ jobs:
1414
- uses: gradle/gradle-build-action@v3
1515
with:
1616
cache-disabled: true
17-
arguments: japicmp
17+
# The 2.14.0 is already reporting breaking changes (see please https://github.com/opensearch-project/OpenSearch/issues/13308)
18+
arguments: japicmp -Djapicmp.compare.version=2.14.0-SNAPSHOT
1819
gradle-version: 8.7
1920
build-root-directory: server
2021
- if: failure()

‎CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
4343
- Improve built-in secure transports support ([#12907](https://github.com/opensearch-project/OpenSearch/pull/12907))
4444
- Update links to documentation in rest-api-spec ([#13043](https://github.com/opensearch-project/OpenSearch/pull/13043))
4545
- Refactoring globMatch using simpleMatchWithNormalizedStrings from Regex ([#13104](https://github.com/opensearch-project/OpenSearch/pull/13104))
46+
- [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))
4647

4748
### Deprecated
4849

‎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

+41-19
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')
@@ -416,53 +432,59 @@ tasks.named("sourcesJar").configure {
416432
}
417433
}
418434

419-
/** Compares the current build against a snapshot build */
435+
/** Compares the current build against a laltest released version or the version supplied through 'japicmp.compare.version' system property */
420436
tasks.register("japicmp", me.champeau.gradle.japicmp.JapicmpTask) {
421-
oldClasspath.from(files("${buildDir}/snapshot/opensearch-${version}.jar"))
437+
logger.info("Comparing public APIs from ${version} to ${japicmpCompareTarget}")
438+
oldClasspath.from(files("${buildDir}/japicmp-target/opensearch-${japicmpCompareTarget}.jar"))
422439
newClasspath.from(tasks.named('jar'))
423440
onlyModified = true
424441
failOnModification = true
425442
ignoreMissingClasses = true
426443
annotationIncludes = ['@org.opensearch.common.annotation.PublicApi', '@org.opensearch.common.annotation.DeprecatedApi']
427444
txtOutputFile = layout.buildDirectory.file("reports/java-compatibility/report.txt")
428445
htmlOutputFile = layout.buildDirectory.file("reports/java-compatibility/report.html")
429-
dependsOn downloadSnapshot
446+
dependsOn downloadJapicmpCompareTarget
430447
}
431448

432449
/** If the Java API Comparison task failed, print a hint if the change should be merged from its target branch */
433450
gradle.taskGraph.afterTask { Task task, TaskState state ->
434451
if (task.name == 'japicmp' && state.failure != null) {
435-
def sha = getGitShaFromJar("${buildDir}/snapshot/opensearch-${version}.jar")
436-
logger.info("Incompatiable java api from snapshot jar built off of commit ${sha}")
437-
438-
if (!inHistory(sha)) {
439-
logger.warn('\u001B[33mPlease merge from the target branch and run this task again.\u001B[0m')
440-
}
452+
logger.info("Public APIs changes incompatiable with ${japicmpCompareTarget} target have been detected")
441453
}
442454
}
443455

444-
/** Downloads latest snapshot from maven repository */
445-
tasks.register("downloadSnapshot", Copy) {
456+
/** Downloads latest released version from maven repository */
457+
tasks.register("downloadJapicmpCompareTarget", Copy) {
446458
def mavenSnapshotRepoUrl = "https://aws.oss.sonatype.org/content/repositories/snapshots/"
447459
def groupId = "org.opensearch"
448460
def artifactId = "opensearch"
449461

450-
repositories {
451-
maven {
452-
url mavenSnapshotRepoUrl
453-
}
462+
// Add repository for snapshot artifacts if japicmp compare target version is snapshot
463+
if (japicmpCompareTarget.endsWith("-SNAPSHOT")) {
464+
def repos = project.getRepositories();
465+
MavenArtifactRepository opensearchRepo = repos.maven(repo -> {
466+
repo.setName("opensearch-snapshots");
467+
repo.setUrl(mavenSnapshotRepoUrl);
468+
});
469+
470+
repos.exclusiveContent(exclusiveRepo -> {
471+
exclusiveRepo.filter(descriptor -> descriptor.includeGroup(groupId));
472+
exclusiveRepo.forRepositories(opensearchRepo);
473+
});
454474
}
455475

456476
configurations {
457-
snapshotArtifact
477+
japicmpCompareTargetArtifact {
478+
exclude group: 'org.apache.lucene'
479+
}
458480
}
459481

460482
dependencies {
461-
snapshotArtifact("${groupId}:${artifactId}:${version}:")
483+
japicmpCompareTargetArtifact("${groupId}:${artifactId}:${japicmpCompareTarget}:")
462484
}
463485

464-
from configurations.snapshotArtifact
465-
into "$buildDir/snapshot"
486+
from configurations.japicmpCompareTargetArtifact
487+
into "$buildDir/japicmp-target"
466488
}
467489

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

0 commit comments

Comments
 (0)
Please sign in to comment.