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
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
// See the LICENSE file in the project root for more information

using System.Text.RegularExpressions;
using Elastic.Documentation.Configuration.Products;
using Elastic.Documentation.Extensions;
using Microsoft.Extensions.Logging;
using YamlDotNet.Serialization;
using YamlStaticContext = Elastic.Documentation.Configuration.Serialization.YamlStaticContext;

namespace Elastic.Documentation.Configuration.Assembler;

Expand Down Expand Up @@ -132,112 +133,110 @@ private static TRepository RepositoryDefaults<TRepository>(TRepository r, string

/// Returns whether the <paramref name="branchOrTag"/> is configured as an integration branch or tag for the given
/// <paramref name="repository"/>.
public ContentSourceMatch Match(string repository, string branchOrTag)
public ContentSourceMatch Match(ILoggerFactory logFactory, string repository, string branchOrTag, Product? product)
{
var logger = logFactory.CreateLogger<ContentSourceMatch>();
var match = new ContentSourceMatch(null, null, null, false);
var tokens = repository.Split('/');
var repositoryName = tokens.Last();
var owner = tokens.First();
var isVersionBranch = ContentSourceRegex.MatchVersionBranch().IsMatch(branchOrTag);

if (tokens.Length < 2 || owner != "elastic")
return match;

if (ReferenceRepositories.TryGetValue(repositoryName, out var r))
{
var current = r.GetBranch(ContentSource.Current);
var next = r.GetBranch(ContentSource.Next);
var edge = r.GetBranch(ContentSource.Edge);
var isVersionBranch = ContentSourceRegex.MatchVersionBranch().IsMatch(branchOrTag);
if (current == branchOrTag)
{
match = match with
{
Current = ContentSource.Current
};
}

if (next == branchOrTag)
{
match = match with
{
Next = ContentSource.Next
};
}

if (edge == branchOrTag)
{
match = match with
{
Edge = ContentSource.Edge
};
}

if (isVersionBranch && SemVersion.TryParse(branchOrTag + ".0", out var v))
{
// if the current branch is a version, only speculatively match if branch is actually a new version
if (SemVersion.TryParse(current + ".0", out var currentVersion))
{
if (v >= currentVersion)
{
match = match with
{
Speculative = true
};
}
}
// assume we are newly onboarding the repository to current/next
else
{
match = match with
{
Speculative = true
};
}
}

logger.LogInformation("Repository {Repository} is not a valid elastic repository but {Owner}", repository, owner);
return match;
}

if (repositoryName != NarrativeRepository.RepositoryName)
// Check for new repositories
if (!AvailableRepositories.TryGetValue(repositoryName, out var r))
{
logger.LogInformation("Repository {Repository} has not yet been onboarded into assembler.yml", repository);
// this is an unknown new elastic repository
var isVersionBranch = ContentSourceRegex.MatchVersionBranch().IsMatch(branchOrTag);
if (isVersionBranch || branchOrTag == "main" || branchOrTag == "master")
{
logger.LogInformation("Speculatively building {Repository} since it looks like an integration branch", repository);
return match with
{
Speculative = true
};
}
logger.LogInformation("{Repository} on '{Branch}' does not look like it needs a speculative build", repository, branchOrTag);
return match;
}

if (Narrative.GetBranch(ContentSource.Current) == branchOrTag)
var current = r.GetBranch(ContentSource.Current);
var next = r.GetBranch(ContentSource.Next);
var edge = r.GetBranch(ContentSource.Edge);
logger.LogInformation("Active content-sources for {Repository}. current: {Current}, next: {Next}, edge: {Edge}' ", repository, current, next, edge);
if (current == branchOrTag)
{
logger.LogInformation("Content-Source current: {Current} matches: {Branch}", current, branchOrTag);
match = match with
{
Current = ContentSource.Current
};
}

if (Narrative.GetBranch(ContentSource.Next) == branchOrTag)
if (next == branchOrTag)
{
logger.LogInformation("Content-Source next: {Next} matches: {Branch}", next, branchOrTag);
match = match with
{
Next = ContentSource.Next
};
}

if (Narrative.GetBranch(ContentSource.Edge) == branchOrTag)
if (edge == branchOrTag)
{
logger.LogInformation("Content-Source edge: {Edge} matches: {Branch}", edge, branchOrTag);
match = match with
{
Edge = ContentSource.Edge
};
}

// check version branches
if (isVersionBranch && SemVersion.TryParse(branchOrTag + ".0", out var v))
{
logger.LogInformation("Branch or tag {Branch} is a versioned branch", branchOrTag);
// if the current branch is a version, only speculatively match if branch is actually a new version
if (SemVersion.TryParse(current + ".0", out var currentVersion))
{
logger.LogInformation("Current is already using versioned branches {Current}", currentVersion);
if (v >= currentVersion)
{
logger.LogInformation("Speculative build because {Branch} is gte current {Current}", branchOrTag, currentVersion);
match = match with
{
Speculative = true
};
}
else
logger.LogInformation("NO speculative build because {Branch} is lt {Current}", branchOrTag, currentVersion);
}
// assume we are newly onboarding the repository to current/next
else if (product?.VersioningSystem is { } versioningSystem)
{
logger.LogInformation("Current is not using versioned branches checking product info");
var productCurrentVersion = versioningSystem.Current;
if (v >= productCurrentVersion)
{
logger.LogInformation("Speculative build {Branch} is gte product current '{ProductCurrent}'", branchOrTag, productCurrentVersion);
match = match with
{
Speculative = true
};
}
else
logger.LogInformation("NO speculative build {Branch} is lte product current '{ProductCurrent}'", branchOrTag, productCurrentVersion);
}
else
logger.LogInformation("No versioning system found for {Repository} on {Branch}", repository, branchOrTag);
}

// if we haven't matched anything yet, and the branch is 'main' or 'master' always build
if (match is { Current: null, Next: null, Edge: null, Speculative: false }
&& branchOrTag is "main" or "master")
if (match is { Current: null, Next: null, Edge: null, Speculative: false } && branchOrTag is "main" or "master")
{
return match with
{
Expand Down
11 changes: 11 additions & 0 deletions src/Elastic.Documentation.Configuration/Products/Product.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,17 @@ namespace Elastic.Documentation.Configuration.Products;
public record ProductsConfiguration
{
public required FrozenDictionary<string, Product> Products { get; init; }


public Product? GetProductByRepositoryName(string repository)
{
var tokens = repository.Split('/');
var repositoryName = tokens.Last();
if (Products.TryGetValue(repositoryName, out var product))
return product;
var match = Products.Values.SingleOrDefault(p => p.Repository is not null && p.Repository.Equals(repositoryName, StringComparison.OrdinalIgnoreCase));
return match;
}
}

[YamlSerializable]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ public async Task<bool> ShouldBuild(IDiagnosticsCollector collector, string? rep

// environment does not matter to check the configuration, defaulting to dev
var assembleContext = new AssembleContext(configuration, configurationContext, "dev", collector, fileSystem, fileSystem, null, null);
var matches = assembleContext.Configuration.Match(repo, refName);
var product = assembleContext.ProductsConfiguration.GetProductByRepositoryName(repo);
var matches = assembleContext.Configuration.Match(logFactory, repo, refName, product);
if (matches is { Current: null, Next: null, Edge: null, Speculative: false })
{
_logger.LogInformation("'{Repository}' '{BranchOrTag}' combination not found in configuration.", repo, refName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public async Task<int> InvokeAsync(Cancel ctx)
if (!success && task.Strict && collector.Errors + collector.Warnings == 0)
collector.EmitGlobalError($"Service {task.ServiceName} registered as strict but returned false without emitting errors or warnings ");
if (!success && !task.Strict && collector.Errors == 0)
collector.EmitGlobalError($"Service {task.ServiceName} but returned false without emitting errors");
collector.EmitGlobalError($"Service {task.ServiceName} returned false without emitting errors");
}
catch (Exception ex)
{
Expand Down
Loading