diff --git a/source/Octo.Tests/Commands/ReleasePlanBuilderTests.cs b/source/Octo.Tests/Commands/ReleasePlanBuilderTests.cs index d4bb29bbbb..68854cc885 100644 --- a/source/Octo.Tests/Commands/ReleasePlanBuilderTests.cs +++ b/source/Octo.Tests/Commands/ReleasePlanBuilderTests.cs @@ -333,10 +333,36 @@ public void VersionControlledProject_WithGitReference_ShouldBeViablePlan() } [Test] - public void VersionControlledProject_ResolvableUsingFeed_ShouldBeViablePlan() + public void VersionControlledProject_ResolvableUsingFeedId_ShouldBeViablePlan() { // arrange gitReference = "main"; + repository.LoadRootDocument().Returns(new RootResource + { + Version = "2022.3.4517" + }); + + projectResource.IsVersionControlled = true; + releaseTemplateResource.Packages.Add(GetReleaseTemplatePackage().WithPackage().IsResolvable()); + packages.Add(new PackageResource { Version = "1.0.0" }); + + // act + var plan = ExecuteBuild(); + + // assert + plan.IsViableReleasePlan().Should().BeTrue(); + } + + [Test] + public void VersionControlledProject_ResolvableUsingFeedName_ShouldBeViablePlan() + { + // arrange + gitReference = "main"; + repository.LoadRootDocument().Returns(new RootResource + { + Version = "2022.2" + }); + projectResource.IsVersionControlled = true; releaseTemplateResource.Packages.Add(GetReleaseTemplatePackage().WithPackage(ResourceBuilderHelpers.KeyedBy.Name).IsResolvable()); packages.Add(new PackageResource { Version = "1.0.0" }); diff --git a/source/Octopus.Cli/Commands/Releases/ReleasePlanBuilder.cs b/source/Octopus.Cli/Commands/Releases/ReleasePlanBuilder.cs index 1280eeb19e..3bfd47b247 100644 --- a/source/Octopus.Cli/Commands/Releases/ReleasePlanBuilder.cs +++ b/source/Octopus.Cli/Commands/Releases/ReleasePlanBuilder.cs @@ -3,7 +3,9 @@ using System.Linq; using System.Threading.Tasks; using Octopus.Cli.Infrastructure; +using Octopus.Cli.Util; using Octopus.Client; +using Octopus.Client.Logging; using Octopus.Client.Model; using Octopus.CommandLine; using Octopus.CommandLine.Commands; @@ -19,12 +21,14 @@ public class ReleasePlanBuilder : IReleasePlanBuilder readonly IPackageVersionResolver versionResolver; readonly IChannelVersionRuleTester versionRuleTester; readonly ICommandOutputProvider commandOutputProvider; + readonly ILogger logger; public ReleasePlanBuilder(ILogger log, IPackageVersionResolver versionResolver, IChannelVersionRuleTester versionRuleTester, ICommandOutputProvider commandOutputProvider) { this.versionResolver = versionResolver; this.versionRuleTester = versionRuleTester; this.commandOutputProvider = commandOutputProvider; + logger = log; } public static string GitReferenceSuppliedForDatabaseProjectErrorMessage(string gitObjectName) @@ -194,14 +198,24 @@ async Task Build(IOctopusAsyncRepository repository, return plan; } - static async Task> LoadFeedsForSteps(IOctopusAsyncRepository repository, ProjectResource project, IEnumerable steps) + async Task> LoadFeedsForSteps(IOctopusAsyncRepository repository, ProjectResource project, IEnumerable steps) { // PackageFeedId can be an id or a name - var allRelevantFeedIdOrName = steps.Select(step => step.PackageFeedId).ToArray(); - var allRelevantFeeds = project.IsVersionControlled - ? (await repository.Feeds.FindByNames(allRelevantFeedIdOrName).ConfigureAwait(false)).ToDictionary(feed => feed.Name) - : (await repository.Feeds.Get(allRelevantFeedIdOrName).ConfigureAwait(false)).ToDictionary(feed => feed.Id); + var allRelevantFeedIds = steps.Select(step => step.PackageFeedId).Distinct().ToArray(); + var isVersionControlled = project.IsVersionControlled; + var useIdsForConfigAsCode = (await repository.LoadRootDocument().ConfigureAwait(false)).UseIdsForConfigAsCode(); + var lookupByName = isVersionControlled && !useIdsForConfigAsCode; + + if (lookupByName) + { + logger.Warning("Using names to reference shared resources from version-controlled projects will be deprecated from 2022.3.4517"); + } + + var allRelevantFeeds = lookupByName + ? (await repository.Feeds.FindByNames(allRelevantFeedIds).ConfigureAwait(false)).ToDictionary(feed => feed.Name) + : (await repository.Feeds.Get(allRelevantFeedIds).ConfigureAwait(false)).ToDictionary(feed => feed.Id); + return allRelevantFeeds; } diff --git a/source/Octopus.Cli/Util/FeatureDetectionExtensions.cs b/source/Octopus.Cli/Util/FeatureDetectionExtensions.cs index acccb2d5db..0e71251ce8 100644 --- a/source/Octopus.Cli/Util/FeatureDetectionExtensions.cs +++ b/source/Octopus.Cli/Util/FeatureDetectionExtensions.cs @@ -42,5 +42,13 @@ public static bool HasProjectDeploymentSettingsSeparation(this RootResource sour !SemanticVersion.TryParse(source.Version, out var octopusServerVersion) || octopusServerVersion >= new SemanticVersion("2021.2"); } + + public static bool UseIdsForConfigAsCode(this RootResource source) + { + // The separation of Projects from DeploymentSettings was exposed from 2021.2 onwards + return source == null || + !SemanticVersion.TryParse(source.Version, out var octopusServerVersion) || + octopusServerVersion >= new SemanticVersion("2022.3.4517"); + } } }