Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions src/Elastic.Documentation.OpenApiIndex/VersionIndexBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ namespace Elastic.Documentation.OpenApiIndex;
/// Builds a <see cref="RootVersionIndex"/> from the object keys in the <c>elastic-docs-openapi-specs</c>
/// bucket, keeping the highest minor published for each major. Keys are expected in the shape written by
/// <c>elastic/docs-actions/openapi/upload</c>: <c>{org}/{repo}/{version}/{fileName}</c>, where
/// <c>version</c> is either <c>main</c> or a validated <c>{major}.{minor}</c> release version.
/// <c>version</c> is the publishing branch: <c>main</c>, <c>master</c>, or a validated
/// <c>{major}.{minor}</c> release version. <c>master</c> indexes under the <c>main</c> moniker so
/// a repo keeps its real branch name in the object key without every workflow overriding it.
/// </summary>
public static class VersionIndexBuilder
{
Expand Down Expand Up @@ -69,10 +71,12 @@ private static bool TryParseKey(string key, out string repo, out string version,
/// <summary>Resolves the index key ("main", or the major number) and a sortable minor for a version segment.</summary>
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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand Down Expand Up @@ -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 <major>.<minor>
[InlineData("elastic/elasticsearch/not-a-branch/openapi.json")] // not main, master, or <major>.<minor>

[InlineData("elastic/elasticsearch/8/openapi.json")] // missing minor

Expand All @@ -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"]);
}
}
Loading