Skip to content

Add explicit versions in the branches.json and use them for calculating unreleased versions for BwC tests #129637

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

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions branches.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,28 @@
"notice": "This file is not maintained outside of the main branch and should only be used for tooling.",
"branches": [
{
"branch": "main"
"branch": "main",
"version": "9.1.0"
},
{
"branch": "9.0"
"branch": "9.0",
"version": "9.0.3"
},
{
"branch": "8.19"
"branch": "8.19",
"version": "8.19.0"
},
{
"branch": "8.18"
"branch": "8.18",
"version": "8.18.3"
},
{
"branch": "8.17"
"branch": "8.17",
"version": "8.17.8"
},
{
"branch": "7.17"
"branch": "7.17",
"version": "7.17.29"
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,23 +51,23 @@ class InternalDistributionBwcSetupPluginFuncTest extends AbstractGitAwareGradleF
assertOutputContains(result.output, "[$bwcDistVersion] > Task :distribution:archives:darwin-tar:${expectedAssembleTaskName}")

where:
bwcDistVersion | bwcProject | expectedAssembleTaskName
"8.4.0" | "minor" | "extractedAssemble"
"8.3.0" | "staged" | "extractedAssemble"
"8.2.1" | "bugfix" | "extractedAssemble"
"8.1.3" | "bugfix2" | "extractedAssemble"
bwcDistVersion | bwcProject | expectedAssembleTaskName
"8.4.0" | "major1" | "extractedAssemble"
"8.3.0" | "major2" | "extractedAssemble"
"8.2.1" | "major3" | "extractedAssemble"
"8.1.3" | "major4" | "extractedAssemble"
}

@Unroll
def "supports #platform aarch distributions"() {
when:
def result = gradleRunner(":distribution:bwc:minor:buildBwc${platform.capitalize()}Aarch64Tar",
def result = gradleRunner(":distribution:bwc:major1:buildBwc${platform.capitalize()}Aarch64Tar",
"-DtestRemoteRepo=" + remoteGitRepo,
"-Dbwc.remote=origin",
"-Dbwc.dist.version=${bwcDistVersion}-SNAPSHOT")
.build()
then:
result.task(":distribution:bwc:minor:buildBwc${platform.capitalize()}Aarch64Tar").outcome == TaskOutcome.SUCCESS
result.task(":distribution:bwc:major1:buildBwc${platform.capitalize()}Aarch64Tar").outcome == TaskOutcome.SUCCESS

and: "assemble tasks triggered"
assertOutputContains(result.output, "[$bwcDistVersion] > Task :distribution:archives:${platform}-aarch64-tar:extractedAssemble")
Expand All @@ -87,7 +87,7 @@ class InternalDistributionBwcSetupPluginFuncTest extends AbstractGitAwareGradleF
}

dependencies {
expandedDist project(path: ":distribution:bwc:minor", configuration:"expanded-darwin-tar")
expandedDist project(path: ":distribution:bwc:major1", configuration:"expanded-darwin-tar")
}

tasks.register("resolveExpandedDistribution") {
Expand All @@ -109,12 +109,12 @@ class InternalDistributionBwcSetupPluginFuncTest extends AbstractGitAwareGradleF
.build()
then:
result.task(":resolveExpandedDistribution").outcome == TaskOutcome.SUCCESS
result.task(":distribution:bwc:minor:buildBwcDarwinTar").outcome == TaskOutcome.SUCCESS
result.task(":distribution:bwc:major1:buildBwcDarwinTar").outcome == TaskOutcome.SUCCESS
and: "assemble task triggered"
result.output.contains("[8.4.0] > Task :distribution:archives:darwin-tar:extractedAssemble")
result.output.contains("expandedRootPath /distribution/bwc/minor/build/bwc/checkout-8.x/" +
result.output.contains("expandedRootPath /distribution/bwc/major1/build/bwc/checkout-8.x/" +
"distribution/archives/darwin-tar/build/install")
result.output.contains("nested folder /distribution/bwc/minor/build/bwc/checkout-8.x/" +
result.output.contains("nested folder /distribution/bwc/major1/build/bwc/checkout-8.x/" +
"distribution/archives/darwin-tar/build/install/elasticsearch-8.4.0-SNAPSHOT")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class InternalDistributionDownloadPluginFuncTest extends AbstractGradleFuncTest
def "resolves expanded bwc versions from source"() {
given:
internalBuild()
bwcMinorProjectSetup()
bwcMajor1ProjectSetup()
buildFile << """
apply plugin: 'elasticsearch.internal-distribution-download'

Expand All @@ -72,16 +72,16 @@ class InternalDistributionDownloadPluginFuncTest extends AbstractGradleFuncTest

def result = gradleRunner("setupDistro").build()
then:
result.task(":distribution:bwc:minor:buildBwcExpandedTask").outcome == TaskOutcome.SUCCESS
result.task(":distribution:bwc:major1:buildBwcExpandedTask").outcome == TaskOutcome.SUCCESS
result.task(":setupDistro").outcome == TaskOutcome.SUCCESS
assertExtractedDistroIsCreated("distribution/bwc/minor/build/install/elastic-distro",
assertExtractedDistroIsCreated("distribution/bwc/major1/build/install/elastic-distro",
'bwc-marker.txt')
}

def "fails on resolving bwc versions with no bundled jdk"() {
given:
internalBuild()
bwcMinorProjectSetup()
bwcMajor1ProjectSetup()
buildFile << """
apply plugin: 'elasticsearch.internal-distribution-download'

Expand All @@ -105,12 +105,12 @@ class InternalDistributionDownloadPluginFuncTest extends AbstractGradleFuncTest
"without a bundled JDK is not supported.")
}

private void bwcMinorProjectSetup() {
private void bwcMajor1ProjectSetup() {
settingsFile << """
include ':distribution:bwc:minor'
include ':distribution:bwc:major1'
"""
def bwcSubProjectFolder = testProjectDir.newFolder("distribution", "bwc", "minor")
new File(bwcSubProjectFolder, 'bwc-marker.txt') << "bwc=minor"
def bwcSubProjectFolder = testProjectDir.newFolder("distribution", "bwc", "major1")
new File(bwcSubProjectFolder, 'bwc-marker.txt') << "bwc=major1"
new File(bwcSubProjectFolder, 'build.gradle') << """
apply plugin:'base'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class LegacyYamlRestCompatTestPluginFuncTest extends AbstractRestResourcesFuncTe
given:
internalBuild()

subProject(":distribution:bwc:minor") << """
subProject(":distribution:bwc:major1") << """
configurations { checkout }
artifacts {
checkout(new File(projectDir, "checkoutDir"))
Expand All @@ -61,11 +61,11 @@ class LegacyYamlRestCompatTestPluginFuncTest extends AbstractRestResourcesFuncTe
result.task(transformTask).outcome == TaskOutcome.NO_SOURCE
}

def "yamlRestCompatTest executes and copies api and transforms tests from :bwc:minor"() {
def "yamlRestCompatTest executes and copies api and transforms tests from :bwc:major1"() {
given:
internalBuild()

subProject(":distribution:bwc:minor") << """
subProject(":distribution:bwc:major1") << """
configurations { checkout }
artifacts {
checkout(new File(projectDir, "checkoutDir"))
Expand Down Expand Up @@ -98,8 +98,8 @@ class LegacyYamlRestCompatTestPluginFuncTest extends AbstractRestResourcesFuncTe
String api = "foo.json"
String test = "10_basic.yml"
//add the compatible test and api files, these are the prior version's normal yaml rest tests
file("distribution/bwc/minor/checkoutDir/rest-api-spec/src/main/resources/rest-api-spec/api/" + api) << ""
file("distribution/bwc/minor/checkoutDir/src/yamlRestTest/resources/rest-api-spec/test/" + test) << ""
file("distribution/bwc/major1/checkoutDir/rest-api-spec/src/main/resources/rest-api-spec/api/" + api) << ""
file("distribution/bwc/major1/checkoutDir/src/yamlRestTest/resources/rest-api-spec/test/" + test) << ""

when:
def result = gradleRunner("yamlRestCompatTest").build()
Expand Down Expand Up @@ -145,7 +145,7 @@ class LegacyYamlRestCompatTestPluginFuncTest extends AbstractRestResourcesFuncTe
given:
internalBuild()
withVersionCatalogue()
subProject(":distribution:bwc:minor") << """
subProject(":distribution:bwc:major1") << """
configurations { checkout }
artifacts {
checkout(new File(projectDir, "checkoutDir"))
Expand Down Expand Up @@ -186,7 +186,7 @@ class LegacyYamlRestCompatTestPluginFuncTest extends AbstractRestResourcesFuncTe
given:
internalBuild()

subProject(":distribution:bwc:minor") << """
subProject(":distribution:bwc:major1") << """
configurations { checkout }
artifacts {
checkout(new File(projectDir, "checkoutDir"))
Expand Down Expand Up @@ -230,7 +230,7 @@ class LegacyYamlRestCompatTestPluginFuncTest extends AbstractRestResourcesFuncTe

setupRestResources([], [])

file("distribution/bwc/minor/checkoutDir/src/yamlRestTest/resources/rest-api-spec/test/test.yml" ) << """
file("distribution/bwc/major1/checkoutDir/src/yamlRestTest/resources/rest-api-spec/test/test.yml" ) << """
"one":
- do:
do_.some.key_to_replace:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@

rootProject.name = "root"

include ":distribution:bwc:bugfix"
include ":distribution:bwc:bugfix2"
include ":distribution:bwc:bugfix3"
include ":distribution:bwc:minor"
include ":distribution:bwc:major"
include ":distribution:bwc:staged"
include ":distribution:bwc:staged2"
include ":distribution:bwc:maintenance"
include ":distribution:bwc:major1"
include ":distribution:bwc:major2"
include ":distribution:bwc:major3"
include ":distribution:bwc:major4"
include ":distribution:bwc:minor1"
include ":distribution:bwc:minor2"
include ":distribution:bwc:minor3"
include ":distribution:bwc:minor4"
include ":distribution:archives:darwin-tar"
include ":distribution:archives:oss-darwin-tar"
include ":distribution:archives:darwin-aarch64-tar"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import org.elasticsearch.gradle.Version;
import org.elasticsearch.gradle.VersionProperties;
import org.elasticsearch.gradle.internal.info.DevelopmentBranch;

import java.io.Serializable;
import java.util.ArrayList;
Expand All @@ -26,6 +27,7 @@
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static java.util.Collections.reverseOrder;
import static java.util.Collections.unmodifiableList;
Expand Down Expand Up @@ -74,11 +76,11 @@ public class BwcVersions implements Serializable {
private final transient List<Version> versions;
private final Map<Version, UnreleasedVersionInfo> unreleased;

public BwcVersions(List<String> versionLines, List<String> developmentBranches) {
public BwcVersions(List<String> versionLines, List<DevelopmentBranch> developmentBranches) {
this(versionLines, Version.fromString(VersionProperties.getElasticsearch()), developmentBranches);
}

public BwcVersions(Version currentVersionProperty, List<Version> allVersions, List<String> developmentBranches) {
public BwcVersions(Version currentVersionProperty, List<Version> allVersions, List<DevelopmentBranch> developmentBranches) {
if (allVersions.isEmpty()) {
throw new IllegalArgumentException("Could not parse any versions");
}
Expand All @@ -91,7 +93,7 @@ public BwcVersions(Version currentVersionProperty, List<Version> allVersions, Li
}

// Visible for testing
BwcVersions(List<String> versionLines, Version currentVersionProperty, List<String> developmentBranches) {
BwcVersions(List<String> versionLines, Version currentVersionProperty, List<DevelopmentBranch> developmentBranches) {
this(currentVersionProperty, parseVersionLines(versionLines), developmentBranches);
}

Expand Down Expand Up @@ -127,81 +129,46 @@ public void forPreviousUnreleased(Consumer<UnreleasedVersionInfo> consumer) {
getUnreleased().stream().filter(version -> version.equals(currentVersion) == false).map(unreleased::get).forEach(consumer);
}

private String getBranchFor(Version version, List<String> developmentBranches) {
// If the current version matches a specific feature freeze branch, use that
if (developmentBranches.contains(version.getMajor() + "." + version.getMinor())) {
return version.getMajor() + "." + version.getMinor();
} else if (developmentBranches.contains(version.getMajor() + ".x")) { // Otherwise if an n.x branch exists and we are that major
return version.getMajor() + ".x";
} else { // otherwise we're the main branch
return "main";
}
}

private Map<Version, UnreleasedVersionInfo> computeUnreleased(List<String> developmentBranches) {
private Map<Version, UnreleasedVersionInfo> computeUnreleased(List<DevelopmentBranch> developmentBranches) {
Map<Version, UnreleasedVersionInfo> result = new TreeMap<>();
Map<String, List<DevelopmentBranch>> bwcBranches = developmentBranches.stream()
.filter(developmentBranch -> developmentBranch.version().before(currentVersion))
.sorted(reverseOrder(comparing(DevelopmentBranch::version)))
.collect(Collectors.groupingBy(branch -> {
if (branch.version().getMajor() == currentVersion.getMajor()) {
return "minor";
} else if (branch.version().getMajor() == currentVersion.getMajor() - 1) {
return "major";
}
return "older";
}));

developmentBranches.stream()
.filter(branch -> branch.version().equals(currentVersion))
.findFirst()
.ifPresent(
developmentBranch -> result.put(
currentVersion,
new UnreleasedVersionInfo(currentVersion, developmentBranch.name(), ":distribution")
)
);

// The current version is always in development
String currentBranch = getBranchFor(currentVersion, developmentBranches);
result.put(currentVersion, new UnreleasedVersionInfo(currentVersion, currentBranch, ":distribution"));

// Check for an n.x branch as well
if (currentBranch.equals("main") && developmentBranches.stream().anyMatch(s -> s.endsWith(".x"))) {
// This should correspond to the latest new minor
Version version = versions.stream()
.sorted(Comparator.reverseOrder())
.filter(v -> v.getMajor() == (currentVersion.getMajor() - 1) && v.getRevision() == 0)
.findFirst()
.orElseThrow(() -> new IllegalStateException("Unable to determine development version for branch"));
String branch = getBranchFor(version, developmentBranches);
assert branch.equals(currentVersion.getMajor() - 1 + ".x") : "Expected branch does not match development branch";

result.put(version, new UnreleasedVersionInfo(version, branch, ":distribution:bwc:minor"));
List<DevelopmentBranch> previousMinorBranches = bwcBranches.getOrDefault("minor", Collections.emptyList());
for (int i = 0; i < previousMinorBranches.size(); i++) {
DevelopmentBranch previousMinorBranch = previousMinorBranches.get(i);
result.put(
previousMinorBranch.version(),
new UnreleasedVersionInfo(previousMinorBranch.version(), previousMinorBranch.name(), ":distribution:bwc:minor" + (i + 1))
);
}

// Now handle all the feature freeze branches
List<String> featureFreezeBranches = developmentBranches.stream()
.filter(b -> Pattern.matches("[0-9]+\\.[0-9]+", b))
.sorted(reverseOrder(comparing(s -> Version.fromString(s, Version.Mode.RELAXED))))
.toList();

int bugfixCount = 0;
boolean existingStaged = false;
for (int i = 0; i < featureFreezeBranches.size(); i++) {
String branch = featureFreezeBranches.get(i);
Version version = versions.stream()
.sorted(Comparator.reverseOrder())
.filter(v -> v.toString().startsWith(branch))
.findFirst()
.orElse(null);

// If we don't know about this version we can ignore it
if (version == null) {
continue;
}

// If this is the current version we can ignore as we've already handled it
if (version.equals(currentVersion)) {
continue;
}

// We only maintain compatibility back one major so ignore anything older
if (currentVersion.getMajor() - version.getMajor() > 1) {
continue;
}

// This is the maintenance version
if (i == featureFreezeBranches.size() - 1) {
result.put(version, new UnreleasedVersionInfo(version, branch, ":distribution:bwc:maintenance"));
} else if (version.getRevision() == 0) { // This is the next staged minor
String project = existingStaged ? "staged2" : "staged";
result.put(version, new UnreleasedVersionInfo(version, branch, ":distribution:bwc:" + project));
existingStaged = true;
} else { // This is a bugfix
bugfixCount++;
String project = "bugfix" + (bugfixCount > 1 ? bugfixCount : "");
result.put(version, new UnreleasedVersionInfo(version, branch, ":distribution:bwc:" + project));
}
List<DevelopmentBranch> previousMajorBranches = bwcBranches.getOrDefault("major", Collections.emptyList());
for (int i = 0; i < previousMajorBranches.size(); i++) {
DevelopmentBranch previousMajorBranch = previousMajorBranches.get(i);
result.put(
previousMajorBranch.version(),
new UnreleasedVersionInfo(previousMajorBranch.version(), previousMajorBranch.name(), ":distribution:bwc:major" + (i + 1))
);
}

return Collections.unmodifiableMap(result);
Expand All @@ -211,19 +178,6 @@ public List<Version> getUnreleased() {
return unreleased.keySet().stream().sorted().toList();
}

private void addUnreleased(Set<Version> unreleased, Version current, int index) {
if (current.getRevision() == 0) {
// If the current version is a new minor, the next version is also unreleased
Version next = versions.get(versions.size() - (index + 2));
unreleased.add(next);

// Keep looking through versions until we find the end of unreleased versions
addUnreleased(unreleased, next, index + 1);
} else {
unreleased.add(current);
}
}

public void compareToAuthoritative(List<Version> authoritativeReleasedVersions) {
Set<Version> notReallyReleased = new HashSet<>(getReleased());
notReallyReleased.removeAll(authoritativeReleasedVersions);
Expand Down
Loading