@@ -29,6 +29,7 @@ import java.util.stream.Collectors;
|
||||
import org.assertj.core.util.VisibleForTesting;
|
||||
import org.springframework.data.release.deployment.DeploymentInformation;
|
||||
import org.springframework.data.release.deployment.StagingRepository;
|
||||
import org.springframework.data.release.git.BranchMapping;
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.data.release.model.Phase;
|
||||
import org.springframework.data.release.model.ProjectAware;
|
||||
@@ -76,6 +77,16 @@ public class BuildOperations {
|
||||
logger.log(iteration, "Update Project Descriptors done: %s", summary);
|
||||
}
|
||||
|
||||
public void updateBuildConfig(TrainIteration iteration, BranchMapping branches) throws Exception {
|
||||
|
||||
Assert.notNull(iteration, "Train iteration must not be null!");
|
||||
|
||||
BuildExecutor.Summary<ModuleIteration> summary = executor.doWithBuildSystemOrdered(iteration,
|
||||
(system, it) -> system.updateBuildConfig(it, branches));
|
||||
|
||||
logger.log(iteration, "Update Build config done: %s", summary);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the versions of the given {@link TrainIteration} depending on the given {@link Phase}.
|
||||
*
|
||||
@@ -414,4 +425,5 @@ public class BuildOperations {
|
||||
return function.apply(buildSystem.withJavaVersion(executor.detectJavaVersion(module.getSupportedProject())),
|
||||
module);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,11 +17,12 @@ package org.springframework.data.release.build;
|
||||
|
||||
import org.springframework.data.release.deployment.DeploymentInformation;
|
||||
import org.springframework.data.release.deployment.StagingRepository;
|
||||
import org.springframework.data.release.git.BranchMapping;
|
||||
import org.springframework.data.release.model.JavaVersion;
|
||||
import org.springframework.data.release.model.ModuleIteration;
|
||||
import org.springframework.data.release.model.Phase;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.data.release.model.ProjectAware;
|
||||
import org.springframework.data.release.model.SupportedProject;
|
||||
import org.springframework.data.release.model.Train;
|
||||
import org.springframework.data.release.model.TrainIteration;
|
||||
import org.springframework.plugin.core.Plugin;
|
||||
@@ -43,6 +44,14 @@ interface BuildSystem extends Plugin<SupportedProject> {
|
||||
*/
|
||||
<M extends ProjectAware> M updateProjectDescriptors(M iteration, UpdateInformation updateInformation);
|
||||
|
||||
/**
|
||||
* Updates the project build config for the given {@link ModuleIteration}.
|
||||
*
|
||||
* @param iteration must not be {@literal null}.
|
||||
* @param branches must not be {@literal null}.
|
||||
*/
|
||||
ModuleIteration updateBuildConfig(ModuleIteration iteration, BranchMapping branches);
|
||||
|
||||
/**
|
||||
* Prepares the project descriptor of the {@link ModuleIteration} for the given release {@link Phase}.
|
||||
*
|
||||
@@ -139,4 +148,5 @@ interface BuildSystem extends Plugin<SupportedProject> {
|
||||
* @return
|
||||
*/
|
||||
BuildSystem withJavaVersion(JavaVersion javaVersion);
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import static org.springframework.data.release.model.Projects.*;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
@@ -31,6 +32,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -51,6 +53,9 @@ import org.springframework.data.release.deployment.DeploymentProperties;
|
||||
import org.springframework.data.release.deployment.DeploymentProperties.Authentication;
|
||||
import org.springframework.data.release.deployment.DeploymentProperties.MavenCentral;
|
||||
import org.springframework.data.release.deployment.StagingRepository;
|
||||
import org.springframework.data.release.git.Branch;
|
||||
import org.springframework.data.release.git.BranchMapping;
|
||||
import org.springframework.data.release.git.GitProject;
|
||||
import org.springframework.data.release.io.Workspace;
|
||||
import org.springframework.data.release.model.*;
|
||||
import org.springframework.data.release.utils.Logger;
|
||||
@@ -126,6 +131,42 @@ class MavenBuildSystem implements BuildSystem {
|
||||
return module;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public ModuleIteration updateBuildConfig(ModuleIteration module, BranchMapping branches) {
|
||||
|
||||
File jenkinsfile = workspace.getFile("Jenkinsfile", module.getSupportedProject());
|
||||
if (!jenkinsfile.exists()) {
|
||||
logger.warn(module, "No Jenkinsfile found, skipping Jenkinsfile update.");
|
||||
}
|
||||
|
||||
byte[] bytes = Files.readAllBytes(jenkinsfile.toPath());
|
||||
String content = new String(bytes, StandardCharsets.UTF_8);
|
||||
|
||||
for (ModuleIteration participatingModule : module.getTrainIteration()) {
|
||||
|
||||
Branch source = branches.getSourceBranch(participatingModule.getProject());
|
||||
Branch target = branches.getTargetBranch(participatingModule.getProject());
|
||||
|
||||
if (source == null || target == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
GitProject project = GitProject.of(participatingModule.getSupportedProject());
|
||||
|
||||
String dependency = String.format("%s/%s", project.getRepositoryName(), source);
|
||||
String replacement = String.format("%s/%s", project.getRepositoryName(), target);
|
||||
|
||||
content = content.replace(dependency, replacement);
|
||||
}
|
||||
|
||||
Files.write(jenkinsfile.toPath(), content.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
logger.warn(module, "Jenkinsfile updated.");
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.release.build.BuildSystem#prepareVersion(org.springframework.data.release.model.ModuleIteration, org.springframework.data.release.model.Phase)
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.springframework.data.release.build.BuildOperations;
|
||||
import org.springframework.data.release.deployment.DeploymentInformation;
|
||||
import org.springframework.data.release.deployment.DeploymentOperations;
|
||||
import org.springframework.data.release.deployment.StagingRepository;
|
||||
import org.springframework.data.release.git.BranchMapping;
|
||||
import org.springframework.data.release.git.GitOperations;
|
||||
import org.springframework.data.release.issues.IssueTrackerCommands;
|
||||
import org.springframework.data.release.issues.github.GitHubCommands;
|
||||
@@ -188,7 +189,7 @@ class ReleaseCommands extends TimedCommand {
|
||||
git.tagRelease(iteration);
|
||||
|
||||
if (iteration.getTrain().isAlwaysUseBranch()) {
|
||||
setupMaintenanceVersions(iteration);
|
||||
setupMaintenanceVersions(iteration, BranchMapping.NONE);
|
||||
} else {
|
||||
|
||||
build.prepareVersions(iteration, Phase.CLEANUP);
|
||||
@@ -202,11 +203,14 @@ class ReleaseCommands extends TimedCommand {
|
||||
if (iteration.getIteration().isGAIteration()) {
|
||||
|
||||
// Create bugfix branches
|
||||
git.createMaintenanceBranches(iteration);
|
||||
BranchMapping branches = git.createMaintenanceBranches(iteration, true);
|
||||
|
||||
// Set project version to maintenance once
|
||||
setupMaintenanceVersions(iteration);
|
||||
}
|
||||
}
|
||||
setupMaintenanceVersions(iteration, branches);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,10 +233,9 @@ class ReleaseCommands extends TimedCommand {
|
||||
gitHub.triggerAntoraWorkflow(project);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void setupMaintenanceVersions(TrainIteration iteration) throws Exception {
|
||||
private void setupMaintenanceVersions(TrainIteration iteration, BranchMapping branches) throws Exception {
|
||||
|
||||
// Set project version to maintenance once
|
||||
build.prepareVersions(iteration, Phase.MAINTENANCE);
|
||||
@@ -240,6 +243,11 @@ class ReleaseCommands extends TimedCommand {
|
||||
|
||||
// Update inter-project dependencies and repositories
|
||||
build.updateProjectDescriptors(iteration, Phase.MAINTENANCE);
|
||||
|
||||
if (branches.hasBranches()) {
|
||||
build.updateBuildConfig(iteration, branches);
|
||||
}
|
||||
|
||||
git.commit(iteration, "After release cleanups.");
|
||||
|
||||
// Back to main branch
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2024 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 java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.data.release.model.Project;
|
||||
|
||||
/**
|
||||
* Value object to capture source and target branches for a {@link Project}
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class BranchMapping {
|
||||
|
||||
public static final BranchMapping NONE = new BranchMapping(Collections.emptyMap(), Collections.emptyMap());
|
||||
|
||||
private final Map<Project, Branch> sourceBranches;
|
||||
|
||||
private final Map<Project, Branch> targetBranches;
|
||||
|
||||
public BranchMapping() {
|
||||
this(new HashMap<>(), new HashMap<>());
|
||||
}
|
||||
|
||||
private BranchMapping(Map<Project, Branch> sourceBranches, Map<Project, Branch> targetBranches) {
|
||||
this.sourceBranches = sourceBranches;
|
||||
this.targetBranches = targetBranches;
|
||||
}
|
||||
|
||||
public void add(Project project, Branch sourceBranch, Branch targetBranch) {
|
||||
sourceBranches.put(project, sourceBranch);
|
||||
targetBranches.put(project, targetBranch);
|
||||
}
|
||||
|
||||
public Branch getSourceBranch(Project project) {
|
||||
return sourceBranches.get(project);
|
||||
}
|
||||
|
||||
public Branch getTargetBranch(Project project) {
|
||||
return targetBranches.get(project);
|
||||
}
|
||||
|
||||
public boolean hasBranches() {
|
||||
return !sourceBranches.isEmpty() && !targetBranches.isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -39,6 +39,7 @@ import org.eclipse.jgit.api.CommitCommand;
|
||||
import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.GitCommand;
|
||||
import org.eclipse.jgit.api.ListBranchCommand;
|
||||
import org.eclipse.jgit.api.LogCommand;
|
||||
import org.eclipse.jgit.api.ResetCommand.ResetType;
|
||||
import org.eclipse.jgit.api.TransportCommand;
|
||||
@@ -925,18 +926,41 @@ public class GitOperations {
|
||||
logger.log(project, "Checkout done!");
|
||||
}
|
||||
|
||||
public void createMaintenanceBranches(TrainIteration iteration) {
|
||||
public BranchMapping createMaintenanceBranches(TrainIteration iteration, boolean checkout) {
|
||||
|
||||
if (!iteration.getIteration().isGAIteration()) {
|
||||
return;
|
||||
if (checkout && !iteration.getIteration().isGAIteration()) {
|
||||
return BranchMapping.NONE;
|
||||
}
|
||||
|
||||
checkout(iteration);
|
||||
if (checkout) {
|
||||
checkout(iteration);
|
||||
}
|
||||
|
||||
return createBranch(iteration);
|
||||
}
|
||||
|
||||
public BranchMapping createBranch(TrainIteration iteration) {
|
||||
|
||||
BranchMapping branches = new BranchMapping();
|
||||
|
||||
ExecutionUtils.run(executor, iteration, module -> {
|
||||
|
||||
Branch branch = createMaintenanceBranch(module);
|
||||
checkout(module.getSupportedProject(), branch, BranchCheckoutMode.CREATE_ONLY);
|
||||
Branch current = getCurrentBranch(module);
|
||||
Branch newBranch = createBranch(module);
|
||||
checkout(module.getSupportedProject(), newBranch, BranchCheckoutMode.CREATE_ONLY);
|
||||
|
||||
synchronized (branches) {
|
||||
branches.add(module.getProject(), current, newBranch);
|
||||
}
|
||||
});
|
||||
|
||||
return branches;
|
||||
}
|
||||
|
||||
private Branch getCurrentBranch(ModuleIteration module) {
|
||||
|
||||
return doWithGit(module.getSupportedProject(), git -> {
|
||||
return Branch.from(git.getRepository().getBranch());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1012,13 +1036,26 @@ public class GitOperations {
|
||||
* @param module must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
private Branch createMaintenanceBranch(ModuleIteration module) {
|
||||
private Branch createBranch(ModuleIteration module) {
|
||||
|
||||
Assert.notNull(module, "Module iteration must not be null!");
|
||||
|
||||
Branch branch = Branch.from(module.getVersion());
|
||||
|
||||
doWithGit(module.getSupportedProject(), git -> {
|
||||
|
||||
List<String> existingBranches = git.branchList().setListMode(ListBranchCommand.ListMode.ALL) //
|
||||
.call() //
|
||||
.stream() //
|
||||
.filter(ref -> ref.getName().startsWith("refs/heads/")) //
|
||||
.map(it -> it.getName().substring(11)) //
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (existingBranches.contains(branch.toString())) {
|
||||
logger.log(module, "Branch %s already exists, skipping creation.", branch);
|
||||
return;
|
||||
}
|
||||
|
||||
logger.log(module, "git checkout -b %s", branch);
|
||||
git.branchCreate().setName(branch.toString()).call();
|
||||
});
|
||||
|
||||
@@ -126,7 +126,8 @@ public class ReleaseTrains {
|
||||
.withCalver("2025.0");
|
||||
|
||||
Z = Y.next("Z", Transition.MAJOR) //
|
||||
.withCalver("2025.1");
|
||||
.withCalver("2025.1") //
|
||||
.withAlwaysUseBranch(true);
|
||||
|
||||
// Trains
|
||||
|
||||
|
||||
Reference in New Issue
Block a user