Additional functionality for the Git module.
Added functionality to reset a release train which actively resets to the latest state of the remote branch. Added functionality to push changes to the remote server and push tags individually. Added functionality to create commits for modules. Release operations now create two commits for the changelog update and the pom modifications. Release conclude does so for the preparation of the next development iteration. Added git.author infrastructure property to make sure we use a real user for the git commits.
This commit is contained in:
@@ -1 +1,3 @@
|
||||
io.workDir=~/temp/spring-data-shell
|
||||
io.workDir=~/temp/spring-data-shell
|
||||
|
||||
git.author=Oliver Gierke <ogierke@gopivotal.com>
|
||||
@@ -106,6 +106,8 @@ public class ReleaseCommands implements CommandMarker {
|
||||
|
||||
maven.updatePom(iteration, Phase.PREPARE);
|
||||
gradle.updateProject(iteration, Phase.PREPARE);
|
||||
|
||||
git.commit(iteration, "Prepare %s.", null);
|
||||
}
|
||||
|
||||
@CliCommand(value = "release conclude")
|
||||
@@ -113,11 +115,9 @@ public class ReleaseCommands implements CommandMarker {
|
||||
|
||||
git.tagRelease(iteration);
|
||||
|
||||
// - post release pom updates
|
||||
|
||||
maven.updatePom(iteration, Phase.CLEANUP);
|
||||
gradle.updateProject(iteration, Phase.CLEANUP);
|
||||
|
||||
// - push
|
||||
git.commit(iteration, "After release cleanups.", null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.git;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.data.release.jira.Ticket;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@EqualsAndHashCode
|
||||
@RequiredArgsConstructor
|
||||
public class Commit {
|
||||
|
||||
private final Ticket ticket;
|
||||
private final String summary;
|
||||
private final String details;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
builder.append(ticket.getId()).append(" - ").append(summary).append("\n");
|
||||
|
||||
if (details != null) {
|
||||
builder.append("\n");
|
||||
builder.append(details).append("\n");
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -63,12 +63,35 @@ public class GitCommands implements CommandMarker {
|
||||
* @throws Exception
|
||||
*/
|
||||
@CliCommand("git reset")
|
||||
public void reset(@CliOption(key = { "", "train" }, mandatory = true) String trainName) throws Exception {
|
||||
git.reset(ReleaseTrains.getTrainByName(trainName));
|
||||
public void reset(@CliOption(key = "", mandatory = true) TrainIteration iteration) throws Exception {
|
||||
git.reset(iteration);
|
||||
}
|
||||
|
||||
@CliCommand("git prepare")
|
||||
public void prepare(@CliOption(key = "", mandatory = true) TrainIteration iteration) throws Exception {
|
||||
git.prepare(iteration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes all changes of all modules of the given {@link TrainIteration} to the remote server. If {@code tags} is
|
||||
* given, only the tags are pushed.
|
||||
*
|
||||
* @param iteration
|
||||
* @param tags
|
||||
* @throws Exception
|
||||
*/
|
||||
@CliCommand("git push")
|
||||
public void push(//
|
||||
@CliOption(key = "", mandatory = true) TrainIteration iteration, //
|
||||
@CliOption(key = "tags", specifiedDefaultValue = "true", unspecifiedDefaultValue = "false") String tags)
|
||||
throws Exception {
|
||||
|
||||
boolean pushTags = Boolean.parseBoolean(tags);
|
||||
|
||||
if (pushTags) {
|
||||
git.pushTags(iteration.getTrain());
|
||||
} else {
|
||||
git.push(iteration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.concurrent.Future;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.data.release.io.CommandResult;
|
||||
import org.springframework.data.release.io.OsCommandOperations;
|
||||
import org.springframework.data.release.io.Workspace;
|
||||
@@ -52,10 +53,11 @@ import org.springframework.util.StringUtils;
|
||||
public class GitOperations {
|
||||
|
||||
private final GitServer server = new GitServer();
|
||||
private final OsCommandOperations osCommandOperations;
|
||||
private final OsCommandOperations os;
|
||||
private final Workspace workspace;
|
||||
private final Logger logger;
|
||||
private final PluginRegistry<IssueTracker, Project> issueTracker;
|
||||
private final Environment environment;
|
||||
|
||||
public GitProject getGitProject(Project project) {
|
||||
return new GitProject(project, server);
|
||||
@@ -67,12 +69,15 @@ public class GitOperations {
|
||||
* @param train must not be {@literal null}.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void reset(Train train) throws Exception {
|
||||
public void reset(TrainIteration train) throws Exception {
|
||||
|
||||
Assert.notNull(train, "Train must not be null!");
|
||||
|
||||
for (Module module : train) {
|
||||
osCommandOperations.executeCommand("git reset --hard", module.getProject()).get();
|
||||
for (ModuleIteration module : train) {
|
||||
|
||||
Branch branch = Branch.from(module);
|
||||
|
||||
os.executeCommand(String.format("git reset --hard origin/%s", branch), module.getProject()).get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +104,7 @@ public class GitOperations {
|
||||
artifactVersion, project));
|
||||
}
|
||||
|
||||
osCommandOperations.executeCommand(String.format("git checkout %s", tag), project).get();
|
||||
os.executeCommand(String.format("git checkout %s", tag), project).get();
|
||||
}
|
||||
|
||||
logger.log(iteration, "Successfully checked out projects.");
|
||||
@@ -114,7 +119,7 @@ public class GitOperations {
|
||||
update(module.getProject()).get();
|
||||
|
||||
String checkoutCommand = String.format("git checkout %s && git pull origin %s", branch, branch);
|
||||
osCommandOperations.executeCommand(checkoutCommand, module.getProject()).get();
|
||||
os.executeCommand(checkoutCommand, module.getProject()).get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,6 +136,22 @@ public class GitOperations {
|
||||
}
|
||||
}
|
||||
|
||||
public void push(TrainIteration iteration) throws Exception {
|
||||
|
||||
for (ModuleIteration module : iteration) {
|
||||
|
||||
Branch branch = Branch.from(module);
|
||||
os.executeCommand(String.format("git push origin %s", branch), module.getProject()).get();
|
||||
}
|
||||
}
|
||||
|
||||
public void pushTags(Train train) throws Exception {
|
||||
|
||||
for (Module module : train) {
|
||||
os.executeCommand("git push --tags", module.getProject()).get();
|
||||
}
|
||||
}
|
||||
|
||||
public Future<CommandResult> update(Project project) throws Exception {
|
||||
|
||||
GitProject gitProject = new GitProject(project, server);
|
||||
@@ -140,8 +161,8 @@ public class GitOperations {
|
||||
|
||||
logger.log(project, "Found existing repository %s. Obtaining latest changes…", repositoryName);
|
||||
|
||||
return osCommandOperations.executeCommand(
|
||||
"git checkout master && git reset --hard && git fetch --tags && git pull origin master", project);
|
||||
return os.executeCommand("git checkout master && git reset --hard && git fetch --tags && git pull origin master",
|
||||
project);
|
||||
|
||||
} else {
|
||||
|
||||
@@ -150,13 +171,13 @@ public class GitOperations {
|
||||
File projectDirectory = workspace.getProjectDirectory(project);
|
||||
String command = String.format("git clone %s %s", gitProject.getProjectUri(), projectDirectory.getName());
|
||||
|
||||
return osCommandOperations.executeCommand(command);
|
||||
return os.executeCommand(command);
|
||||
}
|
||||
}
|
||||
|
||||
public Tags getTags(Project project) throws Exception {
|
||||
|
||||
String result = osCommandOperations.executeForResult("git tag -l", project);
|
||||
String result = os.executeForResult("git tag -l", project);
|
||||
List<Tag> tags = new ArrayList<>();
|
||||
|
||||
for (String line : result.split("\n")) {
|
||||
@@ -177,15 +198,74 @@ public class GitOperations {
|
||||
Project project = module.getProject();
|
||||
|
||||
String checkoutCommand = String.format("git checkout %s", branch);
|
||||
osCommandOperations.executeCommand(checkoutCommand, project).get();
|
||||
os.executeCommand(checkoutCommand, project).get();
|
||||
|
||||
String updateCommand = String.format("git pull origin %s", branch);
|
||||
osCommandOperations.executeCommand(updateCommand, project).get();
|
||||
os.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();
|
||||
os.executeCommand(tagCommand, project).get();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits all changes currently made to all modules of the given {@link TrainIteration}. The summary can contain a
|
||||
* single {@code %s} placeholder which the version of the current module will get replace into.
|
||||
*
|
||||
* @param iteration must not be {@literal null}.
|
||||
* @param summary must not be {@literal null} or empty.
|
||||
* @param details can be {@literal null} or empty.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void commit(TrainIteration iteration, String summary, String details) throws Exception {
|
||||
|
||||
Assert.notNull(iteration, "Train iteration must not be null!");
|
||||
Assert.hasText(summary, "Summary must not be null or empty!");
|
||||
|
||||
for (ModuleIteration module : iteration) {
|
||||
|
||||
if (summary.contains("%s")) {
|
||||
summary = String.format(summary, module.getVersionString());
|
||||
}
|
||||
|
||||
commit(module, summary, details);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits the given files for the given {@link ModuleIteration} using the given summary and details for the commit
|
||||
* message. If no files are given, all pending changes are commited.
|
||||
*
|
||||
* @param module must not be {@literal null}.
|
||||
* @param summary must not be {@literal null} or empty.
|
||||
* @param details can be {@literal null} or empty.
|
||||
* @param files can be empty.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void commit(ModuleIteration module, String summary, String details, File... files) throws Exception {
|
||||
|
||||
Assert.notNull(module, "Module iteration must not be null!");
|
||||
Assert.hasText(summary, "Summary must not be null or empty!");
|
||||
|
||||
Project project = module.getProject();
|
||||
IssueTracker tracker = issueTracker.getPluginFor(project);
|
||||
Ticket ticket = tracker.getReleaseTicketFor(module);
|
||||
|
||||
Commit commit = new Commit(ticket, summary, details);
|
||||
String author = environment.getProperty("git.author");
|
||||
String commitCommand = String.format("git commit -m \"%s\" --author \"%s\"", commit, author);
|
||||
|
||||
if (files.length != 0) {
|
||||
|
||||
for (File file : files) {
|
||||
os.executeCommand(String.format("git add %s", file.getAbsolutePath()), project).get();
|
||||
}
|
||||
|
||||
os.executeCommand(commitCommand, project).get();
|
||||
} else {
|
||||
os.executeCommand(commitCommand.concat(" -a"), project).get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,7 +273,7 @@ public class GitOperations {
|
||||
|
||||
Project project = module.getProject();
|
||||
|
||||
String result = osCommandOperations.executeForResult("git log --pretty=format:'%h %s'", project);
|
||||
String result = os.executeForResult("git log --pretty=format:'%h %s'", project);
|
||||
Ticket releaseTicket = issueTracker.getPluginFor(project).getReleaseTicketFor(module);
|
||||
String trigger = String.format("%s - Release", releaseTicket.getId());
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.release.misc;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
@@ -22,6 +23,7 @@ import java.util.Set;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.release.git.GitOperations;
|
||||
import org.springframework.data.release.io.Workspace;
|
||||
import org.springframework.data.release.io.Workspace.LineCallback;
|
||||
import org.springframework.data.release.jira.Changelog;
|
||||
@@ -56,6 +58,7 @@ public class ReleaseOperations {
|
||||
|
||||
private final PluginRegistry<IssueTracker, Project> trackers;
|
||||
private final Workspace workspace;
|
||||
private final GitOperations git;
|
||||
private final Logger logger;
|
||||
|
||||
/**
|
||||
@@ -94,6 +97,10 @@ public class ReleaseOperations {
|
||||
});
|
||||
|
||||
if (processed) {
|
||||
|
||||
File file = workspace.getFile(location, module.getProject());
|
||||
git.commit(module, "Updated changelog.", null, file);
|
||||
|
||||
logger.log(module.getProject(), "Updated changelog %s.", location);
|
||||
}
|
||||
}
|
||||
@@ -104,20 +111,23 @@ public class ReleaseOperations {
|
||||
|
||||
for (final ModuleIteration module : iteration) {
|
||||
|
||||
workspace.processFile("src/main/resources/notice.txt", module.getProject(), new LineCallback() {
|
||||
boolean processed = workspace.processFile("src/main/resources/notice.txt", module.getProject(),
|
||||
new LineCallback() {
|
||||
|
||||
@Override
|
||||
public String doWith(String line, long number) {
|
||||
@Override
|
||||
public String doWith(String line, long number) {
|
||||
|
||||
if (number != 0) {
|
||||
return line;
|
||||
}
|
||||
if (number != 0) {
|
||||
return line;
|
||||
}
|
||||
|
||||
return module.toString();
|
||||
}
|
||||
});
|
||||
return module.toString();
|
||||
}
|
||||
});
|
||||
|
||||
logger.log(module, "Updated notice.txt.");
|
||||
if (processed) {
|
||||
logger.log(module, "Updated notice.txt.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user