-
Notifications
You must be signed in to change notification settings - Fork 25.3k
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
base: main
Are you sure you want to change the base?
Conversation
1e1a591
to
d84fef9
Compare
|
||
@TaskAction | ||
public void executeTask() throws IOException { | ||
File branchesFile = new File(Util.locateElasticsearchWorkspace(project.getGradle()), "branches.json"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
referencing project
here while executing task is deprecated. In this case I think we should just inject ProjectLayout
instead of project in the ctor and then use layout.getSettingsDirectory().file('branches.json').asFile
.
The Util.locateElasticsearchWorkspace
is just a utility method only used to resolve files relateive from internal builds within this repository, which we don't need here as we never run this task anywhere else but in the :elasticsearch root build
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also we probably want to make this file an outputFile property of the task
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've now changed the way to reference branches.json
file location using ProjectLayout
and also made the branches file an @OutputFile
property of the task.
private final ObjectMapper objectMapper; | ||
private final BranchesFileParser branchesFileParser; | ||
|
||
@Nullable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've made all three parameters @Input
and @Optional
.
4d569dc
to
1e2fb07
Compare
022297f
to
4d3aa2f
Compare
There is still a problem with |
e0f1357
to
2bf9688
Compare
project.getPlugins().apply(VersionPropertiesPlugin.class); | ||
Properties versionProperties = (Properties) project.getExtensions().getByName(VERSIONS_EXT); | ||
JavaVersion minimumCompilerVersion = JavaVersion.toVersion(versionProperties.get("minimumCompilerJava")); | ||
JavaVersion minimumRuntimeVersion = JavaVersion.toVersion(versionProperties.get("minimumRuntimeJava")); | ||
|
||
String bundledJdkVersion = versionProperties.getProperty("bundled_jdk"); | ||
String bundledJdkMajorVersion = bundledJdkVersion.split("[.+]")[0]; | ||
Version elasticsearchVersionProperty = Version.fromString(versionProperties.getProperty("elasticsearch")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not using static VersionProperties any more here as this make the class untestable.
This solves the problem described here: #129637 (comment)
When VersionProperties
is static it is loaded only once per JVM. It means it cannot be changed in the tests. This is a problem, because we want to test that GlobalBuildInfoPlugin
can calculate unreleased versions with BwcVersions for some fixed configuration. This was impossible when VersionProperties reads the real version.properties file which changes with every release.
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" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is simplification of the naming convention.
Name minorN
means previous minor on the same major where number N
is a distance from the current.
Name majorN
means previous major, still actively developed versions, where N is a distance from the current, omitting all the previous minor versions.
Related changes in other files across this PR.
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)) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the main change. Now we use branches.json
to get information about the unreleased versions instead of calculating it from Version.java
.
private List<DevelopmentBranch> getDevelopmentBranches() { | ||
String branchesFileLocation = project.getProviders() | ||
.gradleProperty(BRANCHES_FILE_LOCATION_PROPERTY) | ||
.getOrElse(DEFAULT_BRANCHES_FILE_URL); | ||
LOGGER.info("Reading branches.json from {}", branchesFileLocation); | ||
byte[] branchesBytes; | ||
if (branchesFileLocation.startsWith("http")) { | ||
try (InputStream in = URI.create(branchesFileLocation).toURL().openStream()) { | ||
branchesBytes = in.readAllBytes(); | ||
} catch (IOException e) { | ||
throw new UncheckedIOException("Failed to download branches.json from: " + branchesFileLocation, e); | ||
} | ||
} else { | ||
try { | ||
branchesBytes = Files.readAllBytes(new File(branchesFileLocation).toPath()); | ||
} catch (IOException e) { | ||
throw new UncheckedIOException("Failed to read branches.json from: " + branchesFileLocation, e); | ||
} | ||
} catch (IOException e) { | ||
throw new UncheckedIOException(e); | ||
} | ||
|
||
return branches; | ||
return branchesFileParser.parse(branchesBytes); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It reads development branches (with current versions of ES on these branches) from main branch using raw GitHub link. This URL can be overridden with org.elasticsearch.build.branches-file-location
Gradle property if needed.
# Conflicts: # branches.json
By default, it now reads branches.json from main branch of Elasticsearch (through GitHub raw link) . This can be overridden for testing or when there is a problem with remote call.
This change is needed to make GlobalBuildInfoPlugin testable. Previously it was using static VersionProperties which loaded values once for JVM so it was impossible to test with different values.
This file is needed now during the tests as it is no longer fully static during full JVM execution.
8be969c
to
9dc8160
Compare
Pinging @elastic/es-delivery (Team:Delivery) |
Work in progress
Gradle task added to modify
branches.json
. Possibility to add, remove and update branches in the file with theversion
field added next to thebranch
.After the change the file looks like this:
BwC test configuration has been changed to use changed
branches.json
file to calculate unreleased ES versions, instead of combining data fromVersion.java
andbranches.json
.