From 47c6c9d8ac1c2657f352a7ffe31a0238103a94a4 Mon Sep 17 00:00:00 2001 From: Jan Calanog Date: Thu, 17 Sep 2026 16:21:28 +0200 Subject: [PATCH 1/4] Index OpenAPI specs published from master under the main moniker The upload action keys objects by branch name. elastic/cloud publishes from master, so its specs land in S3 and the index builder dropped them as invalid keys. Mapping master to main here keeps the real branch in the object key without every consumer overriding version. Co-Authored-By: Claude Co-authored-by: Cursor --- .../VersionIndexBuilder.cs | 10 ++++--- .../VersionIndexBuilderTests.cs | 26 ++++++++++++++++--- 2 files changed, 30 insertions(+), 6 deletions(-) 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..80b91f455b 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/latest/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/latest/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/latest/openapi.json"]); } } From 8520144c6401081eaf36e4df29d156fbeb1457a7 Mon Sep 17 00:00:00 2001 From: Jan Calanog Date: Thu, 17 Sep 2026 16:36:31 +0200 Subject: [PATCH 2/4] Add Cloud Billing to the isolated API fixtures Isolated serve needs a prefixed key so assembler preview does not collide with the docs-content entry. Co-Authored-By: Cursor Grok 4.6 Co-authored-by: Cursor --- docs/_docset.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/_docset.yml b/docs/_docset.yml index 1e4ddcad7a..323006b0f5 100644 --- a/docs/_docset.yml +++ b/docs/_docset.yml @@ -64,6 +64,13 @@ api: - spec: kibana-serverless.yaml product: kibana repository: elastic/kibana + docs-builder-cloud-billing: + - spec: cloud-billing.yaml + product: ess + repository: elastic/cloud + catalog: + categories: + - ess docs-builder-cloud-connect: - spec: cloud-connect.yml product: ess From d47e80e0e328cf3951cbc763c0bc7ee890040343 Mon Sep 17 00:00:00 2001 From: Jan Calanog Date: Thu, 17 Sep 2026 16:48:49 +0200 Subject: [PATCH 3/4] Revert "Add Cloud Billing to the isolated API fixtures" This reverts commit 8520144c6401081eaf36e4df29d156fbeb1457a7. --- docs/_docset.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/docs/_docset.yml b/docs/_docset.yml index 323006b0f5..1e4ddcad7a 100644 --- a/docs/_docset.yml +++ b/docs/_docset.yml @@ -64,13 +64,6 @@ api: - spec: kibana-serverless.yaml product: kibana repository: elastic/kibana - docs-builder-cloud-billing: - - spec: cloud-billing.yaml - product: ess - repository: elastic/cloud - catalog: - categories: - - ess docs-builder-cloud-connect: - spec: cloud-connect.yml product: ess From 071b0fba755e26f80bd7c64896efdbf31f64156e Mon Sep 17 00:00:00 2001 From: Jan Calanog Date: Thu, 17 Sep 2026 16:52:27 +0200 Subject: [PATCH 4/4] Use an obviously bogus branch name in the invalid-key tests Co-Authored-By: Claude Co-authored-by: Cursor --- .../VersionIndexBuilderTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Elastic.Documentation.OpenApiIndex.Tests/VersionIndexBuilderTests.cs b/tests/Elastic.Documentation.OpenApiIndex.Tests/VersionIndexBuilderTests.cs index 80b91f455b..7ff88991b3 100644 --- a/tests/Elastic.Documentation.OpenApiIndex.Tests/VersionIndexBuilderTests.cs +++ b/tests/Elastic.Documentation.OpenApiIndex.Tests/VersionIndexBuilderTests.cs @@ -117,7 +117,7 @@ public void Build_MultipleRepos_KeepsSeparateEntriesPerRepo() [InlineData("elastic/elasticsearch/8.16/")] // empty file segment - [InlineData("elastic/elasticsearch/latest/openapi.json")] // not main, master, or . + [InlineData("elastic/elasticsearch/not-a-branch/openapi.json")] // not main, master, or . [InlineData("elastic/elasticsearch/8/openapi.json")] // missing minor @@ -143,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/latest/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/latest/openapi.json"]); + invalidKeys.Should().BeEquivalentTo(["not-a-valid-key", "elastic/elasticsearch/not-a-branch/openapi.json"]); } }