@@ -82,8 +82,18 @@ Workflow:
|
||||
|
||||
* Check for dependency upgrades `$ dependency check $trainIteration`
|
||||
|
||||
Reports upgradable dependencies for Build and Modules and creates `dependency-upgrade-build.properties` file.
|
||||
Edit `dependency-upgrade-build.properties` to specify the dependency version to upgrade. Removing a line will omit that dependency upgrade.
|
||||
Reports upgradable dependencies for Build and Modules and
|
||||
creates `dependency-upgrade-build.properties` file.
|
||||
Edit `dependency-upgrade-build.properties` to specify the dependency version to upgrade.
|
||||
Removing a line will omit that dependency upgrade.
|
||||
|
||||
* Apply dependency upgrade with `$ dependency upgrade $trainIteration`. Applies dependency upgrades currently only to Spring Data Build.
|
||||
* Report store-specific dependencies to Spring Boot's current upgrade ticket ([sample](https://github.com/spring-projects/spring-boot/issues/24036)) `$ dependency report $trainIteration`
|
||||
* Apply dependency upgrade with `$ dependency upgrade $trainIteration`. Applies dependency
|
||||
upgrades currently only to Spring Data Build.
|
||||
* Report store-specific dependencies to Spring Boot's current upgrade
|
||||
ticket ([sample](https://github.com/spring-projects/spring-boot/issues/24036)) `$ dependency report $trainIteration`
|
||||
|
||||
#### CI Properties Distribution
|
||||
|
||||
To distribute `ci/pipeline.properties` across all modules use:
|
||||
|
||||
`$ infra distribute ci-properties $trainIteration`
|
||||
|
||||
@@ -15,8 +15,10 @@
|
||||
*/
|
||||
package org.springframework.data.release.dependency;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
@@ -42,7 +44,6 @@ import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.data.release.CliComponent;
|
||||
import org.springframework.data.release.build.Pom;
|
||||
import org.springframework.data.release.git.GitOperations;
|
||||
import org.springframework.data.release.io.Workspace;
|
||||
@@ -59,6 +60,7 @@ import org.springframework.data.release.utils.Logger;
|
||||
import org.springframework.data.util.Streamable;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.plugin.core.PluginRegistry;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.client.RestOperations;
|
||||
|
||||
@@ -72,8 +74,9 @@ import org.xmlbeam.io.XBStreamInput;
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@CliComponent
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
|
||||
public class DependencyOperations {
|
||||
|
||||
public static final Pattern REPO_MAVEN_ORG_DIR_LISTING = Pattern
|
||||
@@ -341,7 +344,7 @@ public class DependencyOperations {
|
||||
|
||||
action.accept(dependency, dependencyVersion);
|
||||
|
||||
gitOperations.commit(module, upgradeTicket, upgradeTicketSummary, Optional.empty());
|
||||
gitOperations.commit(module, upgradeTicket, upgradeTicketSummary, Optional.empty(), true);
|
||||
|
||||
ticketsToClose.add(upgradeTicket);
|
||||
});
|
||||
|
||||
@@ -57,6 +57,7 @@ public class InfrastructureCommands extends TimedCommand {
|
||||
DependencyOperations operations;
|
||||
ExecutorService executor;
|
||||
GitOperations git;
|
||||
InfrastructureOperations infra;
|
||||
Logger logger;
|
||||
|
||||
@CliCommand(value = "infra maven check")
|
||||
@@ -120,4 +121,15 @@ public class InfrastructureCommands extends TimedCommand {
|
||||
return DependencyUpgradeProposals.fromProperties(iteration, properties);
|
||||
}
|
||||
|
||||
@CliCommand(value = "infra distribute ci-properties")
|
||||
public void distributeCiProperties(@CliOption(key = "", mandatory = true) TrainIteration iteration)
|
||||
throws IOException, InterruptedException {
|
||||
|
||||
logger.log(iteration, "Distributing CI properties for Spring Data…");
|
||||
|
||||
git.checkout(iteration.getTrain(), true);
|
||||
|
||||
infra.distributeCiProperties(iteration);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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.dependency;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import org.springframework.data.release.git.Branch;
|
||||
import org.springframework.data.release.git.GitOperations;
|
||||
import org.springframework.data.release.io.Workspace;
|
||||
import org.springframework.data.release.model.Module;
|
||||
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.ExecutionUtils;
|
||||
import org.springframework.data.util.Streamable;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
|
||||
public class InfrastructureOperations {
|
||||
|
||||
public static final String CI_PROPERTIES = "ci/pipeline.properties";
|
||||
|
||||
Workspace workspace;
|
||||
GitOperations git;
|
||||
ExecutorService executor;
|
||||
|
||||
/**
|
||||
* Distribute {@link #CI_PROPERTIES} from {@link Projects#BUILD} to all modules within {@link TrainIteration}.
|
||||
*
|
||||
* @param iteration
|
||||
*/
|
||||
void distributeCiProperties(TrainIteration iteration) {
|
||||
|
||||
File master = workspace.getFile(CI_PROPERTIES, Projects.BUILD);
|
||||
|
||||
if (!master.exists()) {
|
||||
throw new IllegalStateException(String.format("CI Properties file %s does not exist", master));
|
||||
}
|
||||
|
||||
ExecutionUtils.run(executor, iteration, module -> {
|
||||
|
||||
Project project = module.getProject();
|
||||
Branch branch = Branch.from(module);
|
||||
|
||||
git.update(project);
|
||||
git.checkout(project, branch);
|
||||
});
|
||||
|
||||
verifyExistingPropertyFiles(iteration.getTrain(), master);
|
||||
|
||||
ExecutionUtils.run(executor, Streamable.of(iteration.getModulesExcept(Projects.BUILD)), module -> {
|
||||
|
||||
File target = workspace.getFile(CI_PROPERTIES, module.getProject());
|
||||
target.delete();
|
||||
|
||||
FileUtils.copyFile(master, target);
|
||||
|
||||
git.add(module.getProject(), CI_PROPERTIES);
|
||||
git.commit(module, "Update CI properties.", Optional.empty(), false);
|
||||
// git.push(iteration);
|
||||
});
|
||||
}
|
||||
|
||||
private void verifyExistingPropertyFiles(Train train, File master) {
|
||||
|
||||
for (Module module : train) {
|
||||
File target = workspace.getFile(CI_PROPERTIES, module.getProject());
|
||||
|
||||
if (!target.exists()) {
|
||||
throw new IllegalStateException(String.format("CI Properties file %s does not exist", master));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import org.eclipse.jgit.api.AddCommand;
|
||||
import org.eclipse.jgit.api.CheckoutCommand;
|
||||
import org.eclipse.jgit.api.CherryPickResult;
|
||||
import org.eclipse.jgit.api.CherryPickResult.CherryPickStatus;
|
||||
@@ -37,6 +38,7 @@ import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.LogCommand;
|
||||
import org.eclipse.jgit.api.ResetCommand.ResetType;
|
||||
import org.eclipse.jgit.api.errors.EmptyCommitException;
|
||||
import org.eclipse.jgit.api.errors.RefNotFoundException;
|
||||
import org.eclipse.jgit.errors.UnsupportedCredentialItem;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
@@ -633,7 +635,7 @@ public class GitOperations {
|
||||
() -> String.format("No issue tracker found for project %s!", project));
|
||||
Ticket ticket = tracker.getReleaseTicketFor(module);
|
||||
|
||||
commit(module, ticket, summary, details);
|
||||
commit(module, ticket, summary, details, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -644,7 +646,28 @@ public class GitOperations {
|
||||
* @param summary must not be {@literal null} or empty.
|
||||
* @param details can be {@literal null} or empty.
|
||||
*/
|
||||
public void commit(ModuleIteration module, Ticket ticket, String summary, Optional<String> details) {
|
||||
public void commit(ModuleIteration module, String summary, Optional<String> details, boolean all) {
|
||||
|
||||
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.getRequiredPluginFor(project,
|
||||
() -> String.format("No issue tracker found for project %s!", project));
|
||||
Ticket ticket = tracker.getReleaseTicketFor(module);
|
||||
|
||||
commit(module, ticket, summary, details, all);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 committed.
|
||||
*
|
||||
* @param module must not be {@literal null}.
|
||||
* @param summary must not be {@literal null} or empty.
|
||||
* @param details can be {@literal null} or empty.
|
||||
*/
|
||||
public void commit(ModuleIteration module, Ticket ticket, String summary, Optional<String> details, boolean all) {
|
||||
|
||||
Assert.notNull(module, "Module iteration must not be null!");
|
||||
Assert.hasText(summary, "Summary must not be null or empty!");
|
||||
@@ -654,6 +677,7 @@ public class GitOperations {
|
||||
Commit commit = new Commit(ticket, summary, details);
|
||||
String author = gitProperties.getAuthor();
|
||||
String email = gitProperties.getEmail();
|
||||
boolean allowEmpty = all;
|
||||
|
||||
logger.log(module, "git commit -m \"%s\" %s --author=\"%s <%s>\"", commit.getSummary(),
|
||||
gpg.isGpgAvailable() ? "-S" + gpg.getKeyname() : "", author, email);
|
||||
@@ -664,7 +688,8 @@ public class GitOperations {
|
||||
.setMessage(commit.toString())//
|
||||
.setAuthor(author, email)//
|
||||
.setCommitter(author, email)//
|
||||
.setAll(true);
|
||||
.setAllowEmpty(allowEmpty) //
|
||||
.setAll(all);
|
||||
|
||||
if (gpg.isGpgAvailable()) {
|
||||
commitCommand.setSign(true).setSigningKey(gpg.getKeyname())
|
||||
@@ -673,6 +698,31 @@ public class GitOperations {
|
||||
commitCommand.setSign(false);
|
||||
}
|
||||
|
||||
try {
|
||||
commitCommand.call();
|
||||
} catch (EmptyCommitException e) {
|
||||
// allowed if not all
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the {@code filepattern} to the staging area.
|
||||
*
|
||||
* @param project must not be {@literal null}.
|
||||
* @param filepattern must not be {@literal null} or empty.
|
||||
*/
|
||||
public void add(Project project, String filepattern) {
|
||||
|
||||
Assert.notNull(project, "Project must not be null!");
|
||||
|
||||
logger.log(project, "git add \"filepattern\"");
|
||||
|
||||
doWithGit(project, git -> {
|
||||
|
||||
AddCommand commitCommand = git.add()//
|
||||
.addFilepattern(filepattern);
|
||||
|
||||
commitCommand.call();
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user