From afd6e96435bf7d2973f04906734a33a7aa6b835e Mon Sep 17 00:00:00 2001 From: Andrew Ross Date: Sat, 14 Mar 2026 10:49:57 -0700 Subject: [PATCH] Tolerate BWC branch patch version bump When a patch release (e.g., 2.19.5) is published and the release branch is bumped to the next patch (2.19.6), BWC tests on main fail because Version.java still references the old patch version. This causes all in-flight PRs to fail until Version.java is updated. This change relaxes the logic so that BWC tests will still pass if the checked out code uses a patch version one greater than expected. This prevents CI failures every time a release branch increments its patch version, but still prevents the main branch from drifting by more than one patch version. Signed-off-by: Andrew Ross --- .../InternalDistributionBwcSetupPlugin.java | 109 ++++++++++++++---- 1 file changed, 86 insertions(+), 23 deletions(-) diff --git a/buildSrc/src/main/java/org/opensearch/gradle/internal/InternalDistributionBwcSetupPlugin.java b/buildSrc/src/main/java/org/opensearch/gradle/internal/InternalDistributionBwcSetupPlugin.java index 62b865bb06903..c882a8d69956c 100644 --- a/buildSrc/src/main/java/org/opensearch/gradle/internal/InternalDistributionBwcSetupPlugin.java +++ b/buildSrc/src/main/java/org/opensearch/gradle/internal/InternalDistributionBwcSetupPlugin.java @@ -106,7 +106,7 @@ private void configureBwcProject(Project project, BwcVersions.UnreleasedVersionI bwcVersion, distributionProject.name, distributionProject.getProjectPath(), - distributionProject.getDistFile(), + distributionProject, buildBwcTaskProvider ); @@ -131,14 +131,24 @@ private void registerBwcArtifacts(Project bwcProject, DistributionProject distri } private void registerDistributionArchiveArtifact(Project bwcProject, DistributionProject distributionProject, String buildBwcTask) { - String artifactFileName = distributionProject.getDistFile().getName(); + String artifactFileName = distributionProject.getExpectedDistFile().getName(); String artifactName = "opensearch"; String suffix = artifactFileName.endsWith("tar.gz") ? "tar.gz" : artifactFileName.substring(artifactFileName.length() - 3); int archIndex = artifactFileName.indexOf("x64"); + Provider artifactFileProvider = providerFactory.provider(() -> { + if (distributionProject.getExpectedDistFile().exists()) { + return distributionProject.getExpectedDistFile(); + } else if (distributionProject.getFallbackDistFile().exists()) { + return distributionProject.getFallbackDistFile(); + } + // File doesn't exist, validation will fail elsewhere but we must return a File here + return distributionProject.getExpectedDistFile(); + }); + bwcProject.getConfigurations().create(distributionProject.name); - bwcProject.getArtifacts().add(distributionProject.name, distributionProject.getDistFile(), artifact -> { + bwcProject.getArtifacts().add(distributionProject.name, artifactFileProvider, artifact -> { artifact.setName(artifactName); artifact.builtBy(buildBwcTask); artifact.setType(suffix); @@ -152,6 +162,10 @@ private void registerDistributionArchiveArtifact(Project bwcProject, Distributio }); } + static Version nextPatchVersion(Version version) { + return new Version(version.getMajor(), version.getMinor(), version.getRevision() + 1); + } + private static List resolveArchiveProjects(File checkoutDir, Version bwcVersion) { List projects = new ArrayList<>(); // All active BWC branches publish rpm and deb packages @@ -174,6 +188,8 @@ private static List resolveArchiveProjects(File checkoutDir projects.addAll(asList("zip", "tar")); } + Version fallbackVersion = nextPatchVersion(bwcVersion); + return projects.stream().map(name -> { String baseDir = "distribution" + (name.endsWith("zip") || name.endsWith("tar") ? "/archives" : "/packages"); String classifier = ""; @@ -199,7 +215,7 @@ private static List resolveArchiveProjects(File checkoutDir } else { extension = name.substring(4); } - return new DistributionProject(name, baseDir, bwcVersion, classifier, extension, checkoutDir); + return new DistributionProject(name, baseDir, bwcVersion, fallbackVersion, classifier, extension, checkoutDir); }).collect(Collectors.toList()); } @@ -215,7 +231,7 @@ static void createBuildBwcTask( Provider bwcVersion, String projectName, String projectPath, - File projectArtifact, + DistributionProject distributionProject, TaskProvider bwcTaskProvider ) { String bwcTaskName = buildBwcTaskName(projectName); @@ -223,7 +239,7 @@ static void createBuildBwcTask( @Override public void execute(LoggedExec c) { c.getInputs().file(new File(project.getBuildDir(), "refspec")); - c.getOutputs().files(projectArtifact); + c.getOutputs().files(distributionProject.getExpectedDistFile(), distributionProject.getFallbackDistFile()); c.getOutputs().cacheIf("BWC distribution caching is disabled on 'master' branch", task -> { String gitBranch = System.getenv("GIT_BRANCH"); return BuildParams.isCi() && (gitBranch == null || gitBranch.endsWith("master") == false); @@ -235,9 +251,24 @@ public void execute(LoggedExec c) { c.doLast(new Action() { @Override public void execute(Task task) { - if (projectArtifact.exists() == false) { + if (distributionProject.getExpectedDistFile().exists() == false + && distributionProject.getFallbackDistFile().exists()) { + project.getLogger() + .warn( + "BWC branch produced {} instead of {}. " + + "Version.java on main may need updating to include version {}.", + distributionProject.getFallbackDistFile().getName(), + distributionProject.getExpectedDistFile().getName(), + distributionProject.getFallbackVersion() + ); + } else if (distributionProject.getExpectedDistFile().exists() == false) { throw new InvalidUserDataException( - "Building " + bwcVersion.get() + " didn't generate expected file " + projectArtifact + "Building " + + bwcVersion.get() + + " didn't generate expected file " + + distributionProject.getExpectedDistFile() + + " or fallback " + + distributionProject.getFallbackDistFile() ); } } @@ -251,20 +282,48 @@ public void execute(Task task) { * Represents an archive project (distribution/archives/*) * we build from a bwc Version in a cloned repository */ - private static class DistributionProject { - private final String name; - private String projectPath; - private File distFile; - private File expandedDistDir; - - DistributionProject(String name, String baseDir, Version version, String classifier, String extension, File checkoutDir) { + static class DistributionProject { + final String name; + private final String projectPath; + private final File expectedDistFile; + private final File fallbackDistFile; + private final Version fallbackVersion; + private final File expandedDistDir; + + DistributionProject( + String name, + String baseDir, + Version expectedVersion, + Version fallbackVersion, + String classifier, + String extension, + File checkoutDir + ) { this.name = name; this.projectPath = baseDir + "/" + name; + this.expectedDistFile = buildDistFile(name, baseDir, expectedVersion, classifier, extension, checkoutDir); + this.fallbackDistFile = buildDistFile(name, baseDir, fallbackVersion, classifier, extension, checkoutDir); + this.fallbackVersion = fallbackVersion; + if (name.endsWith("zip") || name.endsWith("tar")) { + this.expandedDistDir = new File(checkoutDir, baseDir + "/" + name + "/build/install"); + } else { + this.expandedDistDir = null; + } + } + + private static File buildDistFile( + String name, + String baseDir, + Version version, + String classifier, + String extension, + File checkoutDir + ) { if (version.onOrAfter("1.1.0")) { // Deb uses underscores (I don't know why...): // https://github.com/opensearch-project/OpenSearch/blob/f6d9a86f0e2e8241fd58b7e8b6cdeaf931b5108f/distribution/packages/build.gradle#L139 final String separator = name.equals("deb") ? "_" : "-"; - this.distFile = new File( + return new File( checkoutDir, baseDir + "/" @@ -278,23 +337,27 @@ private static class DistributionProject { + extension ); } else { - this.distFile = new File( + return new File( checkoutDir, baseDir + "/" + name + "/build/distributions/opensearch-" + version + "-SNAPSHOT" + classifier + "." + extension ); } - // we only ported this down to the 7.x branch. - if (version.onOrAfter("7.10.0") && (name.endsWith("zip") || name.endsWith("tar"))) { - this.expandedDistDir = new File(checkoutDir, baseDir + "/" + name + "/build/install"); - } } public String getProjectPath() { return projectPath; } - public File getDistFile() { - return distFile; + public File getExpectedDistFile() { + return expectedDistFile; + } + + public File getFallbackDistFile() { + return fallbackDistFile; + } + + public Version getFallbackVersion() { + return fallbackVersion; } public File getExpandedDistDirectory() {