Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions docs/_docset.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
project: 'doc-builder'
max_toc_depth: 2
# indicates this documentation set is not linkable by assembler.
Expand Down Expand Up @@ -100,6 +100,7 @@
- file: sidebars.md
- file: stepper.md
- file: substitutions.md
- file: version-variables.md
- file: sundries.md
- file: tables.md
- file: tabs.md
Expand Down
60 changes: 60 additions & 0 deletions docs/syntax/version-variables.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Version Variables

Version are exposed during build using the `{{versions.VERSIONING_SCHEME}}` variable.

For example `stack` versioning variables are exposed as `{{versions.stack}}`.

## Specialized Suffixes.

Besides the current version, the following suffixes are available:

| Version substitution | result | purpose |
|--------------------------------------|-----------------------------------|-----------------------------------------|
| `{{versions.stack}}` | {{version.stack}} | Current version |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in most cases I think we want the base usage to be the major_minor version. might want to make that the "core" and make a versions.stack.patch or something instead

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be formatted e.g 9.0.0 = 9.0 and 9.0.1 would be 9.0.1 ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about that. I think so though?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that the installation instructions would need the full V.R.M but that would not be the general case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in most cases I think we want the base usage to be the major_minor version.

I agree that the installation instructions would need the full V.R.M but that would not be the general case.

Installation instructions and download links are probably the most important use cases for me. 😬

Should it be formatted e.g 9.0.0 = 9.0 and 9.0.1 would be 9.0.1 ?

I think I'd prefer it to be major-minor-patch if only for consistency.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also think the path of least surprise is to have the base be full V.R.M

  • {{versions.stack}}
  • {{versions.stack.base}}
  • {{versions.stack.next_major}}
  • {{versions.stack.next_minor}}

Where the V.R and V.x and V variants can all be obtained using a *.suffix.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I opened #1563 as a completely new approach that allows a more generic approach to reformatting variables.

In that PR we only expose:

  • {{versions.stack}}
  • {{versions.stack.base}}

With operators to get a specific format e.g

  • {{versions.stack | M.x }}

| `{{versions.stack.major_minor}}` | {{version.stack.major_minor}} | Current `MAJOR.MINOR` |
| `{{versions.stack.major_x}}` | {{version.stack.major_x}} | Current `MAJOR.X` |
| `{{versions.stack.major_component}}` | {{version.stack.major_component}} | Current major component |
| `{{versions.stack.next_major}}` | {{version.stack.next_major}} | The next major version |
| `{{versions.stack.next_minor}}` | {{version.stack.next_minor}} | The next minor version |
| `{{versions.stack.base}}` | {{version.stack.base}} | The first version on the new doc system |
Copy link
Contributor

@shainaraskas shainaraskas Jul 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would probably drop the patch segment from these (@lcawl + @colleenmcginnis should confirm they're not needed)

Copy link
Contributor

@colleenmcginnis colleenmcginnis Jul 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be too preoccupied with consistency, but I'd rather see a consistent pattern across current/next versions. Something like:

current next format
version.stack version.stack.next #.#.#
version.stack.major_minor version.stack.next_major_minor #.#
version.stack.major_x version.stack.next_major_x #.x
version.stack.major_component version.stack.next_major_component #

I don't have a strong opinion about versions.stack.base.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

version.stack would be version.stack.current but I see your point.

I think {{version.stack.current}} might be too verbose though.

See also my comment on bases here #1560 (comment)



## Available versioning schemes.

This is dictated by the [version.yml](https://github.com/elastic/docs-builder/blob/main/src/Elastic.Documentation.Configuration/versions.yml) configuration file

* `stack`
* `ece`
* `ech`
* `eck`
* `ess`
* `self`
* `ecctl`
* `curator`
* `security`
* `apm_agent_android`
* `apm_agent_ios`
* `apm_agent_dotnet`
* `apm_agent_go`
* `apm_agent_java`
* `apm_agent_node`
* `apm_agent_php`
* `apm_agent_python`
* `apm_agent_ruby`
* `apm_agent_rum`
* `edot_ios`
* `edot_android`
* `edot_dotnet`
* `edot_java`
* `edot_node`
* `edot_php`
* `edot_python`
* `edot_cf_aws`
* `edot_collector`

The following are available but should not be used. These map to serverless projects and have a fixed high version number.

* `all`
* `serverless`
* `elasticsearch`
* `observability`
2 changes: 1 addition & 1 deletion src/Elastic.Documentation.Configuration/BuildContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public BuildContext(
DocumentationSourceDirectory = ConfigurationPath.Directory!;

Git = gitCheckoutInformation ?? GitCheckoutInformation.Create(DocumentationCheckoutDirectory, ReadFileSystem);
Configuration = new ConfigurationFile(this);
Configuration = new ConfigurationFile(this, VersionsConfig);
GoogleTagManager = new GoogleTagManagerConfiguration
{
Enabled = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using DotNet.Globbing;
using Elastic.Documentation.Configuration.Suggestions;
using Elastic.Documentation.Configuration.TableOfContents;
using Elastic.Documentation.Configuration.Versions;
using Elastic.Documentation.Links;
using Elastic.Documentation.Navigation;
using YamlDotNet.RepresentationModel;
Expand Down Expand Up @@ -61,7 +62,7 @@ public record ConfigurationFile : ITableOfContentsScope
Project is not null
&& Project.Equals("Elastic documentation", StringComparison.OrdinalIgnoreCase);

public ConfigurationFile(IDocumentationContext context)
public ConfigurationFile(IDocumentationContext context, VersionsConfiguration versionsConfig)
{
_context = context;
ScopeDirectory = context.ConfigurationPath.Directory!;
Expand Down Expand Up @@ -159,6 +160,32 @@ public ConfigurationFile(IDocumentationContext context)
}
}

foreach (var (id, system) in versionsConfig.VersioningSystems)
{
var name = id.ToStringFast(true);
var current = system.Current;
var key = $"version.{name}";
_substitutions[key] = system.Current;

key = $"version.{name}.base";
_substitutions[key] = system.Base;

key = $"version.{name}.major_minor";
_substitutions[key] = $"{current.Major:N0}.{current.Minor:N0}";

key = $"version.{name}.major_x";
_substitutions[key] = $"{current.Major:N0}.x";

key = $"version.{name}.major_component";
_substitutions[key] = $"{current.Major:N0}";

key = $"version.{name}.next_minor";
_substitutions[key] = new SemVersion(current.Major, current.Minor + 1, current.Patch, current.Prerelease, current.Metadata);

key = $"version.{name}.next_major";
_substitutions[key] = new SemVersion(current.Major + 1, current.Minor, current.Patch, current.Prerelease, current.Metadata);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these actually required?

I'm afraid that these variables will cause confusion and will output an unexpected version if used wrongly by the user.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't think of a use case where you want to have a next version that changes over time.

Can you explain the use case you were thinking of?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lcawl and wider @elastic/docs-tech-leads can you confirm whether we have a use-case for next major/minor as variables?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also keen to hear thoughts on {{versions.*}} vs {{version.*}} :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are no longer exposed directly but can be obtained through variable mutation operators. See #1563

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sticking with {{version.*}} for now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per my comment here: #1560 (comment) next major and minor are not exposed through variables but can be obtained using variable mutations.

}

var toc = new TableOfContentsConfiguration(this, sourceFile, ScopeDirectory, _context, 0, "");
TableOfContents = toc.TableOfContents;
Files = toc.Files;
Expand Down
6 changes: 3 additions & 3 deletions src/Elastic.Documentation.Configuration/Versions/Version.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ public enum VersioningSystemId
[Display(Name = "serverless")]
Serverless,
[Display(Name = "elasticsearch")]
Elasticsearch,
ElasticsearchProject,
[Display(Name = "observability")]
Observability,
ObservabilityProject,
[Display(Name = "security")]
Security,
SecurityProject,
[Display(Name = "apm_agent_android")]
ApmAgentAndroid,
[Display(Name = "apm_agent_ios")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
@RenderProduct(
"Serverless Elasticsearch",
"Serverless Elasticsearch projects",
VersioningSystemId.Elasticsearch,
VersioningSystemId.ElasticsearchProject,
appliesTo.Serverless.Elasticsearch
)
}
Expand All @@ -86,7 +86,7 @@
@RenderProduct(
"Serverless Observability",
"Serverless Observability projects",
VersioningSystemId.Observability,
VersioningSystemId.ObservabilityProject,
appliesTo.Serverless.Observability
)
}
Expand All @@ -96,7 +96,7 @@
@RenderProduct(
"Serverless Security",
"Serverless Security projects",
VersioningSystemId.Security,
VersioningSystemId.SecurityProject,
appliesTo.Serverless.Security
)
}
Expand All @@ -112,127 +112,106 @@
if (pa.Ecctl is not null)
{
@RenderProduct("ECCTL", "Elastic Cloud Control", VersioningSystemId.Ecctl, pa.Ecctl)
;
}

if (pa.Curator is not null)
{
@RenderProduct("Curator", "Curator", VersioningSystemId.Curator, pa.Curator)
;
}

if (pa.ApmAgentAndroid is not null)
{
@RenderProduct("APM Agent Android", "Application Performance Monitoring Agent for Android", VersioningSystemId.ApmAgentAndroid, pa.ApmAgentAndroid)
;
}

if (pa.ApmAgentDotnet is not null)
{
@RenderProduct("APM Agent .NET", "Application Performance Monitoring Agent for .NET", VersioningSystemId.ApmAgentDotnet, pa.ApmAgentDotnet)
;
}

if (pa.ApmAgentGo is not null)
{
@RenderProduct("APM Agent Go", "Application Performance Monitoring Agent for Go", VersioningSystemId.ApmAgentGo, pa.ApmAgentGo)
;
}

if (pa.ApmAgentIos is not null)
{
@RenderProduct("APM Agent iOS", "Application Performance Monitoring Agent for iOS", VersioningSystemId.ApmAgentIos, pa.ApmAgentIos)
;
}

if (pa.ApmAgentJava is not null)
{
@RenderProduct("APM Agent Java", "Application Performance Monitoring Agent for Java", VersioningSystemId.ApmAgentJava, pa.ApmAgentJava)
;
}

if (pa.ApmAgentNode is not null)
{
@RenderProduct("APM Agent Node.js", "Application Performance Monitoring Agent for Node.js", VersioningSystemId.ApmAgentNode, pa.ApmAgentNode)
;
}

if (pa.ApmAgentPhp is not null)
{
@RenderProduct("APM Agent PHP", "Application Performance Monitoring Agent for PHP", VersioningSystemId.ApmAgentPhp, pa.ApmAgentPhp)
;
}

if (pa.ApmAgentPython is not null)
{
@RenderProduct("APM Agent Python", "Application Performance Monitoring Agent for Python", VersioningSystemId.ApmAgentPython, pa.ApmAgentPython)
;
}

if (pa.ApmAgentRuby is not null)
{
@RenderProduct("APM Agent Ruby", "Application Performance Monitoring Agent for Ruby", VersioningSystemId.ApmAgentRuby, pa.ApmAgentRuby)
;
}

if (pa.ApmAgentRum is not null)
{
@RenderProduct("APM Agent RUM", "Application Performance Monitoring Agent for Real User Monitoring", VersioningSystemId.ApmAgentRum, pa.ApmAgentRum)
;
}

if (pa.EdotIos is not null)
{
@RenderProduct("EDOT iOS", "Elastic Distribution of OpenTelemetry iOS", VersioningSystemId.EdotIos, pa.EdotIos)
;
}

if (pa.EdotAndroid is not null)
{
@RenderProduct("EDOT Android", "Elastic Distribution of OpenTelemetry Android", VersioningSystemId.EdotAndroid, pa.EdotAndroid)
;
}

if (pa.EdotDotnet is not null)
{
@RenderProduct("EDOT .NET", "Elastic Distribution of OpenTelemetry .NET", VersioningSystemId.EdotDotnet, pa.EdotDotnet)
;
}

if (pa.EdotJava is not null)
{
@RenderProduct("EDOT Java", "Elastic Distribution of OpenTelemetry Java", VersioningSystemId.EdotJava, pa.EdotJava)
;
}

if (pa.EdotNode is not null)
{
@RenderProduct("EDOT Node.js", "Elastic Distribution of OpenTelemetry Node.js", VersioningSystemId.EdotNode, pa.EdotNode)
;
}

if (pa.EdotPhp is not null)
{
@RenderProduct("EDOT PHP", "Elastic Distribution of OpenTelemetry PHP", VersioningSystemId.ApmAgentPhp, pa.EdotPhp)
;
}

if (pa.EdotPython is not null)
{
@RenderProduct("EDOT Python", "Elastic Distribution of OpenTelemetry Python", VersioningSystemId.EdotPython, pa.EdotPython)
;
}

if (pa.EdotCfAws is not null)
{
@RenderProduct("EDOT CF AWS", "Elastic Distribution of OpenTelemetry Cloud Forwarder for AWS", VersioningSystemId.EdotCfAws, pa.EdotCfAws)
;
}

if (pa.EdotCollector is not null)
{
@RenderProduct("EDOT Collector", "Elastic Distribution of OpenTelemetry Collector", VersioningSystemId.EdotCollector, pa.EdotCollector)
;
}
}

Expand Down
12 changes: 6 additions & 6 deletions tests/authoring/Framework/Setup.fs
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,9 @@ type Setup =
Base = SemVersion(8, 0, 0)
)
)
versioningSystems.Add(VersioningSystemId.Elasticsearch,
versioningSystems.Add(VersioningSystemId.ElasticsearchProject,
VersioningSystem(
Id = VersioningSystemId.Elasticsearch,
Id = VersioningSystemId.ElasticsearchProject,
Current = SemVersion(8, 0, 0),
Base = SemVersion(8, 0, 0)
)
Expand All @@ -188,16 +188,16 @@ type Setup =
Base = SemVersion(8, 0, 0)
)
)
versioningSystems.Add(VersioningSystemId.Observability,
versioningSystems.Add(VersioningSystemId.ObservabilityProject,
VersioningSystem(
Id = VersioningSystemId.Observability,
Id = VersioningSystemId.ObservabilityProject,
Current = SemVersion(8, 0, 0),
Base = SemVersion(8, 0, 0)
)
)
versioningSystems.Add(VersioningSystemId.Security,
versioningSystems.Add(VersioningSystemId.SecurityProject,
VersioningSystem(
Id = VersioningSystemId.Security,
Id = VersioningSystemId.SecurityProject,
Current = SemVersion(8, 0, 0),
Base = SemVersion(8, 0, 0)
)
Expand Down
Loading