Added migration/index.asciidoc generation support (#87318)

Including extracting static content from migration/index, so the template would be as light as possible.

The reason for this work is because the gradle task `generateReleaseNotes` was not correctly adding new links and imports to the migrations/index and that caused documentation to fail building for 8.3.0.
This commit is contained in:
Craig Taverner 2022-06-02 16:05:18 +02:00 committed by GitHub
parent 8f31c02dad
commit a4e0d9b9dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 196 additions and 31 deletions

View file

@ -56,11 +56,13 @@ public class GenerateReleaseNotesTask extends DefaultTask {
private final RegularFileProperty releaseNotesTemplate;
private final RegularFileProperty releaseHighlightsTemplate;
private final RegularFileProperty breakingChangesTemplate;
private final RegularFileProperty migrationIndexTemplate;
private final RegularFileProperty releaseNotesIndexFile;
private final RegularFileProperty releaseNotesFile;
private final RegularFileProperty releaseHighlightsFile;
private final RegularFileProperty breakingChangesMigrationFile;
private final RegularFileProperty migrationIndexFile;
private final GitWrapper gitWrapper;
@ -72,11 +74,13 @@ public class GenerateReleaseNotesTask extends DefaultTask {
releaseNotesTemplate = objectFactory.fileProperty();
releaseHighlightsTemplate = objectFactory.fileProperty();
breakingChangesTemplate = objectFactory.fileProperty();
migrationIndexTemplate = objectFactory.fileProperty();
releaseNotesIndexFile = objectFactory.fileProperty();
releaseNotesFile = objectFactory.fileProperty();
releaseHighlightsFile = objectFactory.fileProperty();
breakingChangesMigrationFile = objectFactory.fileProperty();
migrationIndexFile = objectFactory.fileProperty();
gitWrapper = new GitWrapper(execOperations);
}
@ -137,6 +141,13 @@ public class GenerateReleaseNotesTask extends DefaultTask {
this.breakingChangesMigrationFile.get().getAsFile(),
entries
);
LOGGER.info("Updating migration/index...");
MigrationIndexGenerator.update(
getMinorVersions(versions),
this.migrationIndexTemplate.get().getAsFile(),
this.migrationIndexFile.get().getAsFile()
);
}
/**
@ -154,6 +165,14 @@ public class GenerateReleaseNotesTask extends DefaultTask {
.collect(toSet());
}
/**
* Convert set of QualifiedVersion to MinorVersion by deleting all but the major and minor components.
*/
@VisibleForTesting
static Set<MinorVersion> getMinorVersions(Set<QualifiedVersion> versions) {
return versions.stream().map(MinorVersion::of).collect(toSet());
}
/**
* Group a set of files by the version in which they first appeared, up until the supplied version. Any files not
* present in an earlier version are assumed to have been introduced in the specified version.
@ -320,6 +339,15 @@ public class GenerateReleaseNotesTask extends DefaultTask {
this.breakingChangesTemplate.set(file);
}
@InputFile
public RegularFileProperty getMigrationIndexTemplate() {
return migrationIndexTemplate;
}
public void setMigrationIndexTemplate(RegularFile file) {
this.migrationIndexTemplate.set(file);
}
@OutputFile
public RegularFileProperty getReleaseNotesIndexFile() {
return releaseNotesIndexFile;
@ -355,4 +383,13 @@ public class GenerateReleaseNotesTask extends DefaultTask {
public void setBreakingChangesMigrationFile(RegularFile file) {
this.breakingChangesMigrationFile.set(file);
}
@OutputFile
public RegularFileProperty getMigrationIndexFile() {
return migrationIndexFile;
}
public void setMigrationIndexFile(RegularFile file) {
this.migrationIndexFile.set(file);
}
}

View file

@ -0,0 +1,50 @@
/*
* 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.google.common.annotations.VisibleForTesting;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
import static java.util.Comparator.reverseOrder;
/**
* This class ensures that the migrate/index page has the appropriate anchors and include directives
* for the current repository version.
*/
public class MigrationIndexGenerator {
static void update(Set<MinorVersion> versions, File indexTemplate, File indexFile) throws IOException {
try (FileWriter indexFileWriter = new FileWriter(indexFile)) {
indexFileWriter.write(generateFile(versions, Files.readString(indexTemplate.toPath())));
}
}
@VisibleForTesting
static String generateFile(Set<MinorVersion> versionsSet, String template) throws IOException {
final Set<MinorVersion> versions = new TreeSet<>(reverseOrder());
versions.addAll(versionsSet);
final List<String> includeVersions = versions.stream().map(MinorVersion::underscore).collect(Collectors.toList());
final Map<String, Object> bindings = new HashMap<>();
bindings.put("versions", versions);
bindings.put("includeVersions", includeVersions);
return TemplateUtils.render(template, bindings);
}
}

View file

@ -0,0 +1,47 @@
/*
* 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 java.util.Comparator;
import java.util.Objects;
/**
* Encapsulates comparison and printing logic for an x.y.
*/
public record MinorVersion(int major, int minor) implements Comparable<MinorVersion> {
/**
* Converts a QualifiedVersion into a MinorVersion by deleting all but the major and minor components.
*/
public static MinorVersion of(final QualifiedVersion v) {
Objects.requireNonNull(v);
return new MinorVersion(v.major(), v.minor());
}
@Override
public String toString() {
return major + "." + minor;
}
/** Generate version string with underscore instead of dot */
public String underscore() {
return major + "_" + minor;
}
private static final Comparator<MinorVersion> COMPARATOR = Comparator.comparing((MinorVersion v) -> v.major)
.thenComparing(v -> v.minor);
@Override
public int compareTo(MinorVersion other) {
return COMPARATOR.compare(this, other);
}
public boolean isBefore(MinorVersion other) {
return this.compareTo(other) < 0;
}
}

View file

@ -96,6 +96,8 @@ public class ReleaseToolsPlugin implements Plugin<Project> {
String.format("docs/reference/migration/migrate_%d_%d.asciidoc", version.getMajor(), version.getMinor())
)
);
task.setMigrationIndexTemplate(projectDirectory.file(RESOURCES + "templates/migration-index.asciidoc"));
task.setMigrationIndexFile(projectDirectory.file("docs/reference/migration/index.asciidoc"));
task.dependsOn(validateChangelogsTask);
});

View file

@ -0,0 +1,4 @@
include::migration_intro.asciidoc[]
<% versions.each { print "* <<migrating-${ it },Migrating to ${ it }>>\n" } %>
<% includeVersions.each { print "include::migrate_${ it }.asciidoc[]\n" } %>

View file

@ -180,6 +180,29 @@ public class GenerateReleaseNotesTaskTest extends GradleUnitTestCase {
);
}
/**
* Check that when deriving a list of major.minor versions from git tags, the current unreleased version is included,
* but any higher version numbers are not.
*/
@Test
public void getMinorVersions_includesCurrentButNotFutureVersions() {
// given:
when(gitWrapper.listVersions(anyString())).thenReturn(
Stream.of("8.0.0-alpha1", "8.0.0-alpha2", "8.0.0", "8.0.1", "8.1.0", "8.2.0", "8.2.1", "8.3.0", "8.3.1", "8.4.0")
.map(QualifiedVersion::of)
);
// when:
Set<QualifiedVersion> versions = GenerateReleaseNotesTask.getVersions(gitWrapper, "8.3.0-SNAPSHOT");
Set<MinorVersion> minorVersions = GenerateReleaseNotesTask.getMinorVersions(versions);
// then:
assertThat(
minorVersions,
containsInAnyOrder(new MinorVersion(8, 0), new MinorVersion(8, 1), new MinorVersion(8, 2), new MinorVersion(8, 3))
);
}
/**
* Check that the task partitions the list of files correctly by version for a prerelease.
*/

View file

@ -1,34 +1,4 @@
[[breaking-changes]]
= Migration guide
This section discusses the changes that you need to be aware of to migrate
your application to {version}. For more information about what's new in this
release, see the <<release-highlights>> and <<es-release-notes>>.
As {es} introduces new features and improves existing ones, the changes
sometimes make older settings, APIs, and parameters obsolete. We typically
deprecate obsolete functionality as part of a release. If possible, we support
the deprecated functionality for several subsequent releases before removing it.
This enables applications to continue working unchanged while you prepare to
migrate away from the deprecated functionality.
To get the most out of {es} and facilitate future upgrades, we strongly
encourage migrating away from using deprecated functionality as soon as
possible.
To give you insight into what deprecated features you're using, {es}:
- Returns a `Warn` HTTP header whenever you
submit a request that uses deprecated functionality.
- <<deprecation-logging, Logs deprecation warnings>> when
deprecated functionality is used.
- <<migration-api-deprecation, Provides a deprecation info API>>
that scans a cluster's configuration
and mappings for deprecated functionality.
For more information about {minor-version},
see the <<release-highlights>> and <<es-release-notes>>.
For information about how to upgrade your cluster, see <<setup-upgrade>>.
include::migration_intro.asciidoc[]
* <<migrating-8.1,Migrating to 8.2>>
* <<migrating-8.1,Migrating to 8.1>>
@ -37,3 +7,4 @@ For information about how to upgrade your cluster, see <<setup-upgrade>>.
include::migrate_8_2.asciidoc[]
include::migrate_8_1.asciidoc[]
include::migrate_8_0.asciidoc[]

View file

@ -0,0 +1,31 @@
[[breaking-changes]]
= Migration guide
This section discusses the changes that you need to be aware of to migrate
your application to {version}. For more information about what's new in this
release, see the <<release-highlights>> and <<es-release-notes>>.
As {es} introduces new features and improves existing ones, the changes
sometimes make older settings, APIs, and parameters obsolete. We typically
deprecate obsolete functionality as part of a release. If possible, we support
the deprecated functionality for several subsequent releases before removing it.
This enables applications to continue working unchanged while you prepare to
migrate away from the deprecated functionality.
To get the most out of {es} and facilitate future upgrades, we strongly
encourage migrating away from using deprecated functionality as soon as
possible.
To give you insight into what deprecated features you're using, {es}:
- Returns a `Warn` HTTP header whenever you
submit a request that uses deprecated functionality.
- <<deprecation-logging, Logs deprecation warnings>> when
deprecated functionality is used.
- <<migration-api-deprecation, Provides a deprecation info API>>
that scans a cluster's configuration
and mappings for deprecated functionality.
For more information about {minor-version},
see the <<release-highlights>> and <<es-release-notes>>.
For information about how to upgrade your cluster, see <<setup-upgrade>>.