diff --git a/src/Elastic.Documentation.OpenApiIndex/VersionIndexBuilder.cs b/src/Elastic.Documentation.OpenApiIndex/VersionIndexBuilder.cs index d6a4125f00..6e4631e4b6 100644 --- a/src/Elastic.Documentation.OpenApiIndex/VersionIndexBuilder.cs +++ b/src/Elastic.Documentation.OpenApiIndex/VersionIndexBuilder.cs @@ -10,7 +10,9 @@ namespace Elastic.Documentation.OpenApiIndex; /// Builds a from the object keys in the elastic-docs-openapi-specs /// bucket, keeping the highest minor published for each major. Keys are expected in the shape written by /// elastic/docs-actions/openapi/upload: {org}/{repo}/{version}/{fileName}, where -/// version is either main or a validated {major}.{minor} release version. +/// version is the publishing branch: main, master, or a validated +/// {major}.{minor} release version. master indexes under the main moniker so +/// a repo keeps its real branch name in the object key without every workflow overriding it. /// public static class VersionIndexBuilder { @@ -69,10 +71,12 @@ private static bool TryParseKey(string key, out string repo, out string version, /// Resolves the index key ("main", or the major number) and a sortable minor for a version segment. private static bool TryParseVersion(string version, out string major, out int minor) { - if (version == "main") + // Both default-branch names share the "main" key. If a repo somehow publishes from both, + // the higher minor wins like any other collision, so main beats master. + if (version is "main" or "master") { major = "main"; - minor = 0; + minor = version == "main" ? 1 : 0; return true; } diff --git a/tests/Elastic.Documentation.OpenApiIndex.Tests/VersionIndexBuilderTests.cs b/tests/Elastic.Documentation.OpenApiIndex.Tests/VersionIndexBuilderTests.cs index e053aa2fb2..7ff88991b3 100644 --- a/tests/Elastic.Documentation.OpenApiIndex.Tests/VersionIndexBuilderTests.cs +++ b/tests/Elastic.Documentation.OpenApiIndex.Tests/VersionIndexBuilderTests.cs @@ -52,6 +52,26 @@ public void Build_MainVersion_CreatesMainEntry() index["elastic/elasticsearch"]["openapi.json"]["main"].Version.Should().Be("main"); } + [Fact] + public void Build_MasterVersion_IndexesUnderMainWithMasterObjectKey() + { + var index = VersionIndexBuilder.Build(["elastic/cloud/master/cloud.json"]).Index; + + var byMajor = index["elastic/cloud"]["cloud.json"]; + byMajor.Should().ContainSingle().Which.Key.Should().Be("main"); + byMajor["main"].Version.Should().Be("master"); + } + + [Fact] + public void Build_MainAndMasterBothPublished_MainWins() + { + var index = VersionIndexBuilder.Build(["elastic/cloud/master/cloud.json", "elastic/cloud/main/cloud.json"]).Index; + + var byMajor = index["elastic/cloud"]["cloud.json"]; + byMajor.Should().ContainSingle().Which.Key.Should().Be("main"); + byMajor["main"].Version.Should().Be("main"); + } + [Fact] public void Build_MainAndReleaseVersions_KeepsBothSeparately() { @@ -97,7 +117,7 @@ public void Build_MultipleRepos_KeepsSeparateEntriesPerRepo() [InlineData("elastic/elasticsearch/8.16/")] // empty file segment - [InlineData("elastic/elasticsearch/master/openapi.json")] // not "main" or . + [InlineData("elastic/elasticsearch/not-a-branch/openapi.json")] // not main, master, or . [InlineData("elastic/elasticsearch/8/openapi.json")] // missing minor @@ -123,10 +143,10 @@ public void Build_MixOfValidAndInvalidKeys_IndexesValidAndReportsInvalidOnly() var (index, invalidKeys) = VersionIndexBuilder.Build([ "elastic/elasticsearch/8.16/openapi.json", "not-a-valid-key", - "elastic/elasticsearch/master/openapi.json" + "elastic/elasticsearch/not-a-branch/openapi.json" ]); index["elastic/elasticsearch"]["openapi.json"]["8"].Version.Should().Be("8.16"); - invalidKeys.Should().BeEquivalentTo(["not-a-valid-key", "elastic/elasticsearch/master/openapi.json"]); + invalidKeys.Should().BeEquivalentTo(["not-a-valid-key", "elastic/elasticsearch/not-a-branch/openapi.json"]); } }