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 @@ -133,7 +133,7 @@ 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(ILoggerFactory logFactory, string repository, string branchOrTag, Product? product)
public ContentSourceMatch Match(ILoggerFactory logFactory, string repository, string branchOrTag, Product? product, bool alreadyPublishing)
{
var logger = logFactory.CreateLogger<ContentSourceMatch>();
var match = new ContentSourceMatch(null, null, null, false);
Expand Down Expand Up @@ -227,22 +227,28 @@ public ContentSourceMatch Match(ILoggerFactory logFactory, string repository, st
// 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 productVersion = versioningSystem.Current;
var anchoredProductVersion = new SemVersion(productVersion.Major, productVersion.Minor, 0);
if (v >= anchoredProductVersion)
if (!alreadyPublishing)
{
logger.LogInformation("Speculative build {Branch} is gte product current '{ProductCurrent}' anchored at {ProductAnchored}", branchOrTag, productVersion, anchoredProductVersion);
match = match with
logger.LogInformation("Current is not using versioned branches and is not publishing to the registry yet, using product information to determine speculative build is needed");
var productVersion = versioningSystem.Current;
var anchoredProductVersion = new SemVersion(productVersion.Major, productVersion.Minor, 0);
if (v >= anchoredProductVersion)
{
Speculative = true
};
logger.LogInformation("Speculative build {Branch} is gte product current '{ProductCurrent}' anchored at {ProductAnchored}", branchOrTag,
productVersion, anchoredProductVersion);
match = match with
{
Speculative = true
};
}
else
logger.LogInformation("NO speculative build {Branch} is lte product current '{ProductCurrent}'", branchOrTag, productVersion);
}
else
logger.LogInformation("NO speculative build {Branch} is lte product current '{ProductCurrent}'", branchOrTag, productVersion);
logger.LogInformation("NO speculative build, repository is not using version branches to publish to documentation and is already in the link registry");
}
else
logger.LogInformation("No versioning system found for {Repository} on {Branch}", repository, branchOrTag);
logger.LogInformation("No versioning system found for {Repository} on {Branch}, can not determine speculative build until repository is specified in docs-builder configuration", repository, branchOrTag);
}

// if we haven't matched anything yet, and the branch is 'main' or 'master' always build
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Elastic.Documentation.Configuration;
using Elastic.Documentation.Configuration.Assembler;
using Elastic.Documentation.Diagnostics;
using Elastic.Documentation.LinkIndex;
using Elastic.Documentation.Services;
using Microsoft.Extensions.Logging;

Expand All @@ -28,7 +29,7 @@ FileSystem fileSystem
/// <para>Will also qualify the branch as being current or next or whether we should build this speculatively</para>
/// <para>e.g., if a new minor branch gets created, we want to build it even if it's not configured in assembler.yml yet</para>
/// </summary>
public async Task<bool> ShouldBuild(IDiagnosticsCollector collector, string? repository, string? branchOrTag)
public async Task<bool> ShouldBuild(IDiagnosticsCollector collector, string? repository, string? branchOrTag, Cancel ctx)
{
var repo = repository ?? githubActionsService.GetInput("repository");
var refName = branchOrTag ?? githubActionsService.GetInput("ref_name");
Expand All @@ -40,9 +41,13 @@ public async Task<bool> ShouldBuild(IDiagnosticsCollector collector, string? rep
throw new ArgumentNullException(nameof(branchOrTag));

// environment does not matter to check the configuration, defaulting to dev
var linkIndexProvider = Aws3LinkIndexReader.CreateAnonymous();
var linkRegistry = await linkIndexProvider.GetRegistry(ctx);
var alreadyPublishing = linkRegistry.Repositories.ContainsKey(repo);
_logger.LogInformation("'{Repository}' publishing to link registry: {PublishState} ", repo, alreadyPublishing);
var assembleContext = new AssembleContext(configuration, configurationContext, "dev", collector, fileSystem, fileSystem, null, null);
var product = assembleContext.ProductsConfiguration.GetProductByRepositoryName(repo);
var matches = assembleContext.Configuration.Match(logFactory, repo, refName, product);
var matches = assembleContext.Configuration.Match(logFactory, repo, refName, product, alreadyPublishing);
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 @@ -48,7 +48,7 @@ public async Task<int> Match([Argument] string? repository = null, [Argument] st
serviceInvoker.AddCommand(service, (repository, branchOrTag),
static async (s, collector, state, ctx) =>
{
_ = await s.ShouldBuild(collector, state.repository, state.branchOrTag);
_ = await s.ShouldBuild(collector, state.repository, state.branchOrTag, ctx);
// ShouldBuild throws an exception on bad args and will return false if it has no matches
// We return true to the service invoker to continue
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public void InvalidRepositoryFormatReturnsNoMatch(string repository)
{
var config = CreateConfiguration();

var result = config.Match(LoggerFactory, repository, "main", null);
var result = config.Match(LoggerFactory, repository, "main", null, false);

result.Should().BeEquivalentTo(NoMatch);
}
Expand All @@ -88,7 +88,7 @@ public void UnknownElasticRepositoryReturnsSpeculativeForIntegrationBranches(str
{
var config = CreateConfiguration();

var result = config.Match(LoggerFactory, "elastic/unknown-repo", branch, null);
var result = config.Match(LoggerFactory, "elastic/unknown-repo", branch, null, false);

result.Should().BeEquivalentTo(Speculative);
}
Expand All @@ -98,7 +98,7 @@ public void UnknownElasticRepositoryReturnsNoMatchForFeatureBranches()
{
var config = CreateConfiguration();

var result = config.Match(LoggerFactory, "elastic/unknown-repo", "feature-branch", null);
var result = config.Match(LoggerFactory, "elastic/unknown-repo", "feature-branch", null, false);

result.Should().BeEquivalentTo(NoMatch);
}
Expand All @@ -111,7 +111,7 @@ public void MatchesCorrectContentSource(string branch, ContentSource expectedSou
{
var config = CreateConfiguration();

var result = config.Match(LoggerFactory, "elastic/test-repo", branch, null);
var result = config.Match(LoggerFactory, "elastic/test-repo", branch, null, false);

// Version branches set Speculative if they're >= current version (8.0)
var isVersionBranch = branch.Contains('.');
Expand All @@ -136,7 +136,7 @@ public void MatchesMultipleContentSourcesWhenBranchMatchesAll()
};
var config = CreateConfiguration(repositories);

var result = config.Match(LoggerFactory, "elastic/test-repo", "main", null);
var result = config.Match(LoggerFactory, "elastic/test-repo", "main", null, false);

result.Should().BeEquivalentTo(new MatchResult(
ContentSource.Current,
Expand All @@ -158,7 +158,7 @@ public void VersionBranchSpeculativeBuildBasedOnCurrentVersion(string branch, st
};
var config = CreateConfiguration(repositories);

var result = config.Match(LoggerFactory, "elastic/test-repo", branch, null);
var result = config.Match(LoggerFactory, "elastic/test-repo", branch, null, false);

result.Speculative.Should().Be(shouldBeSpeculative);
}
Expand All @@ -179,7 +179,7 @@ public void VersionBranchSpeculativeBuildBasedOnProductVersion(string branch, st
var versionParts = productVersion.Split('.');
var product = CreateProduct(new SemVersion(int.Parse(versionParts[0], null), int.Parse(versionParts[1], null), 0));

var result = config.Match(LoggerFactory, "elastic/test-repo", branch, product);
var result = config.Match(LoggerFactory, "elastic/test-repo", branch, product, false);

result.Speculative.Should().Be(shouldBeSpeculative);
}
Expand All @@ -195,7 +195,7 @@ public void FallbackToSpeculativeBuildForMainOrMasterWhenNoMatch(string branch)
};
var config = CreateConfiguration(repositories);

var result = config.Match(LoggerFactory, "elastic/test-repo", branch, null);
var result = config.Match(LoggerFactory, "elastic/test-repo", branch, null, false);

result.Current.Should().BeNull();
result.Next.Should().BeNull();
Expand All @@ -212,7 +212,7 @@ public void NoFallbackToSpeculativeBuildForFeatureBranches()
};
var config = CreateConfiguration(repositories);

var result = config.Match(LoggerFactory, "elastic/test-repo", "feature-branch", null);
var result = config.Match(LoggerFactory, "elastic/test-repo", "feature-branch", null, false);

result.Should().BeEquivalentTo(NoMatch);
}
Expand All @@ -226,7 +226,7 @@ public void DoesNotFallbackToSpeculativeWhenContentSourceMatched()
};
var config = CreateConfiguration(repositories);

var result = config.Match(LoggerFactory, "elastic/test-repo", "main", null);
var result = config.Match(LoggerFactory, "elastic/test-repo", "main", null, false);

result.Current.Should().Be(ContentSource.Current);
}
Expand All @@ -236,7 +236,7 @@ public void HandlesInvalidVersionBranchGracefully()
{
var config = CreateConfiguration();

var result = config.Match(LoggerFactory, "elastic/test-repo", "8.x", null);
var result = config.Match(LoggerFactory, "elastic/test-repo", "8.x", null, false);

result.Should().NotBeNull();
}
Expand All @@ -246,7 +246,7 @@ public void ExtractsRepositoryNameFromFullPath()
{
var config = CreateConfiguration();

var result = config.Match(LoggerFactory, "elastic/test-repo", "8.0", null);
var result = config.Match(LoggerFactory, "elastic/test-repo", "8.0", null, false);

result.Current.Should().Be(ContentSource.Current);
}
Expand All @@ -260,7 +260,7 @@ public void CurrentVersionMatchAlsoSetsSpeculative()
};
var config = CreateConfiguration(repositories);

var result = config.Match(LoggerFactory, "elastic/test-repo", "8.15", null);
var result = config.Match(LoggerFactory, "elastic/test-repo", "8.15", null, false);

result.Current.Should().Be(ContentSource.Current);
result.Speculative.Should().BeTrue();
Expand All @@ -280,7 +280,7 @@ public void VersionBranchSpeculativeBuildWhenGreaterThanOrEqualToAnchoredProduct
var versionParts = productVersion.Split('.');
var product = CreateProduct(new SemVersion(int.Parse(versionParts[0], null), int.Parse(versionParts[1], null), int.Parse(versionParts[2], null)));

var result = config.Match(LoggerFactory, "elastic/test-repo", branch, product);
var result = config.Match(LoggerFactory, "elastic/test-repo", branch, product, false);

result.Speculative.Should().BeTrue();
}
Expand All @@ -299,7 +299,7 @@ public void VersionBranchNoSpeculativeBuildWhenLessThanAnchoredProductVersionAnd
var versionParts = productVersion.Split('.');
var product = CreateProduct(new SemVersion(int.Parse(versionParts[0], null), int.Parse(versionParts[1], null), int.Parse(versionParts[2], null)));

var result = config.Match(LoggerFactory, "elastic/test-repo", branch, product);
var result = config.Match(LoggerFactory, "elastic/test-repo", branch, product, false);

result.Speculative.Should().BeFalse();
}
Expand All @@ -316,7 +316,7 @@ public void VersionBranchSpeculativeBuildWhenMatchesPreviousMinorVersion(string
};
var config = CreateConfiguration(repositories);

var result = config.Match(LoggerFactory, "elastic/test-repo", branch, null);
var result = config.Match(LoggerFactory, "elastic/test-repo", branch, null, false);

result.Speculative.Should().BeTrue();
}
Expand All @@ -336,7 +336,7 @@ public void VersionBranchNoSpeculativeBuildWhenProductVersioningSystemIsNull()
VersioningSystem = null // No versioning system
};

var result = config.Match(LoggerFactory, "elastic/test-repo", "9.0", product);
var result = config.Match(LoggerFactory, "elastic/test-repo", "9.0", product, false);

result.Speculative.Should().BeFalse();
}
Expand All @@ -350,7 +350,7 @@ public void VersionBranchNoSpeculativeBuildWhenProductIsNull()
};
var config = CreateConfiguration(repositories);

var result = config.Match(LoggerFactory, "elastic/test-repo", "9.0", null);
var result = config.Match(LoggerFactory, "elastic/test-repo", "9.0", null, false);

result.Speculative.Should().BeFalse();
}
Expand All @@ -369,7 +369,7 @@ public void VersionBranchAnchorsProductVersionToMinorZero(string branch, string
var versionParts = productVersion.Split('.');
var product = CreateProduct(new SemVersion(int.Parse(versionParts[0], null), int.Parse(versionParts[1], null), int.Parse(versionParts[2], null)));

var result = config.Match(LoggerFactory, "elastic/test-repo", branch, product);
var result = config.Match(LoggerFactory, "elastic/test-repo", branch, product, false);

// Should match because branch 9.0 >= anchored product version 9.0.0
result.Speculative.Should().BeTrue();
Expand All @@ -386,11 +386,85 @@ public void VersionBranchPreviousMinorCalculationHandlesEdgeCases(string branch,
};
var config = CreateConfiguration(repositories);

var result = config.Match(LoggerFactory, "elastic/test-repo", branch, null);
var result = config.Match(LoggerFactory, "elastic/test-repo", branch, null, false);

// 8.0 should match previous minor of 8.1 (which is 8.0)
// 7.17 should NOT match previous minor of 8.0 (which is Math.Max(8-1, 0).0 = 7.0, not 7.17)
var expectedSpeculative = branch == "8.0" && currentVersion == "8.1";
result.Speculative.Should().Be(expectedSpeculative);
}

[Theory]
[InlineData("9.0", "9.0.0")] // Matches anchored product version
[InlineData("9.1", "9.0.0")] // Greater than anchored product version
[InlineData("9.5", "9.0.0")] // Much greater than anchored product version
public void AlreadyPublishingTruePreventSpeculativeBuildForVersionBranch(string branch, string productVersion)
{
var repositories = new Dictionary<string, Repository>
{
["test-repo"] = CreateRepository(current: "main", next: "main", edge: "main")
};
var config = CreateConfiguration(repositories);
var versionParts = productVersion.Split('.');
var product = CreateProduct(new SemVersion(int.Parse(versionParts[0], null), int.Parse(versionParts[1], null), int.Parse(versionParts[2], null)));

var result = config.Match(LoggerFactory, "elastic/test-repo", branch, product, true);

result.Speculative.Should().BeFalse();
}

[Theory]
[InlineData("9.0", "9.0.0")] // Matches anchored product version
[InlineData("9.1", "9.0.0")] // Greater than anchored product version
[InlineData("9.5", "9.0.0")] // Much greater than anchored product version
public void AlreadyPublishingFalseAllowsSpeculativeBuildForVersionBranch(string branch, string productVersion)
{
var repositories = new Dictionary<string, Repository>
{
["test-repo"] = CreateRepository(current: "main", next: "main", edge: "main")
};
var config = CreateConfiguration(repositories);
var versionParts = productVersion.Split('.');
var product = CreateProduct(new SemVersion(int.Parse(versionParts[0], null), int.Parse(versionParts[1], null), int.Parse(versionParts[2], null)));

var result = config.Match(LoggerFactory, "elastic/test-repo", branch, product, false);

result.Speculative.Should().BeTrue();
}

[Fact]
public void AlreadyPublishingOnlyAffectsVersionBranchesWithoutVersionedCurrent()
{
var repositories = new Dictionary<string, Repository>
{
["test-repo"] = CreateRepository(current: "8.15", next: "main", edge: "main")
};
var config = CreateConfiguration(repositories);

// When current is a version branch, alreadyPublishing should have no effect
var resultTrue = config.Match(LoggerFactory, "elastic/test-repo", "8.15", null, true);
var resultFalse = config.Match(LoggerFactory, "elastic/test-repo", "8.15", null, false);

resultTrue.Speculative.Should().BeTrue();
resultFalse.Speculative.Should().BeTrue();
}

[Theory]
[InlineData("main")]
[InlineData("master")]
public void AlreadyPublishingDoesNotAffectNonVersionBranchesWithFallback(string branch)
{
var repositories = new Dictionary<string, Repository>
{
["test-repo"] = CreateRepository(current: "8.0", next: "8.1", edge: "8.2")
};
var config = CreateConfiguration(repositories);

// alreadyPublishing should not affect main/master branches when they fall back to speculative
var resultTrue = config.Match(LoggerFactory, "elastic/test-repo", branch, null, true);
var resultFalse = config.Match(LoggerFactory, "elastic/test-repo", branch, null, false);

resultTrue.Speculative.Should().BeTrue();
resultFalse.Speculative.Should().BeTrue();
}
}
Loading