More release steps automated.
- Dockbook references to Spring Data Commons files get updated. - Updating of notice.txt. - Gradle projects get Spring Data Commons version and repositories updated. - Added release commit detection and tagging for cleanup. Upgraded to Spring Boot 1.0.2.RELEASE.
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.0.0.RC4</version>
|
||||
<version>1.0.2.RELEASE</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -19,8 +19,10 @@ import static org.springframework.data.release.model.Projects.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.release.docs.DocumentationOperations;
|
||||
import org.springframework.data.release.git.GitOperations;
|
||||
import org.springframework.data.release.git.Tags;
|
||||
import org.springframework.data.release.gradle.GradleOperations;
|
||||
import org.springframework.data.release.maven.MavenOperations;
|
||||
import org.springframework.data.release.maven.Pom;
|
||||
import org.springframework.data.release.misc.ReleaseOperations;
|
||||
@@ -43,8 +45,10 @@ import org.springframework.stereotype.Component;
|
||||
public class ReleaseCommands implements CommandMarker {
|
||||
|
||||
private final MavenOperations maven;
|
||||
private final GradleOperations gradle;
|
||||
private final GitOperations git;
|
||||
private final ReleaseOperations misc;
|
||||
private final DocumentationOperations docs;
|
||||
|
||||
@CliCommand("release predict")
|
||||
public String predictTrainAndIteration() throws Exception {
|
||||
@@ -95,18 +99,24 @@ public class ReleaseCommands implements CommandMarker {
|
||||
public void prepare(@CliOption(key = "", mandatory = true) TrainIteration iteration) throws Exception {
|
||||
|
||||
git.prepare(iteration);
|
||||
|
||||
misc.prepareChangelogs(iteration);
|
||||
misc.updateResources(iteration);
|
||||
docs.updateDockbookIncludes(iteration);
|
||||
|
||||
maven.updatePom(iteration, Phase.PREPARE);
|
||||
gradle.updateProject(iteration, Phase.PREPARE);
|
||||
}
|
||||
|
||||
@CliCommand(value = "release conclude")
|
||||
public void conclude(@CliOption(key = "", mandatory = true) TrainIteration iteration) throws Exception {
|
||||
|
||||
// - pull updates
|
||||
// - tag release
|
||||
git.tagRelease(iteration);
|
||||
|
||||
// - post release pom updates
|
||||
|
||||
maven.updatePom(iteration, Phase.CLEANUP);
|
||||
gradle.updateProject(iteration, Phase.CLEANUP);
|
||||
|
||||
// - push
|
||||
}
|
||||
|
||||
@@ -65,11 +65,6 @@ public class TrainIterationConverter implements Converter<TrainIteration> {
|
||||
|
||||
for (Train train : ReleaseTrains.TRAINS) {
|
||||
|
||||
// if (!StringUtils.hasText(existingData) &&
|
||||
// !train.getName().toLowerCase().startsWith(existingData.toLowerCase())) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
for (Iteration iteration : train.getIterations()) {
|
||||
completions.add(new Completion(new TrainIteration(train, iteration).toString()));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.release.docs;
|
||||
|
||||
import static org.springframework.data.release.model.Projects.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.release.git.GitOperations;
|
||||
import org.springframework.data.release.git.GitProject;
|
||||
import org.springframework.data.release.git.Tag;
|
||||
import org.springframework.data.release.git.Tags;
|
||||
import org.springframework.data.release.io.Workspace;
|
||||
import org.springframework.data.release.io.Workspace.LineCallback;
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class DocumentationOperations {
|
||||
|
||||
private static final String INDEX_LOCATION = "/src/docbkx/index.xml";
|
||||
|
||||
private final Workspace workspace;
|
||||
private final GitOperations git;
|
||||
|
||||
public void updateDockbookIncludes(TrainIteration iteration) throws Exception {
|
||||
|
||||
Tags tags = git.getTags(COMMONS);
|
||||
|
||||
ModuleIteration commons = iteration.getModule(COMMONS);
|
||||
ModuleIteration previousIteration = iteration.getPreviousIteration(commons);
|
||||
|
||||
final GitProject gitProject = git.getGitProject(COMMONS);
|
||||
final Tag previousTag = tags.createTag(previousIteration);
|
||||
final Tag newTag = tags.createTag(commons);
|
||||
|
||||
for (ModuleIteration module : iteration) {
|
||||
|
||||
Project project = module.getProject();
|
||||
|
||||
if (!project.dependsOn(COMMONS)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
workspace.processFile(INDEX_LOCATION, project, new LineCallback() {
|
||||
|
||||
@Override
|
||||
public String doWith(String line, long number) {
|
||||
|
||||
boolean isInclude = line.contains("xi:include");
|
||||
boolean containsGitRepo = line.contains(gitProject.getRepositoryName());
|
||||
|
||||
return isInclude && containsGitRepo ? line.replace(previousTag.toString(), newTag.toString()) : line;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.ReleaseTrains;
|
||||
import org.springframework.data.release.model.Train;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
import org.springframework.shell.core.CommandMarker;
|
||||
import org.springframework.shell.core.annotation.CliCommand;
|
||||
@@ -55,9 +56,14 @@ public class GitCommands implements CommandMarker {
|
||||
return StringUtils.collectionToDelimitedString(git.getTags(project).asList(), "\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all projects contained in the given {@link Train}.
|
||||
*
|
||||
* @param trainName
|
||||
* @throws Exception
|
||||
*/
|
||||
@CliCommand("git reset")
|
||||
public void reset(@CliOption(key = { "", "train" }, mandatory = true) String trainName, @CliOption(key = "iteration",
|
||||
mandatory = true) String iterationName) throws Exception {
|
||||
public void reset(@CliOption(key = { "", "train" }, mandatory = true) String trainName) throws Exception {
|
||||
git.reset(ReleaseTrains.getTrainByName(trainName));
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.release.io.CommandResult;
|
||||
import org.springframework.data.release.io.OsCommandOperations;
|
||||
import org.springframework.data.release.io.Workspace;
|
||||
import org.springframework.data.release.jira.IssueTracker;
|
||||
import org.springframework.data.release.jira.Ticket;
|
||||
import org.springframework.data.release.model.ArtifactVersion;
|
||||
import org.springframework.data.release.model.Iteration;
|
||||
import org.springframework.data.release.model.Module;
|
||||
@@ -35,6 +37,7 @@ import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.Train;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
import org.springframework.data.release.utils.Logger;
|
||||
import org.springframework.plugin.core.PluginRegistry;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -52,6 +55,7 @@ public class GitOperations {
|
||||
private final OsCommandOperations osCommandOperations;
|
||||
private final Workspace workspace;
|
||||
private final Logger logger;
|
||||
private final PluginRegistry<IssueTracker, Project> issueTracker;
|
||||
|
||||
public GitProject getGitProject(Project project) {
|
||||
return new GitProject(project, server);
|
||||
@@ -168,6 +172,49 @@ public class GitOperations {
|
||||
return new Tags(tags);
|
||||
}
|
||||
|
||||
public void tagRelease(TrainIteration iteration) throws Exception {
|
||||
|
||||
for (ModuleIteration module : iteration) {
|
||||
|
||||
Branch branch = Branch.from(module);
|
||||
Project project = module.getProject();
|
||||
|
||||
String checkoutCommand = String.format("git checkout %s", branch);
|
||||
osCommandOperations.executeCommand(checkoutCommand, project).get();
|
||||
|
||||
String updateCommand = String.format("git pull origin %s", branch);
|
||||
osCommandOperations.executeCommand(updateCommand, project).get();
|
||||
|
||||
String hash = getReleaseHash(module);
|
||||
Tag tag = getTags(project).createTag(module);
|
||||
String tagCommand = String.format("git tag %s %s", tag, hash);
|
||||
osCommandOperations.executeCommand(tagCommand, project).get();
|
||||
}
|
||||
}
|
||||
|
||||
private String getReleaseHash(ModuleIteration module) throws Exception {
|
||||
|
||||
Project project = module.getProject();
|
||||
|
||||
String result = osCommandOperations.executeForResult("git log --pretty=format:'%h %s'", project);
|
||||
Ticket releaseTicket = issueTracker.getPluginFor(project).getReleaseTicketFor(module);
|
||||
String trigger = String.format("%s - Release", releaseTicket.getId());
|
||||
|
||||
logger.log(project, "Looking up release commit (ticket id %s)", releaseTicket.getId());
|
||||
|
||||
for (String line : result.split("\n")) {
|
||||
|
||||
int summaryStart = line.indexOf(" ");
|
||||
|
||||
if (line.substring(summaryStart + 1).startsWith(trigger)) {
|
||||
return line.substring(0, summaryStart);
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalStateException(String.format("Did not find a release commit for project %s (ticket id %s)",
|
||||
project, releaseTicket.getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Tag} that represents the {@link ArtifactVersion} of the given {@link Project}.
|
||||
*
|
||||
|
||||
@@ -45,6 +45,16 @@ public class Tag implements Comparable<Tag> {
|
||||
return ArtifactVersion.parse(getVersionSource());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Tag} for the given {@link ArtifactVersion} based on the format of the current one.
|
||||
*
|
||||
* @param version
|
||||
* @return
|
||||
*/
|
||||
public Tag createNew(ArtifactVersion version) {
|
||||
return new Tag(name.startsWith("v") ? "v".concat(version.toString()) : version.toString());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
|
||||
@@ -22,6 +22,8 @@ import java.util.List;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import org.springframework.data.release.model.ArtifactVersion;
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -58,6 +60,10 @@ public class Tags implements Iterable<Tag> {
|
||||
return tags.get(0);
|
||||
}
|
||||
|
||||
public Tag createTag(ModuleIteration iteration) {
|
||||
return getLatest().createNew(ArtifactVersion.from(iteration));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all {@link Tag}s as {@link List}.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.release.gradle;
|
||||
|
||||
import static org.springframework.data.release.model.Projects.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.release.io.Workspace;
|
||||
import org.springframework.data.release.io.Workspace.LineCallback;
|
||||
import org.springframework.data.release.maven.Repository;
|
||||
import org.springframework.data.release.model.ArtifactVersion;
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.data.release.model.Phase;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
import org.springframework.data.release.utils.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Gradle specific operations.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class GradleOperations {
|
||||
|
||||
private static final String BUILD_GRADLE = "build.gradle";
|
||||
private static final String GRADLE_PROPERTIES = "gradle.properties";
|
||||
private static final String COMMONS_PROPERTY = "springDataCommonsVersion";
|
||||
|
||||
private final Workspace workspace;
|
||||
private final Logger logger;
|
||||
|
||||
/**
|
||||
* Updates all Gradle projects contained in the release.
|
||||
*
|
||||
* @param iteration
|
||||
* @param phase
|
||||
* @throws Exception
|
||||
*/
|
||||
public void updateProject(TrainIteration iteration, final Phase phase) throws Exception {
|
||||
|
||||
final Repository repository = new Repository(iteration.getIteration());
|
||||
final ArtifactVersion commonsVersion = iteration.getModuleVersion(COMMONS);
|
||||
|
||||
for (ModuleIteration module : iteration.getModulesExcept(BUILD)) {
|
||||
|
||||
final Project project = module.getProject();
|
||||
|
||||
if (!isGradleProject(project)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
workspace.processFile(GRADLE_PROPERTIES, project, new LineCallback() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.release.io.Workspace.LineCallback#doWith(java.lang.String, long)
|
||||
*/
|
||||
@Override
|
||||
public String doWith(String line, long number) {
|
||||
|
||||
if (!line.contains(COMMONS_PROPERTY)) {
|
||||
return line;
|
||||
}
|
||||
|
||||
ArtifactVersion version = phase.equals(Phase.PREPARE) ? commonsVersion : commonsVersion
|
||||
.getNextDevelopmentVersion();
|
||||
|
||||
logger.log(project, "Setting Spring Data Commons version in %s to %s.", GRADLE_PROPERTIES, version);
|
||||
return String.format("%s=%s", COMMONS_PROPERTY, version);
|
||||
}
|
||||
});
|
||||
|
||||
workspace.processFile(BUILD_GRADLE, project, new LineCallback() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.release.io.Workspace.LineCallback#doWith(java.lang.String, long)
|
||||
*/
|
||||
@Override
|
||||
public String doWith(String line, long number) {
|
||||
|
||||
String snapshotUrl = repository.getSnapshotUrl();
|
||||
String releaseUrl = repository.getUrl();
|
||||
String message = "Switching to Spring repository %s";
|
||||
|
||||
switch (phase) {
|
||||
case CLEANUP:
|
||||
logger.log(project, message, snapshotUrl);
|
||||
return line.contains(releaseUrl) ? line.replace(releaseUrl, snapshotUrl) : line;
|
||||
case PREPARE:
|
||||
default:
|
||||
logger.log(project, message, releaseUrl);
|
||||
return line.contains(snapshotUrl) ? line.replace(snapshotUrl, releaseUrl) : line;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given project is a Gradle project (checks for the presence of a build.gradle file).
|
||||
*
|
||||
* @param project
|
||||
* @return
|
||||
*/
|
||||
private boolean isGradleProject(Project project) {
|
||||
return workspace.getFile(BUILD_GRADLE, project).exists();
|
||||
}
|
||||
}
|
||||
@@ -17,8 +17,9 @@ package org.springframework.data.release.io;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Scanner;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
@@ -30,6 +31,8 @@ import org.springframework.data.release.model.Project;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
|
||||
/**
|
||||
* Abstraction of the workspace that is used to work with the {@link Project}'s repositories, execute builds, etc.
|
||||
*
|
||||
@@ -39,6 +42,8 @@ import org.springframework.util.Assert;
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class Workspace {
|
||||
|
||||
private static final Charset UTF_8 = Charset.forName("UTF-8");
|
||||
|
||||
public static final String WORK_DIR_PROPERTY = "io.workDir";
|
||||
|
||||
private final Environment environment;
|
||||
@@ -93,6 +98,40 @@ public class Workspace {
|
||||
return new File(getProjectDirectory(project), name);
|
||||
}
|
||||
|
||||
public boolean processFile(String filename, Project project, LineCallback callback) throws Exception {
|
||||
|
||||
File file = getFile(filename, project);
|
||||
|
||||
if (!file.exists()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
try (Scanner scanner = new Scanner(file)) {
|
||||
|
||||
long number = 0;
|
||||
|
||||
while (scanner.hasNextLine()) {
|
||||
|
||||
String result = callback.doWith(scanner.nextLine(), number++);
|
||||
|
||||
if (result != null) {
|
||||
builder.append(result).append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
writeContentToFile(filename, project, builder.toString());
|
||||
return true;
|
||||
}
|
||||
|
||||
private void writeContentToFile(String name, Project project, String content) throws IOException {
|
||||
|
||||
File file = getFile(name, project);
|
||||
Files.write(content, file, UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the working directory and creates the folders if necessary.
|
||||
*
|
||||
@@ -103,8 +142,12 @@ public class Workspace {
|
||||
|
||||
Path path = getWorkingDirectory().toPath();
|
||||
|
||||
if (!Files.exists(path)) {
|
||||
Files.createDirectories(path);
|
||||
if (!java.nio.file.Files.exists(path)) {
|
||||
java.nio.file.Files.createDirectories(path);
|
||||
}
|
||||
}
|
||||
|
||||
public interface LineCallback {
|
||||
String doWith(String line, long number);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,10 +31,12 @@ import org.springframework.data.release.model.ArtifactVersion;
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.data.release.model.Phase;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.Projects;
|
||||
import org.springframework.data.release.model.Train;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
import org.springframework.data.release.utils.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
import org.xmlbeam.ProjectionFactory;
|
||||
import org.xmlbeam.io.XBFileIO;
|
||||
|
||||
@@ -59,8 +61,25 @@ public class MavenOperations {
|
||||
return projectionFactory.io().file(file).read(Pom.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the POM files for all Maven projects contained in the iteration:
|
||||
* <ol>
|
||||
* <li>Updates the BOM POM.</li>
|
||||
* <li>Updates the dependency version to Spring Data Commons to the current release version for all projects depending
|
||||
* on it.</li>
|
||||
* <li>Switches to the Spring release Maven repository.</li>
|
||||
* </ol>
|
||||
* If {@link Phase} is {@link Phase#CLEANUP} the changes will be rolled back.
|
||||
*
|
||||
* @param iteration must not be {@literal null}.
|
||||
* @param phase must not be {@literal null}.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void updatePom(TrainIteration iteration, final Phase phase) throws Exception {
|
||||
|
||||
Assert.notNull(iteration, "Train iteration must not be null!");
|
||||
Assert.notNull(phase, "Phase must not be null!");
|
||||
|
||||
updateBomPom(iteration, phase);
|
||||
|
||||
final Repository repository = new Repository(iteration.getIteration());
|
||||
@@ -70,20 +89,31 @@ public class MavenOperations {
|
||||
for (ModuleIteration module : iteration.getModulesExcept(BUILD)) {
|
||||
|
||||
final Project project = module.getProject();
|
||||
File pomFile = workspace.getFile(POM_XML, project);
|
||||
|
||||
execute(pomFile, new PomCallback() {
|
||||
if (!isMavenProject(project)) {
|
||||
logger.log(module, "No pom.xml file found, skipping project.");
|
||||
continue;
|
||||
}
|
||||
|
||||
execute(workspace.getFile(POM_XML, project), new PomCallback() {
|
||||
|
||||
@Override
|
||||
public Pom doWith(Pom pom) {
|
||||
|
||||
if (!project.equals(COMMONS)) {
|
||||
pom.setProperty(COMMONS_VERSION_PROPERTY,
|
||||
CLEANUP.equals(phase) ? commonsVersion.getNextDevelopmentVersion() : commonsVersion);
|
||||
if (project.dependsOn(Projects.COMMONS)) {
|
||||
|
||||
ArtifactVersion version = CLEANUP.equals(phase) ? commonsVersion.getNextDevelopmentVersion()
|
||||
: commonsVersion;
|
||||
logger.log(project, "Updating Spring Data Commons version dependecy to %s (setting property %s).", version,
|
||||
COMMONS_VERSION_PROPERTY);
|
||||
pom.setProperty(COMMONS_VERSION_PROPERTY, version);
|
||||
}
|
||||
|
||||
pom.setParentVersion(CLEANUP.equals(phase) ? buildVersion.getNextDevelopmentVersion() : buildVersion);
|
||||
updateRepository(pom, repository, phase);
|
||||
ArtifactVersion version = CLEANUP.equals(phase) ? buildVersion.getNextDevelopmentVersion() : buildVersion;
|
||||
logger.log(project, "Updating Spring Data Build Parent version to %s.", version);
|
||||
pom.setParentVersion(version);
|
||||
|
||||
updateRepository(project, pom, repository, phase);
|
||||
|
||||
return pom;
|
||||
}
|
||||
@@ -144,6 +174,8 @@ public class MavenOperations {
|
||||
|
||||
File bomPomFile = workspace.getFile("bom/pom.xml", BUILD);
|
||||
|
||||
logger.log(BUILD, "Updating BOM pom.xml…");
|
||||
|
||||
execute(bomPomFile, new PomCallback() {
|
||||
|
||||
@Override
|
||||
@@ -155,6 +187,8 @@ public class MavenOperations {
|
||||
ArtifactVersion version = artifact.getVersion();
|
||||
version = PREPARE.equals(phase) ? version : version.getNextDevelopmentVersion();
|
||||
|
||||
logger.log(BUILD, "%s", module);
|
||||
|
||||
pom.setDependencyVersion(artifact.getArtifactId(), version);
|
||||
}
|
||||
|
||||
@@ -163,12 +197,21 @@ public class MavenOperations {
|
||||
});
|
||||
}
|
||||
|
||||
private void updateRepository(Pom pom, Repository repository, Phase phase) {
|
||||
private void updateRepository(Project project, Pom pom, Repository repository, Phase phase) {
|
||||
|
||||
String message = "Switching to Spring repository %s (%s).";
|
||||
|
||||
if (PREPARE.equals(phase)) {
|
||||
|
||||
logger.log(project, message, repository.getId(), repository.getUrl());
|
||||
|
||||
pom.setRepositoryId(repository.getSnapshotId(), repository.getId());
|
||||
pom.setRepositoryUrl(repository.getId(), repository.getUrl());
|
||||
|
||||
} else {
|
||||
|
||||
logger.log(project, message, repository.getSnapshotId(), repository.getSnapshotUrl());
|
||||
|
||||
pom.setRepositoryId(repository.getId(), repository.getSnapshotId());
|
||||
pom.setRepositoryUrl(repository.getSnapshotId(), repository.getSnapshotUrl());
|
||||
}
|
||||
|
||||
@@ -15,14 +15,15 @@
|
||||
*/
|
||||
package org.springframework.data.release.misc;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Scanner;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.release.io.Workspace;
|
||||
import org.springframework.data.release.io.Workspace.LineCallback;
|
||||
import org.springframework.data.release.jira.Changelog;
|
||||
import org.springframework.data.release.jira.IssueTracker;
|
||||
import org.springframework.data.release.model.Iteration;
|
||||
@@ -30,12 +31,11 @@ import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.Train;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
import org.springframework.data.release.utils.Logger;
|
||||
import org.springframework.plugin.core.PluginRegistry;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@@ -43,8 +43,20 @@ import com.google.common.io.Files;
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class ReleaseOperations {
|
||||
|
||||
private static final Set<String> CHANGELOG_LOCATIONS;
|
||||
|
||||
static {
|
||||
|
||||
Set<String> locations = new HashSet<>();
|
||||
locations.add("src/main/resources/changelog.txt"); // for Maven projects
|
||||
locations.add("docs/src/info/changelog.txt"); // for Gradle projects
|
||||
|
||||
CHANGELOG_LOCATIONS = Collections.unmodifiableSet(locations);
|
||||
}
|
||||
|
||||
private final PluginRegistry<IssueTracker, Project> trackers;
|
||||
private final Workspace workspace;
|
||||
private final Logger logger;
|
||||
|
||||
/**
|
||||
* Creates {@link Changelog} instances for all modules of the given {@link Train} and {@link Iteration}.
|
||||
@@ -59,26 +71,53 @@ public class ReleaseOperations {
|
||||
|
||||
for (ModuleIteration module : iteration) {
|
||||
|
||||
Changelog changelog = trackers.getPluginFor(module.getProject()).getChangelogFor(module);
|
||||
File file = workspace.getFile("src/main/resources/changelog.txt", module.getProject());
|
||||
StringBuilder builder = new StringBuilder();
|
||||
final Changelog changelog = trackers.getPluginFor(module.getProject()).getChangelogFor(module);
|
||||
|
||||
try (Scanner scanner = new Scanner(file)) {
|
||||
for (String location : CHANGELOG_LOCATIONS) {
|
||||
|
||||
// Copy headline
|
||||
builder.append(scanner.nextLine()).append("\n");
|
||||
builder.append(scanner.nextLine()).append("\n");
|
||||
boolean processed = workspace.processFile(location, module.getProject(), new LineCallback() {
|
||||
|
||||
// Add new changelog
|
||||
builder.append(changelog.toString());
|
||||
@Override
|
||||
public String doWith(String line, long number) {
|
||||
|
||||
// Append existing
|
||||
while (scanner.hasNextLine()) {
|
||||
builder.append(scanner.nextLine()).append("\n");
|
||||
if (line.startsWith("=")) {
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(line).append("\n\n");
|
||||
builder.append(changelog.toString());
|
||||
|
||||
return builder.toString();
|
||||
} else {
|
||||
return line;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (processed) {
|
||||
logger.log(module.getProject(), "Updated changelog %s.", location);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Files.write(builder, file, Charset.forName("UTF-8"));
|
||||
public void updateResources(TrainIteration iteration) throws Exception {
|
||||
|
||||
for (final ModuleIteration module : iteration) {
|
||||
|
||||
workspace.processFile("src/main/resources/notice.txt", module.getProject(), new LineCallback() {
|
||||
|
||||
@Override
|
||||
public String doWith(String line, long number) {
|
||||
|
||||
if (number != 0) {
|
||||
return line;
|
||||
}
|
||||
|
||||
return module.toString();
|
||||
}
|
||||
});
|
||||
|
||||
logger.log(module, "Updated notice.txt.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,10 @@ public class Iteration {
|
||||
return name.startsWith("SR");
|
||||
}
|
||||
|
||||
public boolean isNext(Iteration iteration) {
|
||||
return next.equals(iteration);
|
||||
}
|
||||
|
||||
public int getBugfixValue() {
|
||||
return name.startsWith("SR") ? Integer.parseInt(name.substring(2)) : 0;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@@ -53,4 +55,16 @@ public class Project {
|
||||
public String getFullName() {
|
||||
return "Spring Data ".concat(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the current project depends on the given one.
|
||||
*
|
||||
* @param project must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public boolean dependsOn(Project project) {
|
||||
|
||||
Assert.notNull(project, "Project must not be null!");
|
||||
return dependencies.contains(project);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,6 +139,10 @@ public class Train implements Iterable<Module> {
|
||||
return ArtifactVersion.from(new ModuleIteration(module, iteration, this));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
@@ -157,7 +161,7 @@ public class Train implements Iterable<Module> {
|
||||
*/
|
||||
@EqualsAndHashCode
|
||||
@ToString
|
||||
private static class Iterations implements Iterable<Iteration> {
|
||||
public static class Iterations implements Iterable<Iteration> {
|
||||
|
||||
public static Iterations DEFAULT = new Iterations(M1, RC1, GA, SR1, SR2, SR3, SR4);
|
||||
|
||||
@@ -191,6 +195,17 @@ public class Train implements Iterable<Module> {
|
||||
return null;
|
||||
}
|
||||
|
||||
Iteration getPreviousIteration(Iteration iteration) {
|
||||
|
||||
for (Iteration candidate : iterations) {
|
||||
if (candidate.isNext(iteration)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(String.format("Could not find previous iteration for %s!", iteration));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Iterable#iterator()
|
||||
|
||||
@@ -53,6 +53,12 @@ public class TrainIteration implements Iterable<ModuleIteration> {
|
||||
return train.getModuleIterations(iteration, exclusions);
|
||||
}
|
||||
|
||||
public ModuleIteration getPreviousIteration(ModuleIteration module) {
|
||||
|
||||
Iteration previousIteration = train.getIterations().getPreviousIteration(iteration);
|
||||
return train.getModuleIteration(previousIteration, module.getProject().getName());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
|
||||
Reference in New Issue
Block a user