From 1ddf103be50706771a0bc12a7c7cd2074fdfe9bb Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Thu, 24 Nov 2016 15:39:14 +0100 Subject: [PATCH] #34 - More logging in GitOperations. Removed some unnecessary resets along the way. Failed cherry picks now get logged explicitly so that they can be resolved manually. --- .../data/release/git/GitCommands.java | 6 +- .../data/release/git/GitOperations.java | 100 +++++++++++++----- .../data/release/utils/ExecutionUtils.java | 4 + 3 files changed, 79 insertions(+), 31 deletions(-) diff --git a/release-tools/src/main/java/org/springframework/data/release/git/GitCommands.java b/release-tools/src/main/java/org/springframework/data/release/git/GitCommands.java index 9d98b2e..baae780 100644 --- a/release-tools/src/main/java/org/springframework/data/release/git/GitCommands.java +++ b/release-tools/src/main/java/org/springframework/data/release/git/GitCommands.java @@ -45,7 +45,7 @@ class GitCommands extends TimedCommand { private final @NonNull GitOperations git; - @CliCommand("git co train") + @CliCommand("git co-train") public void checkout(@CliOption(key = "", mandatory = true) Train train) throws Exception { git.checkout(train); } @@ -97,7 +97,7 @@ class GitCommands extends TimedCommand { public void push(// @CliOption(key = "", mandatory = true) TrainIteration iteration, // @CliOption(key = "tags", specifiedDefaultValue = "true", unspecifiedDefaultValue = "false") String tags) - throws Exception { + throws Exception { boolean pushTags = Boolean.parseBoolean(tags); @@ -135,7 +135,7 @@ class GitCommands extends TimedCommand { @SuppressWarnings("deprecation") public Table issuebranches(@CliOption(key = { "" }, mandatory = true) String projectName, @CliOption(key = "resolved", unspecifiedDefaultValue = "false", specifiedDefaultValue = "true") Boolean resolved) - throws Exception { + throws Exception { Project project = ReleaseTrains.getProjectByName(projectName); TicketBranches ticketBranches = git.listTicketBranches(project); diff --git a/release-tools/src/main/java/org/springframework/data/release/git/GitOperations.java b/release-tools/src/main/java/org/springframework/data/release/git/GitOperations.java index e914275..0e6b6ef 100644 --- a/release-tools/src/main/java/org/springframework/data/release/git/GitOperations.java +++ b/release-tools/src/main/java/org/springframework/data/release/git/GitOperations.java @@ -29,6 +29,8 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import org.eclipse.jgit.api.CheckoutCommand; +import org.eclipse.jgit.api.CherryPickResult; +import org.eclipse.jgit.api.CherryPickResult.CherryPickStatus; import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.ResetCommand.ResetType; @@ -166,8 +168,6 @@ public class GitOperations { public void prepare(TrainIteration iteration) { - reset(iteration); - ExecutionUtils.run(iteration, module -> { Project project = module.getProject(); @@ -176,6 +176,8 @@ public class GitOperations { update(project); checkout(project, branch); + logger.log(project, "Pulling latest updates for branch %s…", branch); + doWithGit(project, git -> { logger.log(project, "git pull origin %s", branch); @@ -183,6 +185,8 @@ public class GitOperations { .setRebase(true)// .call(); }); + + logger.log(project, "Pulling updates done!", branch); }); reset(iteration); @@ -240,6 +244,8 @@ public class GitOperations { Assert.notNull(project, "Project must not be null!"); + logger.log(project, "Updating project…"); + GitProject gitProject = new GitProject(project, server); String repositoryName = gitProject.getRepositoryName(); @@ -250,7 +256,6 @@ public class GitOperations { logger.log(project, "Found existing repository %s. Obtaining latest changes…", repositoryName); checkout(project, Branch.MASTER); - reset(project, Branch.MASTER); logger.log(project, "git fetch --tags"); git.fetch().setTagOpt(TagOpt.FETCH_TAGS).call(); @@ -259,12 +264,11 @@ public class GitOperations { git.pull().call(); } else { - - logger.log(project, "No repository found! Cloning from %s…", gitProject.getProjectUri()); - clone(project); } }); + + logger.log(project, "Project update done!"); } public VersionTags getTags(Project project) { @@ -416,6 +420,7 @@ public class GitOperations { git.commit()// .setMessage(commit.toString())// .setAuthor(author, email)// + .setCommitter(author, email)// .setAll(true)// .call(); }); @@ -434,6 +439,8 @@ public class GitOperations { Assert.notNull(project, "Project must not be null!"); Assert.notNull(branch, "Branch must not be null!"); + logger.log(project, "Checking out project…"); + doWithGit(project, git -> { Optional ref = Optional.ofNullable(git.getRepository().findRef(branch.toString())); @@ -466,6 +473,8 @@ public class GitOperations { .setRemoteBranchName(branch.toString())// .call(); }); + + logger.log(project, "Checkout done!"); } public void createMaintenanceBranches(TrainIteration iteration) { @@ -525,13 +534,16 @@ public class GitOperations { doWithGit(project, git -> { checkout(project, backportTargets.getSource()); - ObjectId objectId = getChangelogUpdate(module); + Optional objectId = getChangelogUpdate(module); + + objectId.ifPresent(it -> backportTargets.forEach(target -> cherryPickCommitToBranch(it, project, target))); + + if (!objectId.isPresent()) { + logger.log(project, "No changelog commit found, skipping backports!"); + } - backportTargets.forEach(target -> cherryPickCommitToBranch(objectId, project, target)); }); }); - - update(iteration.getTrain()); } private void cherryPickCommitToBranch(ObjectId id, Project project, Branch branch) { @@ -546,9 +558,16 @@ public class GitOperations { return; } - git.cherryPick().include(id).call(); - logger.log(project, "Successfully cherry-picked commit %s to branch %s.", id.getName(), branch); + logger.log(project, "git cp %s", id.getName()); + CherryPickResult result = git.cherryPick().include(id).call(); + if (result.getStatus().equals(CherryPickStatus.OK)) { + logger.log(project, "Successfully cherry-picked commit %s to branch %s.", id.getName(), branch); + } else { + logger.log(project, "Cherry pick failed. aborting…"); + logger.log(project, "git reset --hard"); + git.reset().setMode(ResetType.HARD).call(); + } }); } @@ -583,34 +602,47 @@ public class GitOperations { * @throws Exception */ private ObjectId getReleaseHash(ModuleIteration module) { - return findCommit(module, "Release"); + return findRequiredCommit(module, "Release"); } - private ObjectId getChangelogUpdate(ModuleIteration module) { + private Optional getChangelogUpdate(ModuleIteration module) { return findCommit(module, "Updated changelog"); } - private ObjectId findCommit(ModuleIteration module, String summary) { + private ObjectId findRequiredCommit(ModuleIteration module, String summary) { - Project project = module.getProject(); - Ticket releaseTicket = issueTracker.getPluginFor(project).getReleaseTicketFor(module); - String trigger = String.format("%s - %s", releaseTicket.getId(), summary); + String trigger = calculateTrigger(module, summary); - return doWithGit(module.getProject(), git -> { + return findCommit(module, summary).orElseThrow(() -> new IllegalStateException(String + .format("Did not find a commit with summary starting with '%s' for project %s", module.getProject(), trigger))); + } + + private Optional findCommit(ModuleIteration module, String summary) { + return findCommitWithTrigger(module.getProject(), calculateTrigger(module, summary)); + } + + private Optional findCommitWithTrigger(Project project, String trigger) { + + return doWithGit(project, git -> { for (RevCommit commit : git.log().setMaxCount(50).call()) { if (commit.getShortMessage().startsWith(trigger)) { - return commit.getId(); + return Optional.of(commit.getId()); } } - throw new IllegalStateException( - String.format("Did not find a commit with summary starting with '%s' for project %s", project, trigger)); - + return Optional.empty(); }); } + private String calculateTrigger(ModuleIteration module, String summary) { + + Project project = module.getProject(); + Ticket releaseTicket = issueTracker.getPluginFor(project).getReleaseTicketFor(module); + return String.format("%s - %s", releaseTicket.getId(), summary); + } + /** * Returns the {@link Tag} that represents the {@link ArtifactVersion} of the given {@link Project}. * @@ -632,14 +664,20 @@ public class GitOperations { private void clone(Project project) throws Exception { + GitProject gitProject = getGitProject(project); + + logger.log(project, "No repository found! Cloning from %s…", gitProject.getProjectUri()); + Git git = Git.cloneRepository()// - .setURI(getGitProject(project).getProjectUri())// + .setURI(gitProject.getProjectUri())// .setDirectory(workspace.getProjectDirectory(project))// .call(); git.checkout()// .setName(Branch.MASTER.toString())// .call(); + + logger.log(project, "Cloning done!", project); } private boolean branchExists(Project project, Branch branch) { @@ -657,9 +695,13 @@ public class GitOperations { logger.log(project, "git reset --hard origin/%s", branch); - try (Git git = new Git(getRepository(project))) { - git.reset().setMode(ResetType.HARD).setRef("origin/".concat(branch.toString())).call(); - } + doWithGit(project, git -> { + + git.reset()// + .setMode(ResetType.HARD)// + .setRef("origin/".concat(branch.toString()))// + .call(); + }); } private static String expandSummary(String summary, ModuleIteration module, TrainIteration iteration) { @@ -669,7 +711,9 @@ public class GitOperations { private T doWithGit(Project project, GitCallback callback) { try (Git git = new Git(getRepository(project))) { - return callback.doWithGit(git); + T result = callback.doWithGit(git); + Thread.sleep(100); + return result; } catch (Exception o_O) { throw new RuntimeException(o_O); } diff --git a/release-tools/src/main/java/org/springframework/data/release/utils/ExecutionUtils.java b/release-tools/src/main/java/org/springframework/data/release/utils/ExecutionUtils.java index 3f0598a..4356637 100644 --- a/release-tools/src/main/java/org/springframework/data/release/utils/ExecutionUtils.java +++ b/release-tools/src/main/java/org/springframework/data/release/utils/ExecutionUtils.java @@ -15,6 +15,8 @@ */ package org.springframework.data.release.utils; +import lombok.extern.slf4j.Slf4j; + import java.util.Collection; import java.util.concurrent.CompletableFuture; import java.util.function.Function; @@ -29,6 +31,7 @@ import org.springframework.util.Assert; * * @author Oliver Gierke */ +@Slf4j public class ExecutionUtils { /** @@ -49,6 +52,7 @@ public class ExecutionUtils { try { consumer.accept(it); } catch (Exception o_O) { + log.error(o_O.getMessage(), o_O); throw new RuntimeException(o_O); } })).collect(Collectors.toList()).forEach(future -> future.join());