Skip to content

Commit 7a01172

Browse files
committed
Use VersioningSystem.None for non-public-reference products
Products without the public-reference feature (e.g. release-notes-only products like docs-builder) now get VersioningSystem.None instead of null. This prevents NullReferenceExceptions in version inference when the product is matched by repository name during doc builds. VersioningSystem.None is a versionless sentinel (using the existing 99999 convention) with a new VersioningSystemId.None enum value, making the "no versioning" state explicit rather than relying on null. Made-with: Cursor
1 parent f186f95 commit 7a01172

4 files changed

Lines changed: 50 additions & 14 deletions

File tree

src/Elastic.Documentation.Configuration/Inference/VersionInference.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,17 @@ public VersioningSystem InferVersion(string repositoryName, IReadOnlyCollection<
3030
return versioningFromApplicability;
3131
}
3232

33-
var versioning = ProductsConfiguration.Products.TryGetValue(repositoryName, out var belonging)
34-
? belonging.VersioningSystem! //If the page's docset has a name with a direct product match, use the versioning system of the product
35-
: ProductsConfiguration.Products.Values.SingleOrDefault(p =>
36-
p.Repository is not null && p.Repository.Equals(repositoryName, StringComparison.OrdinalIgnoreCase)) is { } repositoryMatch
37-
? repositoryMatch.VersioningSystem! // Verify if the page belongs to a repository linked to a product, and if so, use the versioning system of the product
38-
: VersionsConfiguration.VersioningSystems[VersioningSystemId.Stack]; // Fallback to the stack versioning system
39-
40-
return versioning;
33+
var stackFallback = VersionsConfiguration.VersioningSystems[VersioningSystemId.Stack];
34+
35+
if (ProductsConfiguration.Products.TryGetValue(repositoryName, out var belonging) && belonging.VersioningSystem is not null)
36+
return belonging.VersioningSystem;
37+
38+
var repositoryMatch = ProductsConfiguration.Products.Values
39+
.SingleOrDefault(p => p.Repository is not null && p.Repository.Equals(repositoryName, StringComparison.OrdinalIgnoreCase));
40+
if (repositoryMatch?.VersioningSystem is not null)
41+
return repositoryMatch.VersioningSystem;
42+
43+
return stackFallback;
4144
}
4245

4346
private VersioningSystem? VersioningFromApplicability(ApplicableTo applicableTo)

src/Elastic.Documentation.Configuration/Products/ProductExtensions.cs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,22 @@ public static ProductsConfiguration CreateProducts(this ConfigurationFileProvide
1818

1919
var products = productsDto.Products.ToDictionary(
2020
kvp => kvp.Key,
21-
kvp => new Product
21+
kvp =>
2222
{
23-
Id = kvp.Key,
24-
DisplayName = kvp.Value.Display,
25-
VersioningSystem = ResolveVersioningSystem(versionsConfiguration, kvp.Value.Versioning ?? kvp.Key),
26-
Repository = kvp.Value.Repository ?? kvp.Key,
27-
Features = ResolveFeatures(kvp.Key, kvp.Value.Features)
23+
var features = ResolveFeatures(kvp.Key, kvp.Value.Features);
24+
var versioningSystem = ResolveVersioningSystem(versionsConfiguration, kvp.Value.Versioning ?? kvp.Key);
25+
26+
if (versioningSystem is null && !features.PublicReference)
27+
versioningSystem = VersioningSystem.None;
28+
29+
return new Product
30+
{
31+
Id = kvp.Key,
32+
DisplayName = kvp.Value.Display,
33+
VersioningSystem = versioningSystem,
34+
Repository = kvp.Value.Repository ?? kvp.Key,
35+
Features = features
36+
};
2837
});
2938

3039
var publicReferenceProducts = products

src/Elastic.Documentation.Configuration/Versions/VersionConfiguration.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public VersioningSystem GetVersioningSystem(VersioningSystemId versioningSystem)
2323
[EnumExtensions]
2424
public enum VersioningSystemId
2525
{
26+
[Display(Name = "none")]
27+
None,
2628
[Display(Name = "stack")]
2729
Stack,
2830
[Display(Name = "all")]
@@ -152,6 +154,17 @@ public record VersioningSystem
152154
/// </summary>
153155
public const int VersionlessSentinel = 99999;
154156

157+
/// <summary>
158+
/// A versionless sentinel for products that have no versioning system at all
159+
/// (e.g. release-notes-only products without public documentation).
160+
/// </summary>
161+
public static VersioningSystem None { get; } = new()
162+
{
163+
Id = VersioningSystemId.None,
164+
Base = new SemVersion(VersionlessSentinel, 0, 0),
165+
Current = new SemVersion(VersionlessSentinel, 0, 0)
166+
};
167+
155168
public required VersioningSystemId Id { get; init; }
156169

157170
[YamlMember(Alias = "base")]

tests/Elastic.Documentation.Configuration.Tests/ProductFeaturesTests.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,17 @@ public void ProductWithReleaseNotesOnly_ExcludedFromPublicReference()
3232
docsBuilder.Features.ReleaseNotes.Should().BeTrue();
3333
}
3434

35+
[Fact]
36+
public void ProductWithoutPublicReference_GetsNoneVersioningSystem()
37+
{
38+
var config = LoadActualProductsConfiguration();
39+
var docsBuilder = config.Products["docs-builder"];
40+
41+
docsBuilder.VersioningSystem.Should().Be(VersioningSystem.None);
42+
docsBuilder.VersioningSystem.IsVersionless.Should().BeTrue();
43+
docsBuilder.VersioningSystem.Id.Should().Be(VersioningSystemId.None);
44+
}
45+
3546
[Fact]
3647
public void PublicReferenceProducts_ExcludesReleaseNotesOnlyProducts()
3748
{

0 commit comments

Comments
 (0)