-
Notifications
You must be signed in to change notification settings - Fork 25.5k
Add and modify mappings between version ids and release versions #103627
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
Merged
Merged
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
4df06c3
Add ReleaseVersions class for reading version record files
thecoop 9507f7c
Add a task to tag new versions in the version records
thecoop a0a98ff
Merge remote-tracking branch 'upstream/main' into version-records
thecoop 4f8e744
Add some comments to versions
thecoop 241d685
Merge branch 'main' into version-records
thecoop 7920370
Change version map to load on startup
thecoop 4203945
Update docs/changelog/103627.yaml
thecoop 69c01cd
Merge remote-tracking branch 'upstream/main' into version-records
thecoop be1cee5
Delete docs/changelog/103627.yaml
thecoop 085238f
Separate out extract & tag functionality into separate gradle tasks
thecoop 3f1399a
Use constants for string constants
thecoop e6087e9
Fix setting outputfile parameter
thecoop a9aae42
Add some tests
thecoop ac44aca
More tests
thecoop 67e961d
Update docs/changelog/103627.yaml
thecoop 5027972
Only sort on output
thecoop 5ce4286
Create file if it does not exist already
thecoop 33510bc
Merge branch 'main' into version-records
thecoop 1865d54
Merge branch 'main' into version-records
elasticmachine 16c983c
Merge branch 'main' into version-records
thecoop 3dc09d9
Use lists rather than sorted sets for version lists
thecoop dbf0f90
Add extra checks to options
thecoop 80fef71
Support processing Version from 7.17 releases
thecoop 8cb7350
Merge remote-tracking branch 'upstream/main' into version-records
thecoop 108749d
Make it clear raw ids are from snapshot builds
thecoop 702329b
Some tweaks
thecoop File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
35 changes: 35 additions & 0 deletions
35
...nternal/src/main/java/org/elasticsearch/gradle/internal/release/AbstractVersionsTask.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
package org.elasticsearch.gradle.internal.release; | ||
|
||
import org.gradle.api.DefaultTask; | ||
import org.gradle.initialization.layout.BuildLayout; | ||
|
||
import java.nio.file.Path; | ||
|
||
public abstract class AbstractVersionsTask extends DefaultTask { | ||
|
||
static final String TRANSPORT_VERSION_TYPE = "TransportVersion"; | ||
static final String INDEX_VERSION_TYPE = "IndexVersion"; | ||
|
||
static final String SERVER_MODULE_PATH = "server/src/main/java/"; | ||
static final String TRANSPORT_VERSION_FILE_PATH = SERVER_MODULE_PATH + "org/elasticsearch/TransportVersions.java"; | ||
static final String INDEX_VERSION_FILE_PATH = SERVER_MODULE_PATH + "org/elasticsearch/index/IndexVersions.java"; | ||
|
||
static final String SERVER_RESOURCES_PATH = "server/src/main/resources/"; | ||
static final String TRANSPORT_VERSIONS_RECORD = SERVER_RESOURCES_PATH + "org/elasticsearch/TransportVersions.csv"; | ||
static final String INDEX_VERSIONS_RECORD = SERVER_RESOURCES_PATH + "org/elasticsearch/index/IndexVersions.csv"; | ||
|
||
final Path rootDir; | ||
|
||
protected AbstractVersionsTask(BuildLayout layout) { | ||
rootDir = layout.getRootDirectory().toPath(); | ||
} | ||
|
||
} |
105 changes: 105 additions & 0 deletions
105
...l/src/main/java/org/elasticsearch/gradle/internal/release/ExtractCurrentVersionsTask.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
package org.elasticsearch.gradle.internal.release; | ||
|
||
import com.github.javaparser.StaticJavaParser; | ||
import com.github.javaparser.ast.CompilationUnit; | ||
import com.github.javaparser.ast.body.FieldDeclaration; | ||
import com.github.javaparser.ast.expr.IntegerLiteralExpr; | ||
|
||
import org.gradle.api.logging.Logger; | ||
import org.gradle.api.logging.Logging; | ||
import org.gradle.api.tasks.TaskAction; | ||
import org.gradle.api.tasks.options.Option; | ||
import org.gradle.initialization.layout.BuildLayout; | ||
|
||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.StandardOpenOption; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.function.Consumer; | ||
|
||
import javax.inject.Inject; | ||
|
||
public class ExtractCurrentVersionsTask extends AbstractVersionsTask { | ||
private static final Logger LOGGER = Logging.getLogger(ExtractCurrentVersionsTask.class); | ||
|
||
private Path outputFile; | ||
|
||
@Inject | ||
public ExtractCurrentVersionsTask(BuildLayout layout) { | ||
super(layout); | ||
} | ||
|
||
@Option(option = "output-file", description = "File to output tag information to") | ||
public void outputFile(String file) { | ||
this.outputFile = Path.of(file); | ||
} | ||
|
||
@TaskAction | ||
public void executeTask() throws IOException { | ||
if (outputFile == null) { | ||
throw new IllegalArgumentException("Output file not specified"); | ||
} | ||
|
||
LOGGER.lifecycle("Extracting latest version information"); | ||
|
||
List<String> output = new ArrayList<>(); | ||
int transportVersion = readLatestVersion(rootDir.resolve(TRANSPORT_VERSION_FILE_PATH)); | ||
LOGGER.lifecycle("Transport version: {}", transportVersion); | ||
output.add(TRANSPORT_VERSION_TYPE + ":" + transportVersion); | ||
|
||
int indexVersion = readLatestVersion(rootDir.resolve(INDEX_VERSION_FILE_PATH)); | ||
LOGGER.lifecycle("Index version: {}", indexVersion); | ||
output.add(INDEX_VERSION_TYPE + ":" + indexVersion); | ||
|
||
LOGGER.lifecycle("Writing version information to {}", outputFile); | ||
Files.write(outputFile, output, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING); | ||
} | ||
|
||
static class FieldIdExtractor implements Consumer<FieldDeclaration> { | ||
private Integer highestVersionId; | ||
|
||
Integer highestVersionId() { | ||
return highestVersionId; | ||
} | ||
|
||
@Override | ||
public void accept(FieldDeclaration fieldDeclaration) { | ||
var ints = fieldDeclaration.findAll(IntegerLiteralExpr.class); | ||
switch (ints.size()) { | ||
case 0 -> { | ||
// No ints in the field declaration, ignore | ||
} | ||
case 1 -> { | ||
int id = ints.get(0).asNumber().intValue(); | ||
if (highestVersionId != null && highestVersionId > id) { | ||
LOGGER.warn("Version ids [{}, {}] out of order", highestVersionId, id); | ||
} else { | ||
highestVersionId = id; | ||
} | ||
} | ||
default -> LOGGER.warn("Multiple integers found in version field declaration [{}]", fieldDeclaration); // and ignore it | ||
} | ||
} | ||
} | ||
|
||
private static int readLatestVersion(Path javaVersionsFile) throws IOException { | ||
CompilationUnit java = StaticJavaParser.parse(javaVersionsFile); | ||
|
||
FieldIdExtractor extractor = new FieldIdExtractor(); | ||
java.walk(FieldDeclaration.class, extractor); // walks in code file order | ||
if (extractor.highestVersionId == null) { | ||
throw new IllegalArgumentException("No version ids found in " + javaVersionsFile); | ||
} | ||
return extractor.highestVersionId; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
134 changes: 134 additions & 0 deletions
134
...ols-internal/src/main/java/org/elasticsearch/gradle/internal/release/TagVersionsTask.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
package org.elasticsearch.gradle.internal.release; | ||
|
||
import org.elasticsearch.gradle.Version; | ||
import org.gradle.api.logging.Logger; | ||
import org.gradle.api.logging.Logging; | ||
import org.gradle.api.tasks.TaskAction; | ||
import org.gradle.api.tasks.options.Option; | ||
import org.gradle.initialization.layout.BuildLayout; | ||
|
||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.StandardOpenOption; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
import java.util.stream.Collectors; | ||
|
||
import javax.inject.Inject; | ||
|
||
public class TagVersionsTask extends AbstractVersionsTask { | ||
private static final Logger LOGGER = Logging.getLogger(TagVersionsTask.class); | ||
|
||
private Version releaseVersion; | ||
|
||
private Map<String, Integer> tagVersions = Map.of(); | ||
|
||
@Inject | ||
public TagVersionsTask(BuildLayout layout) { | ||
super(layout); | ||
} | ||
|
||
@Option(option = "release", description = "The release version to be tagged") | ||
public void release(String version) { | ||
releaseVersion = Version.fromString(version); | ||
} | ||
|
||
@Option(option = "tag-version", description = "Version id to tag. Of the form <VersionType>:<id>.") | ||
public void tagVersions(List<String> version) { | ||
this.tagVersions = version.stream().map(l -> { | ||
var split = l.split(":"); | ||
if (split.length != 2) throw new IllegalArgumentException("Invalid tag format [" + l + "]"); | ||
return split; | ||
}).collect(Collectors.toMap(l -> l[0], l -> Integer.parseInt(l[1]))); | ||
} | ||
|
||
@TaskAction | ||
public void executeTask() throws IOException { | ||
if (releaseVersion == null) { | ||
throw new IllegalArgumentException("Release version not specified"); | ||
} | ||
if (tagVersions.isEmpty()) { | ||
throw new IllegalArgumentException("No version tags specified"); | ||
} | ||
|
||
LOGGER.lifecycle("Tagging version {} component ids", releaseVersion); | ||
|
||
var versions = expandV7Version(tagVersions); | ||
|
||
for (var v : versions.entrySet()) { | ||
Path recordFile = switch (v.getKey()) { | ||
case TRANSPORT_VERSION_TYPE -> rootDir.resolve(TRANSPORT_VERSIONS_RECORD); | ||
case INDEX_VERSION_TYPE -> rootDir.resolve(INDEX_VERSIONS_RECORD); | ||
default -> throw new IllegalArgumentException("Unknown version type " + v.getKey()); | ||
}; | ||
|
||
LOGGER.lifecycle("Adding version record for {} to [{}]: [{},{}]", v.getKey(), recordFile, releaseVersion, v.getValue()); | ||
|
||
Path file = rootDir.resolve(recordFile); | ||
List<String> versionRecords = Files.readAllLines(file); | ||
var modified = addVersionRecord(versionRecords, releaseVersion, v.getValue()); | ||
if (modified.isPresent()) { | ||
Files.write( | ||
file, | ||
modified.get(), | ||
StandardOpenOption.CREATE, | ||
StandardOpenOption.WRITE, | ||
StandardOpenOption.TRUNCATE_EXISTING | ||
); | ||
} | ||
} | ||
} | ||
|
||
/* | ||
* V7 just extracts a single Version. If so, this version needs to be applied to transport and index versions. | ||
*/ | ||
private static Map<String, Integer> expandV7Version(Map<String, Integer> tagVersions) { | ||
Integer v7Version = tagVersions.get("Version"); | ||
if (v7Version == null) return tagVersions; | ||
|
||
return Map.of(TRANSPORT_VERSION_TYPE, v7Version, INDEX_VERSION_TYPE, v7Version); | ||
} | ||
|
||
private static final Pattern VERSION_LINE = Pattern.compile("(\\d+\\.\\d+\\.\\d+),(\\d+)"); | ||
|
||
static Optional<List<String>> addVersionRecord(List<String> versionRecordLines, Version release, int id) { | ||
Map<Version, Integer> versions = versionRecordLines.stream().map(l -> { | ||
Matcher m = VERSION_LINE.matcher(l); | ||
if (m.matches() == false) throw new IllegalArgumentException(String.format("Incorrect format for line [%s]", l)); | ||
return m; | ||
}).collect(Collectors.toMap(m -> Version.fromString(m.group(1)), m -> Integer.parseInt(m.group(2)))); | ||
|
||
Integer existing = versions.putIfAbsent(release, id); | ||
if (existing != null) { | ||
if (existing.equals(id)) { | ||
LOGGER.lifecycle("Version id [{}] for release [{}] already recorded", id, release); | ||
return Optional.empty(); | ||
} else { | ||
throw new IllegalArgumentException( | ||
String.format( | ||
"Release [%s] already recorded with version id [%s], cannot update to version [%s]", | ||
release, | ||
existing, | ||
id | ||
) | ||
); | ||
} | ||
} | ||
|
||
return Optional.of( | ||
versions.entrySet().stream().sorted(Map.Entry.comparingByKey()).map(e -> e.getKey() + "," + e.getValue()).toList() | ||
); | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
.../test/java/org/elasticsearch/gradle/internal/release/ExtractCurrentVersionsTaskTests.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
package org.elasticsearch.gradle.internal.release; | ||
|
||
import com.github.javaparser.StaticJavaParser; | ||
import com.github.javaparser.ast.body.FieldDeclaration; | ||
|
||
import org.elasticsearch.gradle.internal.release.ExtractCurrentVersionsTask.FieldIdExtractor; | ||
import org.junit.Test; | ||
|
||
import static org.hamcrest.MatcherAssert.assertThat; | ||
import static org.hamcrest.Matchers.is; | ||
|
||
public class ExtractCurrentVersionsTaskTests { | ||
|
||
@Test | ||
public void testFieldExtractor() { | ||
var unit = StaticJavaParser.parse(""" | ||
public class Version { | ||
public static final Version V_1 = def(1); | ||
public static final Version V_2 = def(2); | ||
public static final Version V_3 = def(3); | ||
|
||
// ignore fields with no or more than one int | ||
public static final Version REF = V_3; | ||
public static final Version COMPUTED = compute(100, 200); | ||
}"""); | ||
|
||
FieldIdExtractor extractor = new FieldIdExtractor(); | ||
unit.walk(FieldDeclaration.class, extractor); | ||
assertThat(extractor.highestVersionId(), is(3)); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.