From 0fefcfc504a38585ea858c9ca6c2cbffaf12a06c Mon Sep 17 00:00:00 2001 From: Martijn Laarman Date: Tue, 24 Feb 2026 09:01:57 +0100 Subject: [PATCH] Fix speculative build incorrectly triggering for current version branches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a repository uses `main` as its current branch (not a version branch), the speculative build logic falls back to product version information. The comparison used `>=` against the anchored product version, which caused version branches equal to the current product version to trigger speculative builds unnecessarily. For example, `elastic/elasticsearch` has `current: main` in assembler.yml and the stack product version is `9.3.0`. When a push to the `9.3` branch occurs, the match logic traces as follows: 1. Branch `9.3` is a version branch, but `current/next/edge` are all `main` so no content source matches 2. `SemVersion.TryParse("main.0")` fails since current is not a version branch, falling into the product version fallback path 3. Product version `9.3.0` anchors to `9.3.0`, and `9.3.0 >= 9.3.0` is true, incorrectly triggering a speculative build The `9.3` branch IS the current version — its content is already served from `main`. Only versions strictly greater than current (e.g. `9.4`) represent future versions that need speculative builds. Fix: change `>=` to `>` in the product version comparison path. This does not affect the versioned-current path (where current is e.g. `8.0`) which correctly uses `>=` since the exact match is already recorded as a named content source. Fixes: https://github.com/elastic/elasticsearch/actions/runs/22323312600/job/64598377227?pr=142356 Co-authored-by: Cursor --- .../Assembler/AssemblyConfiguration.cs | 4 ++-- .../AssemblyConfigurationMatchTests.cs | 19 ++++++++----------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/Elastic.Documentation.Configuration/Assembler/AssemblyConfiguration.cs b/src/Elastic.Documentation.Configuration/Assembler/AssemblyConfiguration.cs index ba59d4266..ecc765fd5 100644 --- a/src/Elastic.Documentation.Configuration/Assembler/AssemblyConfiguration.cs +++ b/src/Elastic.Documentation.Configuration/Assembler/AssemblyConfiguration.cs @@ -232,9 +232,9 @@ public ContentSourceMatch Match(ILoggerFactory logFactory, string repository, st logger.LogInformation("Current is not using versioned branches and is not publishing to the registry yet, using product information to determine speculative build is needed"); var productVersion = versioningSystem.Current; var anchoredProductVersion = new SemVersion(productVersion.Major, productVersion.Minor, 0); - if (v >= anchoredProductVersion) + if (v > anchoredProductVersion) { - logger.LogInformation("Speculative build {Branch} is gte product current '{ProductCurrent}' anchored at {ProductAnchored}", branchOrTag, + logger.LogInformation("Speculative build {Branch} is gt product current '{ProductCurrent}' anchored at {ProductAnchored}", branchOrTag, productVersion, anchoredProductVersion); match = match with { diff --git a/tests/Elastic.Documentation.Configuration.Tests/AssemblyConfigurationMatchTests.cs b/tests/Elastic.Documentation.Configuration.Tests/AssemblyConfigurationMatchTests.cs index 44cff7c7f..467c00ea7 100644 --- a/tests/Elastic.Documentation.Configuration.Tests/AssemblyConfigurationMatchTests.cs +++ b/tests/Elastic.Documentation.Configuration.Tests/AssemblyConfigurationMatchTests.cs @@ -165,10 +165,10 @@ public void VersionBranchSpeculativeBuildBasedOnCurrentVersion(string branch, st [Theory] [InlineData("8.16", "8.15", true)] // Greater than product version - [InlineData("8.15", "8.15", true)] // Equal to product version + [InlineData("8.15", "8.15", false)] // Equal to product version — current is served from main [InlineData("8.14", "8.15", false)] // Previous minor version - but current is not versioned, so no previous minor logic [InlineData("8.13", "8.15", false)] // Less than previous minor - [InlineData("8.0", "8.0", true)] // Edge case: minor version 0 + [InlineData("8.0", "8.0", false)] // Edge case: equal at minor version 0 public void VersionBranchSpeculativeBuildBasedOnProductVersion(string branch, string productVersion, bool shouldBeSpeculative) { var repositories = new Dictionary @@ -267,10 +267,9 @@ public void CurrentVersionMatchAlsoSetsSpeculative() } [Theory] - [InlineData("9.0", "9.0.0")] // Matches anchored product version [InlineData("9.1", "9.0.0")] // Greater than anchored product version [InlineData("9.5", "9.0.0")] // Much greater than anchored product version - public void VersionBranchSpeculativeBuildWhenGreaterThanOrEqualToAnchoredProductVersion(string branch, string productVersion) + public void VersionBranchSpeculativeBuildWhenGreaterThanAnchoredProductVersion(string branch, string productVersion) { var repositories = new Dictionary { @@ -289,7 +288,8 @@ public void VersionBranchSpeculativeBuildWhenGreaterThanOrEqualToAnchoredProduct [InlineData("8.15", "9.0.0")] // Less than anchored product version [InlineData("7.17", "9.0.0")] // Much less than anchored product version [InlineData("8.0", "9.1.5")] // Less than anchored product version with patch - public void VersionBranchNoSpeculativeBuildWhenLessThanAnchoredProductVersionAndNotPreviousMinor(string branch, string productVersion) + [InlineData("9.0", "9.0.0")] // Equal to anchored product version — current is served from main + public void VersionBranchNoSpeculativeBuildWhenLessThanOrEqualToAnchoredProductVersionAndNotPreviousMinor(string branch, string productVersion) { var repositories = new Dictionary { @@ -356,9 +356,9 @@ public void VersionBranchNoSpeculativeBuildWhenProductIsNull() } [Theory] - [InlineData("9.0", "9.0.15")] // Anchored version equals major.minor.0 - [InlineData("9.0", "9.0.0")] // Anchored version equals major.minor.0 - [InlineData("9.0", "9.0.1")] // Anchored version equals major.minor.0 + [InlineData("9.1", "9.0.15")] // Anchored to 9.0.0, branch 9.1 > 9.0.0 + [InlineData("9.1", "9.0.0")] // Anchored to 9.0.0, branch 9.1 > 9.0.0 + [InlineData("9.1", "9.0.1")] // Anchored to 9.0.0, branch 9.1 > 9.0.0 public void VersionBranchAnchorsProductVersionToMinorZero(string branch, string productVersion) { var repositories = new Dictionary @@ -371,7 +371,6 @@ public void VersionBranchAnchorsProductVersionToMinorZero(string branch, string var result = config.Match(LoggerFactory, "elastic/test-repo", branch, product, false); - // Should match because branch 9.0 >= anchored product version 9.0.0 result.Speculative.Should().BeTrue(); } @@ -395,7 +394,6 @@ public void VersionBranchPreviousMinorCalculationHandlesEdgeCases(string branch, } [Theory] - [InlineData("9.0", "9.0.0")] // Matches anchored product version [InlineData("9.1", "9.0.0")] // Greater than anchored product version [InlineData("9.5", "9.0.0")] // Much greater than anchored product version public void AlreadyPublishingTruePreventSpeculativeBuildForVersionBranch(string branch, string productVersion) @@ -414,7 +412,6 @@ public void AlreadyPublishingTruePreventSpeculativeBuildForVersionBranch(string } [Theory] - [InlineData("9.0", "9.0.0")] // Matches anchored product version [InlineData("9.1", "9.0.0")] // Greater than anchored product version [InlineData("9.5", "9.0.0")] // Much greater than anchored product version public void AlreadyPublishingFalseAllowsSpeculativeBuildForVersionBranch(string branch, string productVersion)