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

New release notes generator tasks #71125

Merged
merged 31 commits into from
Jul 28, 2021
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
54f0b83
Define tasks for handling release notes
pugnascotia Mar 29, 2021
507142d
Revise generated changelog files
pugnascotia Mar 31, 2021
288efb7
Fixing YAML files
pugnascotia Mar 31, 2021
21c44b2
Leave only a test set of yaml files
pugnascotia Mar 31, 2021
c0f241b
Merge remote-tracking branch 'upstream/master' into 67335-new-changel…
pugnascotia Mar 31, 2021
c715d20
Address review feedback
pugnascotia Apr 7, 2021
0f98874
Link validateChangelogs task to precommit
pugnascotia Apr 7, 2021
da15f7e
Merge remote-tracking branch 'upstream/master' into 67335-new-changel…
pugnascotia Apr 19, 2021
fef52ec
Fix property name, auto-generate anchor value
pugnascotia Apr 19, 2021
7bc66a3
Tweaks to schema
pugnascotia Apr 20, 2021
a608417
Add further validation beyond schema check
pugnascotia Apr 20, 2021
4db9aca
Merge remote-tracking branch 'upstream/master' into 67335-new-changel…
pugnascotia Apr 26, 2021
ef4969f
Merge remote-tracking branch 'upstream/master' into 67335-new-changel…
pugnascotia Jun 9, 2021
ed70b89
Fixes after merge
pugnascotia Jun 10, 2021
6b54e2e
Tweaks
pugnascotia Jun 10, 2021
22a0e8c
Switch to using SimpleTemplateEngine
pugnascotia Jun 10, 2021
6e24def
Various fixes
pugnascotia Jun 14, 2021
f715472
Support 'security' and 'known-issue' entries
pugnascotia Jun 15, 2021
a3c3109
Make it possible to test generator code
pugnascotia Jun 15, 2021
8831b10
Merge remote-tracking branch 'upstream/master' into 67335-new-changel…
pugnascotia Jun 15, 2021
f489015
Test changelog files
pugnascotia Jun 18, 2021
d3ee9b7
Review feedback
pugnascotia Jun 24, 2021
4f05927
Merge remote-tracking branch 'upstream/master' into 67335-new-changel…
pugnascotia Jun 24, 2021
3e4d604
Merge remote-tracking branch 'upstream/master' into 67335-new-changel…
pugnascotia Jul 9, 2021
2d52eed
Run changelogs tasks via precommit
pugnascotia Jul 9, 2021
1a0a734
Version parsing fixes
pugnascotia Jul 10, 2021
2f0e923
Actually commit my changes
pugnascotia Jul 12, 2021
7b697c2
Remove copy of VersionTests.java
pugnascotia Jul 12, 2021
ca19c41
Merge branch 'master' into 67335-new-changelog-process
elasticmachine Jul 12, 2021
dfeaae2
Merge remote-tracking branch 'upstream/master' into 67335-new-changel…
pugnascotia Jul 27, 2021
f2125e3
Remove test yaml files
pugnascotia Jul 27, 2021
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: 4 additions & 0 deletions build-tools-internal/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ gradlePlugin {
id = 'elasticsearch.jdk-download'
implementationClass = 'org.elasticsearch.gradle.internal.JdkDownloadPlugin'
}
releaseTools {
id = 'elasticsearch.release-tools'
implementationClass = 'org.elasticsearch.gradle.internal.release.ReleaseToolsPlugin'
}
repositories {
id = 'elasticsearch.repositories'
implementationClass = 'org.elasticsearch.gradle.internal.RepositoriesSetupPlugin'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@
import org.gradle.api.file.FileCollection;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.Internal;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;
import org.gradle.work.ChangeType;
import org.gradle.work.FileChange;
import org.gradle.work.Incremental;
import org.gradle.work.InputChanges;

Expand All @@ -42,8 +44,6 @@
* Incremental task to validate a set of JSON files against against a schema.
*/
public class ValidateJsonAgainstSchemaTask extends DefaultTask {

private final ObjectMapper mapper = new ObjectMapper();
private File jsonSchema;
private File report;
private FileCollection inputFiles;
Expand Down Expand Up @@ -76,28 +76,36 @@ public File getReport() {
return this.report;
}

@Internal
protected ObjectMapper getMapper() {
return new ObjectMapper();
}

@Internal
protected String getFileType() {
return "JSON";
}

@TaskAction
public void validate(InputChanges inputChanges) throws IOException {
File jsonSchemaOnDisk = getJsonSchema();
getLogger().debug("JSON schema : [{}]", jsonSchemaOnDisk.getAbsolutePath());
SchemaValidatorsConfig config = new SchemaValidatorsConfig();
JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7);
JsonSchema jsonSchema = factory.getSchema(mapper.readTree(jsonSchemaOnDisk), config);
Map<File, Set<String>> errors = new LinkedHashMap<>();
final File jsonSchemaOnDisk = getJsonSchema();
final JsonSchema jsonSchema = buildSchemaObject(jsonSchemaOnDisk);

final Map<File, Set<String>> errors = new LinkedHashMap<>();
final ObjectMapper mapper = this.getMapper();

// incrementally evaluate input files
// validate all files and hold on to errors for a complete report if there are failures
StreamSupport.stream(inputChanges.getFileChanges(getInputFiles()).spliterator(), false)
.filter(f -> f.getChangeType() != ChangeType.REMOVED)
.forEach(fileChange -> {
File file = fileChange.getFile();
if (file.isDirectory() == false) {
// validate all files and hold on to errors for a complete report if there are failures
getLogger().debug("Validating JSON [{}]", file.getName());
try {
Set<ValidationMessage> validationMessages = jsonSchema.validate(mapper.readTree(file));
maybeLogAndCollectError(validationMessages, errors, file);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
.map(FileChange::getFile)
.filter(file -> file.isDirectory() == false)
.forEach(file -> {
try {
Set<ValidationMessage> validationMessages = jsonSchema.validate(mapper.readTree(file));
maybeLogAndCollectError(validationMessages, errors, file);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
if (errors.isEmpty()) {
Expand All @@ -119,9 +127,17 @@ public void validate(InputChanges inputChanges) throws IOException {
}
}

private JsonSchema buildSchemaObject(File jsonSchemaOnDisk) throws IOException {
final ObjectMapper jsonMapper = new ObjectMapper();
final SchemaValidatorsConfig config = new SchemaValidatorsConfig();
final JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7);
return factory.getSchema(jsonMapper.readTree(jsonSchemaOnDisk), config);
}

private void maybeLogAndCollectError(Set<ValidationMessage> messages, Map<File, Set<String>> errors, File file) {
final String fileType = getFileType();
for (ValidationMessage message : messages) {
getLogger().error("[validate JSON][ERROR][{}][{}]", file.getName(), message.toString());
getLogger().error("[validate {}][ERROR][{}][{}]", fileType, file.getName(), message.toString());
errors.computeIfAbsent(file, k -> new LinkedHashSet<>())
.add(String.format("%s: %s", file.getAbsolutePath(), message.toString()));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* 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.precommit;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;

/**
* Incremental task to validate a set of YAML files against against a schema.
*/
public class ValidateYamlAgainstSchemaTask extends ValidateJsonAgainstSchemaTask {
@Override
protected String getFileType() {
return "YAML";
}

protected ObjectMapper getMapper() {
return new ObjectMapper(new YAMLFactory());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* 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 groovy.text.SimpleTemplateEngine;

import com.google.common.annotations.VisibleForTesting;

import org.elasticsearch.gradle.Version;
import org.elasticsearch.gradle.VersionProperties;

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.Objects;
import java.util.TreeMap;
import java.util.stream.Collectors;

/**
* Generates the page that lists the breaking changes and deprecations for a minor version release.
*/
public class BreakingChangesGenerator {

static void update(File templateFile, File outputFile, List<ChangelogEntry> entries) throws IOException {
try (FileWriter output = new FileWriter(outputFile)) {
generateFile(Files.readString(templateFile.toPath()), output, entries);
}
}

@VisibleForTesting
private static void generateFile(String template, FileWriter outputWriter, List<ChangelogEntry> entries) throws IOException {
final Version version = VersionProperties.getElasticsearchVersion();

final Map<Boolean, Map<String, List<ChangelogEntry.Breaking>>> breakingChangesByNotabilityByArea = entries.stream()
.map(ChangelogEntry::getBreaking)
.filter(Objects::nonNull)
.collect(
Collectors.groupingBy(
ChangelogEntry.Breaking::isNotable,
Collectors.groupingBy(ChangelogEntry.Breaking::getArea, TreeMap::new, Collectors.toList())
)
);

final Map<String, List<ChangelogEntry.Deprecation>> deprecationsByArea = entries.stream()
.map(ChangelogEntry::getDeprecation)
.filter(Objects::nonNull)
.collect(Collectors.groupingBy(ChangelogEntry.Deprecation::getArea, TreeMap::new, Collectors.toList()));

final Map<String, Object> bindings = new HashMap<>();
bindings.put("breakingChangesByNotabilityByArea", breakingChangesByNotabilityByArea);
bindings.put("deprecationsByArea", deprecationsByArea);
bindings.put("isElasticsearchSnapshot", VersionProperties.isElasticsearchSnapshot());
bindings.put("majorDotMinor", version.getMajor() + "." + version.getMinor());
bindings.put("majorMinor", String.valueOf(version.getMajor()) + version.getMinor());
bindings.put("nextMajor", (version.getMajor() + 1) + ".0");
bindings.put("version", version);

try {
pugnascotia marked this conversation as resolved.
Show resolved Hide resolved
final SimpleTemplateEngine engine = new SimpleTemplateEngine();
engine.createTemplate(template).make(bindings).writeTo(outputWriter);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
Loading