diff --git a/NuGet.config b/NuGet.config index b2bee8970..be0cb23db 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,4 +1,4 @@ - + @@ -11,7 +11,11 @@ + + + + diff --git a/source/Octopus.Cli/Commands/ImportCommand.cs b/source/Octopus.Cli/Commands/ImportCommand.cs index 7f949da6e..c2bdbc6ca 100644 --- a/source/Octopus.Cli/Commands/ImportCommand.cs +++ b/source/Octopus.Cli/Commands/ImportCommand.cs @@ -1,5 +1,4 @@ -using System; -using log4net; +using log4net; using Octopus.Cli.Importers; using Octopus.Cli.Infrastructure; using Octopus.Cli.Util; diff --git a/source/Octopus.Cli/Exporters/ProjectExporter.cs b/source/Octopus.Cli/Exporters/ProjectExporter.cs index abe615260..fecc8376f 100644 --- a/source/Octopus.Cli/Exporters/ProjectExporter.cs +++ b/source/Octopus.Cli/Exporters/ProjectExporter.cs @@ -29,6 +29,7 @@ protected override void Export(Dictionary parameters) { throw new CommandException("Please specify the name of the project to export using the paramater: --name=XYZ"); } + var projectName = parameters["Name"]; Log.Debug("Finding project: " + projectName); @@ -73,7 +74,6 @@ protected override void Export(Dictionary parameters) throw new CouldNotFindException("deployment process for project",project.Name); Log.Debug("Finding NuGet feed for deployment process..."); - var nugetFeeds = new List(); foreach (var step in deploymentProcess.Steps) { @@ -83,9 +83,15 @@ protected override void Export(Dictionary parameters) if (action.Properties.TryGetValue("Octopus.Action.Package.NuGetFeedId", out nugetFeedId)) { Log.Debug("Finding NuGet feed for step " + step.Name); - var feed = Repository.Feeds.Get(nugetFeedId.Value); + FeedResource feed = null; + if (FeedCustomExpressionHelper.IsRealFeedId(nugetFeedId.Value)) + feed = Repository.Feeds.Get(nugetFeedId.Value); + else + feed = FeedCustomExpressionHelper.CustomExpressionFeedWithId(nugetFeedId.Value); + if (feed == null) throw new CouldNotFindException("NuGet feed for step", step.Name); + if (nugetFeeds.All(f => f.Id != nugetFeedId.Value)) { nugetFeeds.Add(new ReferenceDataItem(feed.Id, feed.Name)); @@ -123,7 +129,6 @@ protected override void Export(Dictionary parameters) { throw new CouldNotFindException("library variable set with Id", libraryVariableSetId); } - libraryVariableSets.Add(new ReferenceDataItem(libraryVariableSet.Id, libraryVariableSet.Name)); } diff --git a/source/Octopus.Cli/Importers/ProjectImporter.cs b/source/Octopus.Cli/Importers/ProjectImporter.cs index 8c2f43c78..80bd1409d 100644 --- a/source/Octopus.Cli/Importers/ProjectImporter.cs +++ b/source/Octopus.Cli/Importers/ProjectImporter.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Security.Permissions; using log4net; using Octopus.Cli.Commands; using Octopus.Cli.Extensions; @@ -37,8 +36,7 @@ class ValidatedImportSettings : BaseValidatedImportSettings public IDictionary Templates { get; set; } public VariableSetResource VariableSet { get; set; } public IEnumerable Channels { get; set; } - public IDictionary ChannelLifecycles { get; set; } - + public IDictionary ChannelLifecycles { get; set; } } public ProjectImporter(IOctopusRepository repository, IOctopusFileSystem fileSystem, ILog log) @@ -59,6 +57,7 @@ protected override bool Validate(Dictionary paramDictionary) { throw new CommandException("Unable to find a lifecycle to assign to this project."); } + Log.DebugFormat("Found lifecycle '{0}'", existingLifecycle.Name); project.LifecycleId = existingLifecycle.Id; } @@ -470,7 +469,6 @@ IEnumerable> ImportProjectChannels(List CheckProjectGroup(ReferenceDataItem projectGroup) { @@ -546,7 +543,12 @@ protected CheckedReferences CheckNuGetFeedsExist(List(); foreach (var nugetFeed in nugetFeeds) { - var feed = Repository.Feeds.FindByName(nugetFeed.Name); + FeedResource feed = null; + if (FeedCustomExpressionHelper.IsRealFeedId(nugetFeed.Id)) + feed = Repository.Feeds.FindByName(nugetFeed.Name); + else + feed = FeedCustomExpressionHelper.CustomExpressionFeedWithId(nugetFeed.Id); + dependencies.Register(nugetFeed.Name, nugetFeed.Id, feed); } return dependencies; diff --git a/source/Octopus.Cli/Octopus.Cli.csproj b/source/Octopus.Cli/Octopus.Cli.csproj index 1b0966a36..7d75337cd 100644 --- a/source/Octopus.Cli/Octopus.Cli.csproj +++ b/source/Octopus.Cli/Octopus.Cli.csproj @@ -121,6 +121,7 @@ + diff --git a/source/Octopus.Cli/Util/FeedCustomExpressionHelper.cs b/source/Octopus.Cli/Util/FeedCustomExpressionHelper.cs new file mode 100644 index 000000000..f1bc7f513 --- /dev/null +++ b/source/Octopus.Cli/Util/FeedCustomExpressionHelper.cs @@ -0,0 +1,40 @@ +using Octopus.Client.Model; +using System; + +namespace Octopus.Cli.Util +{ + /// + /// Helps with situations where feeds use custom expressions Eg. #{MyCustomFeedURL} + /// + public static class FeedCustomExpressionHelper + { + public static string CustomExpressionFeedName = "Custom expression"; + + public static FeedResource CustomExpressionFeedWithId(string id) + { + var feed = new FeedResource() + { + Id = id, + Name = FeedCustomExpressionHelper.CustomExpressionFeedName + }; + return feed; + } + + /// + /// Helps to check for a valid repository-based feed Id. + /// + /// Feeds may have custom expressions as their Id, which may contain Octostache variable syntax #{MyCustomFeedURL}. + /// If you pass a custom expression Id like this to the API, it will resolve to /api/feeds/, return all the feeds, then + /// attempt to cast that response to a FeedResource object and you'll end up getting an empty FeedResource object instead + /// of null. This method helps you detect valid repository feed objects before running into this confusing API scenario. + /// + /// + /// + public static bool IsRealFeedId(string id) + { + if (id.StartsWith("feeds-", StringComparison.OrdinalIgnoreCase)) + return true; + return false; + } + } +}