Skip to content

Use new versions.yml config to render applies_to tags #1465

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 30, 2025
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
169 changes: 135 additions & 34 deletions docs/syntax/applies.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/syntax/stepper.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ npm install
::::

::::{step} Build
### Build
Then build the project.
```shell
npm run build
Expand Down
37 changes: 3 additions & 34 deletions docs/testing/req.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,5 @@
---
applies_to:
stack: ga 9.1
---

# Requirements

Current version: **9.0.0**

| `applies_to` | result |
|--------------------------------------------|--------------------------------------|
| `` {applies_to}`stack: preview` `` | {applies_to}`stack: preview` |
| `` {applies_to}`stack: preview 8.18` `` | {applies_to}`stack: preview 8.18` |
| `` {applies_to}`stack: preview 9.0` `` | {applies_to}`stack: preview 9.0` |
| `` {applies_to}`stack: preview 9.1` `` | {applies_to}`stack: preview 9.1` |
| `` {applies_to}`stack: ga` `` | {applies_to}`stack: ga` |
| `` {applies_to}`stack: ga 8.18` `` | {applies_to}`stack: ga 8.18` |
| `` {applies_to}`stack: ga 9.0` `` | {applies_to}`stack: ga 9.0` |
| `` {applies_to}`stack: ga 9.1` `` | {applies_to}`stack: ga 9.1` |
| `` {applies_to}`stack: beta` `` | {applies_to}`stack: beta` |
| `` {applies_to}`stack: beta 8.18` `` | {applies_to}`stack: beta 8.18` |
| `` {applies_to}`stack: beta 9.0` `` | {applies_to}`stack: beta 9.0` |
| `` {applies_to}`stack: beta 9.1` `` | {applies_to}`stack: beta 9.1` |
| `` {applies_to}`stack: deprecated` `` | {applies_to}`stack: deprecated` |
| `` {applies_to}`stack: deprecated 8.18` `` | {applies_to}`stack: deprecated 8.18` |
| `` {applies_to}`stack: deprecated 9.0` `` | {applies_to}`stack: deprecated 9.0` |
| `` {applies_to}`stack: deprecated 9.1` `` | {applies_to}`stack: deprecated 9.1` |
| `` {applies_to}`stack: removed` `` | {applies_to}`stack: removed` |
| `` {applies_to}`stack: removed 8.18` `` | {applies_to}`stack: removed 8.18` |
| `` {applies_to}`stack: removed 9.0` `` | {applies_to}`stack: removed 9.0` |
| `` {applies_to}`stack: removed 9.1` `` | {applies_to}`stack: removed 9.1` |
| `` {applies_to}`stack: ` `` | {applies_to}`stack: ` |

{applies_to}`stack: deprecated 9.1, removed 9.4`


To follow this tutorial you will need to install the following components:

- An installation of Elasticsearch, based on our hosted [Elastic Cloud](https://www.elastic.co/cloud) service (which includes a free trial period), or a self-hosted service that you run on your own computer. See the Install Elasticsearch section above for installation instructions.
Expand All @@ -44,3 +10,6 @@ The tutorial assumes that you have no previous knowledge of Elasticsearch or gen
- Python development
- The [Flask](https://flask.palletsprojects.com/) web framework for Python.
- The command prompt or terminal application in your operating system.


{applies_to}`ece: removed`
15 changes: 11 additions & 4 deletions src/Elastic.Documentation.Configuration/BuildContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@
using System.Reflection;
using Elastic.Documentation.Configuration.Assembler;
using Elastic.Documentation.Configuration.Builder;
using Elastic.Documentation.Configuration.Versions;
using Elastic.Documentation.Diagnostics;

namespace Elastic.Documentation.Configuration;

public record BuildContext : IDocumentationContext
{
public static string Version { get; } = Assembly.GetExecutingAssembly().GetCustomAttributes<AssemblyInformationalVersionAttribute>()
.FirstOrDefault()?.InformationalVersion ?? "0.0.0";
.FirstOrDefault()?.InformationalVersion ?? "0.0.0";

public IFileSystem ReadFileSystem { get; }
public IFileSystem WriteFileSystem { get; }

Expand All @@ -23,6 +25,8 @@ public record BuildContext : IDocumentationContext

public ConfigurationFile Configuration { get; }

public VersionsConfiguration VersionsConfig { get; init; }

public IFileInfo ConfigurationPath { get; }

public GitCheckoutInformation Git { get; }
Expand Down Expand Up @@ -60,13 +64,16 @@ public string? UrlPathPrefix
init => _urlPathPrefix = value;
}

public BuildContext(IDiagnosticsCollector collector, IFileSystem fileSystem)
: this(collector, fileSystem, fileSystem, null, null) { }
public BuildContext(IDiagnosticsCollector collector, IFileSystem fileSystem, VersionsConfiguration versionsConfig)
: this(collector, fileSystem, fileSystem, versionsConfig, null, null)
{
}

public BuildContext(
IDiagnosticsCollector collector,
IFileSystem readFileSystem,
IFileSystem writeFileSystem,
VersionsConfiguration versionsConfig,
string? source = null,
string? output = null,
GitCheckoutInformation? gitCheckoutInformation = null
Expand All @@ -75,6 +82,7 @@ public BuildContext(
Collector = collector;
ReadFileSystem = readFileSystem;
WriteFileSystem = writeFileSystem;
VersionsConfig = versionsConfig;

var rootFolder = !string.IsNullOrWhiteSpace(source)
? ReadFileSystem.DirectoryInfo.New(source)
Expand All @@ -98,5 +106,4 @@ public BuildContext(
Enabled = false
};
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,8 @@
<PackageReference Include="Vecc.YamlDotNet.Analyzers.StaticGenerator"/>
<PackageReference Include="YamlDotNet"/>
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="versions.yml" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information

using Elastic.Documentation.Configuration.Assembler;
using Elastic.Documentation.Configuration.Versions;
using YamlDotNet.Serialization;

namespace Elastic.Documentation.Configuration.Serialization;
Expand All @@ -15,4 +16,6 @@ namespace Elastic.Documentation.Configuration.Serialization;
[YamlSerializable(typeof(GoogleTagManager))]
[YamlSerializable(typeof(ContentSource))]
[YamlSerializable(typeof(VersionEntry))]
[YamlSerializable(typeof(VersionsConfigDto))]
[YamlSerializable(typeof(VersioningSystemDto))]
public partial class YamlStaticContext;
98 changes: 98 additions & 0 deletions src/Elastic.Documentation.Configuration/Versions/Version.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using System.ComponentModel.DataAnnotations;
using NetEscapades.EnumGenerators;
using YamlDotNet.Serialization;

namespace Elastic.Documentation.Configuration.Versions;

[YamlSerializable]
public record VersionsConfiguration
{
public required IReadOnlyDictionary<VersioningSystemId, VersioningSystem> VersioningSystems { get; init; }
public VersioningSystem GetVersioningSystem(VersioningSystemId versioningSystem)
{
if (!VersioningSystems.TryGetValue(versioningSystem, out var version))
throw new ArgumentException($"Unknown versioning system: {versioningSystem}");
return version;
}
}

[EnumExtensions]
public enum VersioningSystemId
{
[Display(Name = "stack")]
Stack,
[Display(Name = "all")]
All,
[Display(Name = "ece")]
Ece,
[Display(Name = "ech")]
Ech,
[Display(Name = "eck")]
Eck,
[Display(Name = "ess")]
Ess,
[Display(Name = "self")]
Self,
[Display(Name = "ecctl")]
Ecctl,
[Display(Name = "curator")]
Curator,
[Display(Name = "serverless")]
Serverless,
[Display(Name = "elasticsearch")]
Elasticsearch,
[Display(Name = "observability")]
Observability,
[Display(Name = "security")]
Security,
[Display(Name = "apm_agent_android")]
ApmAgentAndroid,
[Display(Name = "apm_agent_ios")]
ApmAgentIos,
[Display(Name = "apm_agent_dotnet")]
ApmAgentDotnet,
[Display(Name = "apm_agent_go")]
ApmAgentGo,
[Display(Name = "apm_agent_java")]
ApmAgentJava,
[Display(Name = "apm_agent_node")]
ApmAgentNode,
[Display(Name = "apm_agent_php")]
ApmAgentPhp,
[Display(Name = "apm_agent_python")]
ApmAgentPython,
[Display(Name = "apm_agent_ruby")]
ApmAgentRuby,
[Display(Name = "apm_agent_rum")]
ApmAgentRum,
[Display(Name = "edot_ios")]
EdotIos,
[Display(Name = "edot_android")]
EdotAndroid,
[Display(Name = "edot_dotnet")]
EdotDotnet,
[Display(Name = "edot_java")]
EdotJava,
[Display(Name = "edot_node")]
EdotNode,
[Display(Name = "edot_php")]
EdotPhp,
[Display(Name = "edot_python")]
EdotPython
}

[YamlSerializable]
public record VersioningSystem
{
public required VersioningSystemId Id { get; init; }

[YamlMember(Alias = "base")]
public required SemVersion Base { get; init; }

[YamlMember(Alias = "current")]
public required SemVersion Current { get; init; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using Elastic.Documentation.Configuration.Serialization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

namespace Elastic.Documentation.Configuration.Versions;

public static class VersionsConfigurationExtensions
{
private static readonly string ResourceName = "Elastic.Documentation.Configuration.versions.yml";

public static IServiceCollection AddVersions(this IServiceCollection services)
{
var assembly = typeof(VersionsConfigurationExtensions).Assembly;
using var stream = assembly.GetManifestResourceStream(ResourceName) ?? throw new FileNotFoundException(ResourceName);
using var reader = new StreamReader(stream);

var deserializer = new StaticDeserializerBuilder(new YamlStaticContext())
.WithNamingConvention(UnderscoredNamingConvention.Instance)
.Build();

var dto = deserializer.Deserialize<VersionsConfigDto>(reader);

var versions = dto.VersioningSystems.ToDictionary(
kvp => ToVersioningSystemId(kvp.Key),
kvp => new VersioningSystem
{
Id = ToVersioningSystemId(kvp.Key),
Base = ToSemVersion(kvp.Value.Base),
Current = ToSemVersion(kvp.Value.Current)
});
var config = new VersionsConfiguration { VersioningSystems = versions };

_ = services.AddSingleton<IOptions<VersionsConfiguration>>(new OptionsWrapper<VersionsConfiguration>(config));

return services;
}

private static VersioningSystemId ToVersioningSystemId(string id)
{
if (!VersioningSystemIdExtensions.TryParse(id, out var versioningSystemId, true, true))
throw new InvalidOperationException($"Could not parse versioning system id {id}");
return versioningSystemId;
}

private static SemVersion ToSemVersion(string semVer)
{
var fullVersion = semVer.Split('.').Length switch
{
0 => semVer + "0.0.0",
1 => semVer + ".0.0",
2 => semVer + ".0",
_ => semVer
};
if (!SemVersion.TryParse(fullVersion, out var version))
throw new InvalidOperationException($"Could not parse version {semVer}");
return version;
}
}

// Private DTOs for deserialization. These match the YAML structure directly.

internal sealed record VersionsConfigDto
{
public Dictionary<string, VersioningSystemDto> VersioningSystems { get; set; } = [];
}

internal sealed record VersioningSystemDto
{
public string Base { get; set; } = string.Empty;
public string Current { get; set; } = string.Empty;
}
Loading
Loading