Skip to content

Commit 6b30159

Browse files
mark-vieirapugnascotiaelasticmachine
authored
Updates to changelog processing after docs redesign (#89463) (#89476)
# Conflicts: # build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/release/ReleaseHighlightsGeneratorTest.java # build-tools-internal/src/test/resources/org/elasticsearch/gradle/internal/release/ReleaseHighlightsGeneratorTest.generateFile.asciidoc # docs/changelog/83345.yaml Co-authored-by: Rory Hunter <[email protected]> Co-authored-by: Elastic Machine <[email protected]>
1 parent e22e64e commit 6b30159

21 files changed

+502
-157
lines changed

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/BreakingChangesGenerator.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ static String generateMigrationFile(QualifiedVersion version, String template, L
7474
bindings.put("deprecationsByNotabilityByArea", deprecationsByNotabilityByArea);
7575
bindings.put("isElasticsearchSnapshot", version.isSnapshot());
7676
bindings.put("majorDotMinor", version.major() + "." + version.minor());
77+
bindings.put("majorDotMinorDotRevision", version.major() + "." + version.minor() + "." + version.revision());
7778
bindings.put("majorMinor", String.valueOf(version.major()) + version.minor());
7879
bindings.put("nextMajor", (version.major() + 1) + ".0");
7980
bindings.put("version", version);

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/ChangelogEntry.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ public Highlight getHighlight() {
9999

100100
public void setHighlight(Highlight highlight) {
101101
this.highlight = highlight;
102+
if (this.highlight != null) this.highlight.pr = this.pr;
102103
}
103104

104105
public Breaking getBreaking() {
@@ -160,6 +161,7 @@ public static class Highlight {
160161
private boolean notable;
161162
private String title;
162163
private String body;
164+
private Integer pr;
163165

164166
public boolean isNotable() {
165167
return notable;
@@ -189,6 +191,10 @@ public String getAnchor() {
189191
return generatedAnchor(this.title);
190192
}
191193

194+
public Integer getPr() {
195+
return pr;
196+
}
197+
192198
@Override
193199
public boolean equals(Object o) {
194200
if (this == o) {

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/GenerateReleaseNotesTask.java

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import java.util.Locale;
3838
import java.util.Map;
3939
import java.util.Set;
40+
import java.util.stream.Stream;
4041

4142
import javax.inject.Inject;
4243

@@ -55,11 +56,13 @@ public class GenerateReleaseNotesTask extends DefaultTask {
5556
private final RegularFileProperty releaseNotesTemplate;
5657
private final RegularFileProperty releaseHighlightsTemplate;
5758
private final RegularFileProperty breakingChangesTemplate;
59+
private final RegularFileProperty migrationIndexTemplate;
5860

5961
private final RegularFileProperty releaseNotesIndexFile;
6062
private final RegularFileProperty releaseNotesFile;
6163
private final RegularFileProperty releaseHighlightsFile;
6264
private final RegularFileProperty breakingChangesMigrationFile;
65+
private final RegularFileProperty migrationIndexFile;
6366

6467
private final GitWrapper gitWrapper;
6568

@@ -71,11 +74,13 @@ public GenerateReleaseNotesTask(ObjectFactory objectFactory, ExecOperations exec
7174
releaseNotesTemplate = objectFactory.fileProperty();
7275
releaseHighlightsTemplate = objectFactory.fileProperty();
7376
breakingChangesTemplate = objectFactory.fileProperty();
77+
migrationIndexTemplate = objectFactory.fileProperty();
7478

7579
releaseNotesIndexFile = objectFactory.fileProperty();
7680
releaseNotesFile = objectFactory.fileProperty();
7781
releaseHighlightsFile = objectFactory.fileProperty();
7882
breakingChangesMigrationFile = objectFactory.fileProperty();
83+
migrationIndexFile = objectFactory.fileProperty();
7984

8085
gitWrapper = new GitWrapper(execOperations);
8186
}
@@ -136,6 +141,13 @@ public void executeTask() throws IOException {
136141
this.breakingChangesMigrationFile.get().getAsFile(),
137142
entries
138143
);
144+
145+
LOGGER.info("Updating migration/index...");
146+
MigrationIndexGenerator.update(
147+
getMinorVersions(versions),
148+
this.migrationIndexTemplate.get().getAsFile(),
149+
this.migrationIndexFile.get().getAsFile()
150+
);
139151
}
140152

141153
/**
@@ -146,11 +158,19 @@ public void executeTask() throws IOException {
146158
*/
147159
@VisibleForTesting
148160
static Set<QualifiedVersion> getVersions(GitWrapper gitWrapper, String currentVersion) {
149-
QualifiedVersion v = QualifiedVersion.of(currentVersion);
150-
final String pattern = "v" + v.major() + ".*";
151-
Set<QualifiedVersion> versions = gitWrapper.listVersions(pattern).collect(toSet());
152-
versions.add(v);
153-
return versions;
161+
QualifiedVersion qualifiedVersion = QualifiedVersion.of(currentVersion);
162+
final String pattern = "v" + qualifiedVersion.major() + ".*";
163+
// We may be generating notes for a minor version prior to the latest minor, so we need to filter out versions that are too new.
164+
return Stream.concat(gitWrapper.listVersions(pattern).filter(v -> v.isBefore(qualifiedVersion)), Stream.of(qualifiedVersion))
165+
.collect(toSet());
166+
}
167+
168+
/**
169+
* Convert set of QualifiedVersion to MinorVersion by deleting all but the major and minor components.
170+
*/
171+
@VisibleForTesting
172+
static Set<MinorVersion> getMinorVersions(Set<QualifiedVersion> versions) {
173+
return versions.stream().map(MinorVersion::of).collect(toSet());
154174
}
155175

156176
/**
@@ -319,6 +339,15 @@ public void setBreakingChangesTemplate(RegularFile file) {
319339
this.breakingChangesTemplate.set(file);
320340
}
321341

342+
@InputFile
343+
public RegularFileProperty getMigrationIndexTemplate() {
344+
return migrationIndexTemplate;
345+
}
346+
347+
public void setMigrationIndexTemplate(RegularFile file) {
348+
this.migrationIndexTemplate.set(file);
349+
}
350+
322351
@OutputFile
323352
public RegularFileProperty getReleaseNotesIndexFile() {
324353
return releaseNotesIndexFile;
@@ -354,4 +383,13 @@ public RegularFileProperty getBreakingChangesMigrationFile() {
354383
public void setBreakingChangesMigrationFile(RegularFile file) {
355384
this.breakingChangesMigrationFile.set(file);
356385
}
386+
387+
@OutputFile
388+
public RegularFileProperty getMigrationIndexFile() {
389+
return migrationIndexFile;
390+
}
391+
392+
public void setMigrationIndexFile(RegularFile file) {
393+
this.migrationIndexFile.set(file);
394+
}
357395
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
package org.elasticsearch.gradle.internal.release;
10+
11+
import com.google.common.annotations.VisibleForTesting;
12+
13+
import java.io.File;
14+
import java.io.FileWriter;
15+
import java.io.IOException;
16+
import java.nio.file.Files;
17+
import java.util.HashMap;
18+
import java.util.List;
19+
import java.util.Map;
20+
import java.util.Set;
21+
import java.util.TreeSet;
22+
import java.util.stream.Collectors;
23+
24+
import static java.util.Comparator.reverseOrder;
25+
26+
/**
27+
* This class ensures that the migrate/index page has the appropriate anchors and include directives
28+
* for the current repository version.
29+
*/
30+
public class MigrationIndexGenerator {
31+
32+
static void update(Set<MinorVersion> versions, File indexTemplate, File indexFile) throws IOException {
33+
try (FileWriter indexFileWriter = new FileWriter(indexFile)) {
34+
indexFileWriter.write(generateFile(versions, Files.readString(indexTemplate.toPath())));
35+
}
36+
}
37+
38+
@VisibleForTesting
39+
static String generateFile(Set<MinorVersion> versionsSet, String template) throws IOException {
40+
final Set<MinorVersion> versions = new TreeSet<>(reverseOrder());
41+
versions.addAll(versionsSet);
42+
final List<String> includeVersions = versions.stream().map(MinorVersion::underscore).collect(Collectors.toList());
43+
44+
final Map<String, Object> bindings = new HashMap<>();
45+
bindings.put("versions", versions);
46+
bindings.put("includeVersions", includeVersions);
47+
48+
return TemplateUtils.render(template, bindings);
49+
}
50+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
package org.elasticsearch.gradle.internal.release;
10+
11+
import java.util.Comparator;
12+
import java.util.Objects;
13+
14+
/**
15+
* Encapsulates comparison and printing logic for an x.y.
16+
*/
17+
public record MinorVersion(int major, int minor) implements Comparable<MinorVersion> {
18+
/**
19+
* Converts a QualifiedVersion into a MinorVersion by deleting all but the major and minor components.
20+
*/
21+
public static MinorVersion of(final QualifiedVersion v) {
22+
Objects.requireNonNull(v);
23+
return new MinorVersion(v.major(), v.minor());
24+
}
25+
26+
@Override
27+
public String toString() {
28+
return major + "." + minor;
29+
}
30+
31+
/** Generate version string with underscore instead of dot */
32+
public String underscore() {
33+
return major + "_" + minor;
34+
}
35+
36+
private static final Comparator<MinorVersion> COMPARATOR = Comparator.comparing((MinorVersion v) -> v.major)
37+
.thenComparing(v -> v.minor);
38+
39+
@Override
40+
public int compareTo(MinorVersion other) {
41+
return COMPARATOR.compare(this, other);
42+
}
43+
44+
public boolean isBefore(MinorVersion other) {
45+
return this.compareTo(other) < 0;
46+
}
47+
}

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/ReleaseHighlightsGenerator.java

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import java.io.IOException;
1818
import java.nio.file.Files;
1919
import java.util.ArrayList;
20+
import java.util.Comparator;
2021
import java.util.HashMap;
2122
import java.util.List;
2223
import java.util.Map;
@@ -43,21 +44,14 @@ static String generateFile(QualifiedVersion version, String template, List<Chang
4344
final int major = version.major();
4445
for (int minor = version.minor() - 1; minor >= 0; minor--) {
4546
String majorMinor = major + "." + minor;
46-
priorVersions.add(
47-
"{ref-bare}/"
48-
+ majorMinor
49-
+ "/release-highlights"
50-
+ (minor <= 6 ? "-" + majorMinor + ".0" : "")
51-
+ ".html["
52-
+ majorMinor
53-
+ "]"
54-
);
47+
priorVersions.add("{ref-bare}/" + majorMinor + "/release-highlights.html[" + majorMinor + "]");
5548
}
5649
}
5750

5851
final Map<Boolean, List<ChangelogEntry.Highlight>> groupedHighlights = entries.stream()
5952
.map(ChangelogEntry::getHighlight)
6053
.filter(Objects::nonNull)
54+
.sorted(Comparator.comparingInt(ChangelogEntry.Highlight::getPr))
6155
.collect(Collectors.groupingBy(ChangelogEntry.Highlight::isNotable, Collectors.toList()));
6256

6357
final List<ChangelogEntry.Highlight> notableHighlights = groupedHighlights.getOrDefault(true, List.of());

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/ReleaseNotesGenerator.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,6 @@ static String generateFile(String template, QualifiedVersion version, Set<Change
6868

6969
private static Map<String, Map<String, List<ChangelogEntry>>> buildChangelogBreakdown(Set<ChangelogEntry> changelogs) {
7070
Map<String, Map<String, List<ChangelogEntry>>> changelogsByTypeByArea = changelogs.stream()
71-
// Special case - we have a changelog file that isn't in the 'known-issue' or 'security' areas, but
72-
// doesn't have an ES PR for it.
73-
.filter(each -> each.getPr() == null || each.getPr() != -1)
7471
.collect(
7572
groupingBy(
7673
// Entries with breaking info are always put in the breaking section

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/ReleaseNotesIndexGenerator.java

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,6 @@
2929
*/
3030
public class ReleaseNotesIndexGenerator {
3131

32-
// Some versions where never released or were pulled. They shouldn't be listed.
33-
private static Set<QualifiedVersion> EXCLUDED_VERSIONS = Set.of(
34-
QualifiedVersion.of("7.0.1"),
35-
QualifiedVersion.of("7.13.3"),
36-
QualifiedVersion.of("7.13.4")
37-
);
38-
3932
static void update(Set<QualifiedVersion> versions, File indexTemplate, File indexFile) throws IOException {
4033
try (FileWriter indexFileWriter = new FileWriter(indexFile)) {
4134
indexFileWriter.write(generateFile(versions, Files.readString(indexTemplate.toPath())));
@@ -47,19 +40,9 @@ static String generateFile(Set<QualifiedVersion> versionsSet, String template) t
4740
final Set<QualifiedVersion> versions = new TreeSet<>(reverseOrder());
4841

4942
// For the purpose of generating the index, snapshot versions are the same as released versions. Prerelease versions are not.
50-
versionsSet.stream()
51-
.filter(v -> EXCLUDED_VERSIONS.contains(v) == false)
52-
.map(v -> v.isSnapshot() ? v.withoutQualifier() : v)
53-
.forEach(versions::add);
43+
versionsSet.stream().map(v -> v.isSnapshot() ? v.withoutQualifier() : v).forEach(versions::add);
5444

55-
final List<String> includeVersions = versions.stream()
56-
.map(
57-
version -> version.isBefore(QualifiedVersion.of("7.17.0")) && version.hasQualifier() == false
58-
? version.major() + "." + version.minor()
59-
: version.toString()
60-
)
61-
.distinct()
62-
.collect(Collectors.toList());
45+
final List<String> includeVersions = versions.stream().map(QualifiedVersion::toString).collect(Collectors.toList());
6346

6447
final Map<String, Object> bindings = new HashMap<>();
6548
bindings.put("versions", versions);

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/ReleaseToolsPlugin.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.elasticsearch.gradle.VersionProperties;
1313
import org.elasticsearch.gradle.internal.conventions.precommit.PrecommitTaskPlugin;
1414
import org.elasticsearch.gradle.internal.precommit.ValidateYamlAgainstSchemaTask;
15+
import org.gradle.api.Action;
1516
import org.gradle.api.Plugin;
1617
import org.gradle.api.Project;
1718
import org.gradle.api.file.Directory;
@@ -22,6 +23,7 @@
2223
import org.gradle.api.tasks.util.PatternSet;
2324

2425
import java.io.File;
26+
import java.util.function.Function;
2527

2628
import javax.inject.Inject;
2729

@@ -67,10 +69,14 @@ public void apply(Project project) {
6769
task.dependsOn(validateChangelogsAgainstYamlTask);
6870
});
6971

70-
project.getTasks().register("generateReleaseNotes", GenerateReleaseNotesTask.class).configure(task -> {
72+
final Function<Boolean, Action<GenerateReleaseNotesTask>> configureGenerateTask = shouldConfigureYamlFiles -> task -> {
7173
task.setGroup("Documentation");
72-
task.setDescription("Generates release notes from changelog files held in this checkout");
73-
task.setChangelogs(yamlFiles);
74+
if (shouldConfigureYamlFiles) {
75+
task.setChangelogs(yamlFiles);
76+
task.setDescription("Generates release notes from changelog files held in this checkout");
77+
} else {
78+
task.setDescription("Generates stub release notes e.g. after feature freeze");
79+
}
7480

7581
task.setReleaseNotesIndexTemplate(projectDirectory.file(RESOURCES + "templates/release-notes-index.asciidoc"));
7682
task.setReleaseNotesIndexFile(projectDirectory.file("docs/reference/release-notes.asciidoc"));
@@ -96,9 +102,16 @@ public void apply(Project project) {
96102
String.format("docs/reference/migration/migrate_%d_%d.asciidoc", version.getMajor(), version.getMinor())
97103
)
98104
);
105+
task.setMigrationIndexTemplate(projectDirectory.file(RESOURCES + "templates/migration-index.asciidoc"));
106+
task.setMigrationIndexFile(projectDirectory.file("docs/reference/migration/index.asciidoc"));
99107

100108
task.dependsOn(validateChangelogsTask);
101-
});
109+
};
110+
111+
project.getTasks().register("generateReleaseNotes", GenerateReleaseNotesTask.class).configure(configureGenerateTask.apply(true));
112+
project.getTasks()
113+
.register("generateStubReleaseNotes", GenerateReleaseNotesTask.class)
114+
.configure(configureGenerateTask.apply(false));
102115

103116
project.getTasks().register("pruneChangelogs", PruneChangelogsTask.class).configure(task -> {
104117
task.setGroup("Documentation");

0 commit comments

Comments
 (0)