Skip to content
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

Make the build version qualifier aware #32128

Closed
wants to merge 38 commits into from
Closed
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
2bb8616
Switch build to dynamically configured qualifiers
alpar-t Jul 17, 2018
9dd442c
Remove alpha1 from version qualifier
alpar-t Jul 17, 2018
9380817
Merge remote-tracking branch 'origin/master' into version-qualifier-a…
alpar-t Jul 17, 2018
08096d2
PR changes, version ID
alpar-t Jul 18, 2018
018fafa
Merge remote-tracking branch 'origin/master' into version-qualifier-a…
alpar-t Jul 18, 2018
76b67b3
Correct references to 7.0.0-alpha1
alpar-t Jul 23, 2018
ee2359f
Don't pass qualifier to plugin metadata
alpar-t Jul 23, 2018
54176b6
Rename from suffix to qualifier for consistency
alpar-t Jul 23, 2018
67c06f3
Temp: hard code information about released major
alpar-t Jul 23, 2018
cbaa33a
Add comment, reproduction info
alpar-t Aug 6, 2018
6071cfd
Merge remote-tracking branch 'origin/master' into version-qualifier-a…
alpar-t Aug 6, 2018
218bbf4
fix references to 7.0.0 alpha1
alpar-t Aug 6, 2018
d5ceca9
fix merge errort
alpar-t Aug 6, 2018
6507480
fix doc tests
alpar-t Aug 7, 2018
73d7496
drop snapshot and qualifier from version passed to packaging tests
alpar-t Aug 7, 2018
4c68d70
Fix tests failing to match versions
alpar-t Aug 8, 2018
ad58c10
fix packaging tests
alpar-t Aug 8, 2018
63910ab
Merge remote-tracking branch 'origin/master' into version-qualifier-a…
alpar-t Aug 8, 2018
de4b304
Merge branch 'master' into version-qualifier-aware
alpar-t Aug 10, 2018
13d92a5
Don't rely on version conventions for wildfly test
alpar-t Aug 10, 2018
75489c7
Merge remote-tracking branch 'origin/master' into version-qualifier-a…
alpar-t Aug 14, 2018
64a833d
Remove qualifier from version in manifest
alpar-t Aug 14, 2018
e10f818
update version IDs
alpar-t Aug 14, 2018
1fe9ac4
PR review
alpar-t Aug 15, 2018
051539d
PR review: change method names
alpar-t Aug 21, 2018
c9be34e
Merge remote-tracking branch 'origin/master' into version-qualifier-a…
alpar-t Aug 22, 2018
4195a55
replace reference to alpha1 version
alpar-t Aug 22, 2018
377b632
Merge remote-tracking branch 'origin/master' into version-qualifier-a…
alpar-t Aug 29, 2018
dd5122e
Don't allow for dash in qualifier
alpar-t Aug 29, 2018
d5a3f2e
remove qualifeir from version enums as part of merge
alpar-t Aug 29, 2018
6a47804
Merge remote-tracking branch 'origin/master' into version-qualifier-a…
alpar-t Aug 29, 2018
53b1fce
Merge remote-tracking branch 'origin/master' into version-qualifier-a…
alpar-t Aug 29, 2018
85d010e
Correct test failure
alpar-t Aug 30, 2018
6f53bd3
Merge remote-tracking branch 'origin/master' into version-qualifier-a…
alpar-t Aug 30, 2018
4074bc3
Merge remote-tracking branch 'origin/master' into version-qualifier-a…
alpar-t Aug 30, 2018
e76a255
Merge remote-tracking branch 'origin/master' into version-qualifier-a…
alpar-t Sep 6, 2018
2e7b567
PR review: remove snapshot and qualifier from version
alpar-t Sep 6, 2018
dcf67a9
Make clusterformation deal with snapshot and qualifier not in build
alpar-t Sep 6, 2018
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
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ subprojects {

apply plugin: 'nebula.info-scm'
String licenseCommit
if (VersionProperties.elasticsearch.toString().endsWith('-SNAPSHOT')) {
if (VersionProperties.elasticsearch.isSnapshot()) {
licenseCommit = scminfo.change ?: "master" // leniency for non git builds
} else {
licenseCommit = "v${version}"
Expand Down Expand Up @@ -102,7 +102,7 @@ subprojects {
* in a branch if there are only betas and rcs in the branch so we have
* *something* to test against. */
VersionCollection versions = new VersionCollection(file('server/src/main/java/org/elasticsearch/Version.java').readLines('UTF-8'))
if (versions.currentVersion != VersionProperties.elasticsearch) {
if (versions.currentVersion.isSameVersionNumber(VersionProperties.elasticsearch) == false) {
throw new GradleException("The last version in Versions.java [${versions.currentVersion}] does not match " +
"VersionProperties.elasticsearch [${VersionProperties.elasticsearch}]")
}
Expand Down
29 changes: 1 addition & 28 deletions buildSrc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
import java.nio.file.Files

plugins {
id 'java-gradle-plugin'
id 'groovy'
Expand Down Expand Up @@ -52,33 +50,8 @@ sourceCompatibility = minimumRuntimeVersion

Properties props = new Properties()
props.load(project.file('version.properties').newDataInputStream())
version = props.getProperty('elasticsearch')
boolean snapshot = "true".equals(System.getProperty("build.snapshot", "true"));
if (snapshot) {
// we update the version property to reflect if we are building a snapshot or a release build
// we write this back out below to load it in the Build.java which will be shown in rest main action
// to indicate this being a snapshot build or a release build.
version += "-SNAPSHOT"
props.put("elasticsearch", version);
}

File tempPropertiesFile = new File(project.buildDir, "version.properties")
task writeVersionProperties {
inputs.properties(props)
outputs.file(tempPropertiesFile)
doLast {
OutputStream stream = Files.newOutputStream(tempPropertiesFile.toPath());
try {
props.store(stream, "UTF-8");
} finally {
stream.close();
}
}
}

processResources {
dependsOn writeVersionProperties
from tempPropertiesFile
from file('version.properties')
}

/*****************************************************************************
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -696,18 +696,13 @@ class BuildPlugin implements Plugin<Project> {
jarTask.destinationDir = new File(project.buildDir, 'distributions')
// fixup the jar manifest
jarTask.doFirst {
final Version versionWithoutSnapshot = new Version(
VersionProperties.elasticsearch.major,
VersionProperties.elasticsearch.minor,
VersionProperties.elasticsearch.revision,
VersionProperties.elasticsearch.suffix,
false)
// this doFirst is added before the info plugin, therefore it will run
// after the doFirst added by the info plugin, and we can override attributes
jarTask.manifest.attributes(
'X-Compile-Elasticsearch-Version': versionWithoutSnapshot,
'X-Compile-Lucene-Version': VersionProperties.lucene,
'X-Compile-Elasticsearch-Version': VersionProperties.elasticsearch.dropSnapshot().dropQualifier(),
'X-Compile-Elasticsearch-Qualifier': VersionProperties.elasticsearch.qualifier,
'X-Compile-Elasticsearch-Snapshot': VersionProperties.elasticsearch.isSnapshot(),
'X-Compile-Lucene-Version': VersionProperties.lucene,
'Build-Date': ZonedDateTime.now(ZoneOffset.UTC),
'Build-Java-Version': project.compilerJavaVersion)
if (jarTask.manifest.attributes.containsKey('Change') == false) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,13 @@ import java.util.regex.Matcher
* Notes on terminology:
* - The case for major+1 being released is accomplished through the isReleasableBranch value. If this is false, then the branch is no longer
* releasable, meaning not to test against any snapshots.
* - Released is defined as having > 1 suffix-free version in a major.minor series. For instance, only 6.2.0 means unreleased, but a
* - Released is defined as having > 1 qualifier-free version in a major.minor series. For instance, only 6.2.0 means unreleased, but a
* 6.2.0 and 6.2.1 mean that 6.2.0 was released already.
*/
class VersionCollection {

public static final int LAST_RELEASED_MAJOR = 6

private final List<Version> versions
Version nextMinorSnapshot
Version stagedMinorSnapshot
Expand Down Expand Up @@ -93,15 +95,15 @@ class VersionCollection {
}

// If the major version has been released, then remove all of the alpha/beta/rc versions that exist in the set
versionSet.removeAll { it.suffix.isEmpty() == false && isMajorReleased(it, versionSet) }
versionSet.removeAll { it.qualifier.isEmpty() == false && isMajorReleased(it, versionSet) }

// set currentVersion
Version lastVersion = versionSet.last()
currentVersion = new Version(lastVersion.major, lastVersion.minor, lastVersion.revision, lastVersion.suffix, buildSnapshot)
currentVersion = new Version(lastVersion.major, lastVersion.minor, lastVersion.revision, lastVersion.qualifier, buildSnapshot)

// remove all of the potential alpha/beta/rc from the currentVersion
versionSet.removeAll {
it.suffix.isEmpty() == false &&
it.qualifier.isEmpty() == false &&
it.major == currentVersion.major &&
it.minor == currentVersion.minor &&
it.revision == currentVersion.revision }
Expand Down Expand Up @@ -281,10 +283,14 @@ class VersionCollection {
* This means that there is more than just a major.0.0 or major.0.0-alpha in a branch to signify it has been prevously released.
*/
private boolean isMajorReleased(Version version, TreeSet<Version> items) {
if (version.getMajor() <= LAST_RELEASED_MAJOR) {
// TODO: Starting with 7.0.0 we no longer store qualifiers in Version.java we are not able to tell from qualifiers
return true
}
return items
.tailSet(Version.fromString("${version.major}.0.0"))
.headSet(Version.fromString("${version.major + 1}.0.0"))
.count { it.suffix.isEmpty() } // count only non suffix'd versions as actual versions that may be released
.count { it.qualifier.isEmpty() } // count only non qualifier'd versions as actual versions that may be released
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: qualifier'd -> qualified

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, thanks

.intValue() > 1
}

Expand All @@ -301,7 +307,7 @@ class VersionCollection {
*/
private Version replaceAsSnapshot(Version version) {
versionSet.remove(version)
Version snapshotVersion = new Version(version.major, version.minor, version.revision, version.suffix, true)
Version snapshotVersion = new Version(version.major, version.minor, version.revision, version.qualifier, true)
safeAddToSet(snapshotVersion)
return snapshotVersion
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ public class DocsTestPlugin extends RestTestPlugin {
* the values may differ. In particular {version} needs to resolve
* to the version being built for testing but needs to resolve to
* the last released version for docs. */
'\\{version\\}':
VersionProperties.elasticsearch.toString().replace('-SNAPSHOT', ''),
'\\{version\\}': VersionProperties.elasticsearch.dropQualifier().dropSnapshot().toString(),
'\\{plugin_version\\}': VersionProperties.elasticsearch.toString(),
'\\{lucene_version\\}' : VersionProperties.lucene.replaceAll('-snapshot-\\w+$', ''),
'\\{build_flavor\\}' :
project.integTestCluster.distribution.startsWith('oss-') ? 'oss' : 'default',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,11 @@ class PluginPropertiesTask extends Copy {
}

Map<String, String> generateSubstitutions() {
def stringSnap = { version ->
if (version.endsWith("-SNAPSHOT")) {
return version.substring(0, version.length() - 9)
}
return version
}
return [
'name': extension.name,
'description': extension.description,
'version': stringSnap(extension.version),
'elasticsearchVersion': stringSnap(VersionProperties.elasticsearch.toString()),
'version': extension.version as String,
'elasticsearchVersion': VersionProperties.elasticsearch.dropQualifier().dropSnapshot() as String,
'javaVersion': project.targetCompatibility as String,
'classname': extension.classname,
'extendedPlugins': extension.extendedPlugins.join(','),
Expand Down
64 changes: 43 additions & 21 deletions buildSrc/src/main/java/org/elasticsearch/gradle/Version.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,43 @@ public final class Version implements Comparable<Version> {
/**
* Suffix on the version name.
*/
private final String suffix;
private final String qualifier;

private static final Pattern pattern =
Pattern.compile("(\\d)+\\.(\\d+)\\.(\\d+)(-alpha\\d+|-beta\\d+|-rc\\d+)?(-SNAPSHOT)?");

public Version(int major, int minor, int revision, String suffix, boolean snapshot) {
Version(int major, int minor, int revision, String qualifier, boolean snapshot) {
Objects.requireNonNull(major, "major version can't be null");
Objects.requireNonNull(minor, "minor version can't be null");
Objects.requireNonNull(revision, "revision version can't be null");
this.major = major;
this.minor = minor;
this.revision = revision;
this.snapshot = snapshot;
this.suffix = suffix == null ? "" : suffix;
if (qualifier == null || qualifier.isEmpty()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this leniency? The semantics should be either no qualifier is null, or empty string, but not either.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's because the instance was constructed with null most of the time but, we mostly get the qualifier to compare against it, so having "" instead is more convenient and readable.
We could disallow nulls in the constructor, I would clean this up as part of #32872

this.qualifier = "";
} else if (qualifier.startsWith("-")) {
this.qualifier = qualifier;
} else {
this.qualifier = "-" + qualifier;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to do the formatting here (prefixing with dash), or could this be done when printed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We used to store it with a dash so existing code expected it, but I didn't want to add have it in the property, so this takes care of that. I think the cleanest way would be to have an enum for the qualifier.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An enum won't work since these are numbered (or it would require separate variable to keep track of the number). But I don't see why the leniency needs to exist here to add the dash if it doesn't exist. I think the qualifier should always have no dash internally, just like we don't have dot prefixes on the numeric parts of the version.

}

int suffixOffset = 0;
if (this.suffix.isEmpty()) {
// no suffix will be considered smaller, uncomment to change that
if (this.qualifier.isEmpty()) {
// no qualifier will be considered smaller, uncomment to change that
// suffixOffset = 100;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of having this commented out conditional block? With the new rules, we shouldn't ever be comparing a qualified build against each other or a non qualified build, since qualified and non qualified of the same version have the exact same bwc behavior.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this comment some time ago when I discovered that 7.0.0 would be considered smaller than 7.0.0-alpha1 which is incorrect, but changing that caused failures in VersionCollection and I didn't want to dig deeper at that time so just left this comment as a reminder.
The qualifier will not be relevant indeed for bwc behavior, but it's still relevant for the build, e.x. we still want to use an beta over an alpha if available so the build still has to order them.
I'm hoping that with the metadata format in #32872 the proper ordering will be clearer and the implementation will clean up as a result as well.
I think these are simple things, yet hard to get right with harsh consequences if they are not right, I'm reluctant to change them without the visualization described in #32872 to be able to better reason about it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we still want to use an beta over an alpha

There shouldn't be anything needing to choose a beta over an alpha? There should be nothing using any qualified build to check bwc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the commented code to avoid confusion.
To make sure my understanding is correct: we will need to consider qualifier in the build, i.e. so we don't BWC test against an alpha if a beta is already available. This is for build only, server will not know of qualifier, so it has no way to decide based on it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know what you mean by "consider qualifier in the build". There should be no attempt to test bwc of any qualified version, so I don't believe the build needs to know about it in our build Version, since that class is all about which versions we bwc test against.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The version class is now used more broadly, including in figuring out dependencies ( as it's string value is set as project.version which is then used when considering dependencies ).
My understanding was that in BWC testing we will want to pic up alpha, beta etc as these become available, I'm starting to realize that since we don't offer guarantees we won't have to test with those and would just test against the latest snapshot and be ok.

I don't think we should remove the qualifier from the version right now, we should eventually better express requirements for a version used in bwc, perhaps as part of #32872.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The version class is now used more broadly, including in figuring out dependencies ( as it's string value is set as project.version which is then used when considering dependencies ).

There shouldn't be any dependencies on a qualified version, so there should be no need to serialize it into a string value.

I don't think we should remove the qualifier from the version right now, we should eventually better express requirements for a version used in bwc

Why would we keep something around that is unused? I think it only adds to confusion in a class that is already difficult to under (our gradle's Version class).

} else {
if (this.suffix.contains("alpha")) {
suffixOffset += parseSuffixNumber(this.suffix.substring(6));
} else if (this.suffix.contains("beta")) {
suffixOffset += 25 + parseSuffixNumber(this.suffix.substring(5));
} else if (this.suffix.contains("rc")) {
suffixOffset += 50 + parseSuffixNumber(this.suffix.substring(3));
if (this.qualifier.contains("alpha")) {
suffixOffset += parseSuffixNumber(this.qualifier.substring(6));
} else if (this.qualifier.contains("beta")) {
suffixOffset += 25 + parseSuffixNumber(this.qualifier.substring(5));
} else if (this.qualifier.contains("rc")) {
suffixOffset += 50 + parseSuffixNumber(this.qualifier.substring(3));
}
else {
throw new IllegalArgumentException("Suffix must contain one of: alpha, beta or rc");
throw new IllegalArgumentException(
"Suffix must contain one of: alpha, beta or rc instead of: " + this.qualifier
);
}
}

Expand All @@ -54,7 +62,7 @@ public Version(int major, int minor, int revision, String suffix, boolean snapsh

private static int parseSuffixNumber(String substring) {
if (substring.isEmpty()) {
throw new IllegalArgumentException("Invalid suffix, must contain a number e.x. alpha2");
throw new IllegalArgumentException("Invalid qualifier, must contain a number e.x. alpha2");
}
return Integer.parseInt(substring);
}
Expand All @@ -81,7 +89,7 @@ public static Version fromString(final String s) {
public String toString() {
final String snapshotStr = snapshot ? "-SNAPSHOT" : "";
return String.valueOf(getMajor()) + "." + String.valueOf(getMinor()) + "." + String.valueOf(getRevision()) +
(suffix == null ? "" : suffix) + snapshotStr;
(qualifier == null ? "" : qualifier) + snapshotStr;
}

public boolean before(Version compareTo) {
Expand Down Expand Up @@ -121,12 +129,12 @@ public boolean onOrBeforeIncludingSuffix(Version otherVersion) {
return id < otherVersion.getId();
}

if (suffix.equals("")) {
return otherVersion.getSuffix().equals("");
if (qualifier.equals("")) {
return otherVersion.getQualifier().equals("");
}


return otherVersion.getSuffix().equals("") || suffix.compareTo(otherVersion.getSuffix()) < 0;
return otherVersion.getQualifier().equals("") || qualifier.compareTo(otherVersion.getQualifier()) < 0;
}

@Override
Expand All @@ -139,13 +147,27 @@ public boolean equals(Object o) {
revision == version.revision &&
id == version.id &&
snapshot == version.snapshot &&
Objects.equals(suffix, version.suffix);
Objects.equals(qualifier, version.qualifier);
}

@Override
public int hashCode() {

return Objects.hash(major, minor, revision, id, snapshot, suffix);
return Objects.hash(major, minor, revision, id, snapshot, qualifier);
}

public boolean isSameVersionNumber(Version other) {
return major == other.major &&
minor == other.minor &&
revision == other.revision;
}

public Version dropQualifier() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can we use the "without" terminology? I think this better matches other code like the builders for java time stuff having egwithTimeZone. Drop implies mutating the current object.

return new Version(major, minor, revision, "", snapshot);
}

public Version dropSnapshot() {
return new Version(major, minor, revision, qualifier, false);
}

public int getMajor() {
Expand All @@ -168,8 +190,8 @@ public boolean isSnapshot() {
return snapshot;
}

public String getSuffix() {
return suffix;
public String getQualifier() {
return qualifier;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,29 @@ public static Map<String, String> getVersions() {
private static final Map<String, String> versions = new HashMap<String, String>();
static {
Properties props = getVersionProperties();
elasticsearch = Version.fromString(props.getProperty("elasticsearch"));
Version baseVersion = Version.fromString(props.getProperty("elasticsearch"));
if (baseVersion.isSnapshot()) {
throw new IllegalArgumentException("version.properties can't contain a snapshot version for elasticsearch. " +
"Use the `build.snapshot` property instead.");
}
if (baseVersion.getQualifier().isEmpty() == false) {
throw new IllegalArgumentException("version.properties can't contain a version qualifier for elasticsearch." +
"Use the `build.version_qualifier` property instead.");
}
elasticsearch = new Version(
baseVersion.getMajor(),
baseVersion.getMinor(),
baseVersion.getRevision(),
// TODO: Change default to "" after CI "warm-up" by adding -Dbuild.version_qualifier="" to ML jobs to produce
// a snapshot.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We now have the ability to set the ML C++ version qualifier when kicking off a build, so if it makes life easier for you I can create a one-off build of ML C++ 7.0.0-SNAPSHOT artifacts now so that the PR build can pass with a default qualifier of "". Then ping me when you merge this PR and I'll change the value for the periodic ML C++ builds to be no qualifier too.

System.getProperty("build.version_qualifier", "alpha1"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not default to alpha1. It should default to the empty string. In the production of our nightly snapshots we want to set this externally now and we will start with alpha1.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this also means that we need to percolate this through to CI otherwise the builds will be looking for ML 7.0.0-SNAPSHOT artifacts which will not exist.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One reason that I do not like the default of alpha1 and instead prefer this to be completely managed externally is that we can end up with the following sequence:

  • today we are producing alpha1 snapshots
  • at some point we will bump to producing alpha2 snapshots
  • with this default, we would still be running alpha1 in CI and that's confusing and wrong (wrong because we need it to be alpha2 to pick up the latest ML builds)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the confusion is that without any qualifier, we'll be producing 7.0.0-SNAPSHOT which is not something we produce now AFAIK, as we go 7.0.0-alpha1-SNAPSHOT -> e.x 7.0.0-rc3-SNAPSHOT -> 7.0.0-rc3 -> 7.0.0. In this context 7.0.0-SNAPSHOT is a pre-alpha1 .
We need to check the Version class in the build for this, since I don't think it compares like that.
It will a bit awkward to start with 7.0.0-SNAPSHOT end with 7.0.0. and have all the qualifiers in between, but I think it's the only way to have a default to no qualifier. That means CI will use this default while we are in development mode, and start using the alpha1 qualifier close to the release only. We don't want to force people building outside of CI to pass this, and knowing this always passing it in CI feels like to big of a difference to me. If we do this, a good way to percolate this to CI is to merge it like this, with alpha1 as default, then start changing it to empty in CI and eventually change the code to default to empty and remove the parameter from CI.

An alternative is to continue having the qualifier in version.properties, but also allow for a property. This way the bump from -alpha1 to alpha2 all the way to rc3 will be a code change,
but if we are happy with rc3 our job to produce the final release will not do a code change but pass in the qualifier using the property to override the one in version.properties. I think this might be a more straight forward approach as it avoids 7.0.0-SNAPSHOT. We can even enforce that an empty qualifier can't be a snapshot. It's also easier to propagate and less disruptive overall.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am starting to come around to the view that we simply always produce unqualified builds, yet from time to time we will ship a qualified build with a progression of alpha1, alpha2, etc. as we head towards GA. This feels like the simplest approach and I am not seeing any major downsides? We would still need to bake the qualifier into the version ID when a qualified build is produced though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jasontedor you mean to have CI always build a snapshot without a qualifier like 7.0.0-SNAPSHOT and then when we want to ship something we would have one with a qualifier only then e.x 7.0.0-alpha1 so we'll have snapshots before and after the qualified build without distinguishing them. Snapshot and qualifier will become mutually exclusive.

I like it how that simplifies things, and I think it is ok since we either don't consider the qualifiers already ( e.x. we remove qualified versions from bwc tests ) or we are making changes to compare without the version qualifier ( e.x. when comparing build with Version.java and when comparing plugin vs es version ). The only risk I can think of is that we will never run those qualified builds that we make time to time trough our testing. Is there already some sanity tests that runs on artifacts produced by the RM ? That being said, this isn't entirely new, it's just one way there could be differences between elasticsearch ci and RM and the version comparison code is easy to unit test to make sure it does the right thing.

Boolean.parseBoolean(System.getProperty("build.snapshot", "true"))
);
lucene = props.getProperty("lucene");
for (String property : props.stringPropertyNames()) {
versions.put(property, props.getProperty(property));
}
versions.put("elasticsearch", elasticsearch.toString());
}

private static Properties getVersionProperties() {
Expand Down
Loading