예제 #1
0
        public async Task TestBuildNugetSources_Source_Uri_Is_Null(NuGetProtocolVersion protocolVersion)
        {
            await using var nugetTempDirectory = new DisposableDirectory(_baseFixture.WorkingDirectory, _fileSystem);

            var snapNugetFeed = new SnapNugetFeed
            {
                Name            = "nuget.org",
                ProtocolVersion = protocolVersion,
                Source          = null
            };

            var snapChannel = new SnapChannel
            {
                Name       = "test",
                PushFeed   = snapNugetFeed,
                UpdateFeed = snapNugetFeed
            };

            var snapApp = new SnapApp
            {
                Channels = new List <SnapChannel> {
                    snapChannel
                }
            };

            var nugetPackageSources = snapApp.BuildNugetSources(nugetTempDirectory);

            Assert.Empty(nugetPackageSources);
        }
예제 #2
0
        static Task PushPackageAsync([NotNull] INugetService nugetService, [NotNull] ISnapFilesystem filesystem,
                                     [NotNull] IDistributedMutex distributedMutex, [NotNull] INuGetPackageSources nugetSources,
                                     [NotNull] PackageSource packageSource, SnapChannel channel, [NotNull] string packageAbsolutePath,
                                     CancellationToken cancellationToken,
                                     [NotNull] ILog logger)
        {
            if (nugetService == null)
            {
                throw new ArgumentNullException(nameof(nugetService));
            }
            if (filesystem == null)
            {
                throw new ArgumentNullException(nameof(filesystem));
            }
            if (distributedMutex == null)
            {
                throw new ArgumentNullException(nameof(distributedMutex));
            }
            if (nugetSources == null)
            {
                throw new ArgumentNullException(nameof(nugetSources));
            }
            if (packageSource == null)
            {
                throw new ArgumentNullException(nameof(packageSource));
            }
            if (packageAbsolutePath == null)
            {
                throw new ArgumentNullException(nameof(packageAbsolutePath));
            }
            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            if (!filesystem.FileExists(packageAbsolutePath))
            {
                throw new FileNotFoundException(packageAbsolutePath);
            }

            var packageName = filesystem.PathGetFileName(packageAbsolutePath);

            return(SnapUtility.RetryAsync(async() =>
            {
                if (!distributedMutex.Acquired)
                {
                    throw new Exception("Distributed mutex has expired. This is most likely due to intermittent internet connection issues " +
                                        "or another user is attempting to publish a new version. Please retry pack operation.");
                }

                logger.Info($"Pushing {packageName} to channel {channel.Name} using package source {packageSource.Name}");
                var pushStopwatch = new Stopwatch();
                pushStopwatch.Restart();
                await nugetService.PushAsync(packageAbsolutePath, nugetSources, packageSource, null, cancellationToken: cancellationToken);
                logger.Info($"Pushed {packageName} to channel {channel.Name} using package source {packageSource.Name} in {pushStopwatch.Elapsed.TotalSeconds:0.0}s.");
            }));
        }
예제 #3
0
        public async Task TestBuildSnapApp_Ignore_Non_Existant_Feeds()
        {
            await using var nugetTempDirectory = new DisposableDirectory(_baseFixture.WorkingDirectory, _fileSystem);

            var testChannel = new SnapChannel
            {
                Name     = "test",
                PushFeed = new SnapNugetFeed {
                    Name = Guid.NewGuid().ToString("N")
                },
                UpdateFeed = new SnapNugetFeed {
                    Name = Guid.NewGuid().ToString("N")
                },
                Current = true
            };

            var snapAppBefore = new SnapApp
            {
                Id           = "demoapp",
                SuperVisorId = Guid.NewGuid().ToString(),
                Version      = new SemanticVersion(1, 0, 0),
                Channels     = new List <SnapChannel>
                {
                    testChannel
                },
                Target = new SnapTarget
                {
                    Os               = OSPlatform.Windows,
                    Framework        = "netcoreapp2.1",
                    Rid              = "win-x64",
                    PersistentAssets = new List <string>
                    {
                        "subdirectory",
                        "myjsonfile.json"
                    }
                }
            };

            var snapApps = new SnapApps(snapAppBefore);

            var snapAppAfter = snapApps.BuildSnapApp(snapAppBefore.Id, snapAppBefore.Target.Rid,
                                                     snapAppBefore.BuildNugetSources(nugetTempDirectory), _fileSystem,
                                                     false, false);

            Assert.NotNull(snapAppAfter);
            Assert.Single(snapAppAfter.Channels.Select(x => x.UpdateFeed is {}));
예제 #4
0
        public void TestIsValidChannelName(string channelName, bool isValid)
        {
            var channel = new SnapChannel
            {
                Name    = channelName,
                Current = true
            };

            var snapApp = new SnapApp
            {
                Id       = channelName,
                Channels = new List <SnapChannel>
                {
                    channel
                }
            };

            Assert.Equal(isValid, snapApp.IsValidChannelName());
        }
예제 #5
0
        public SnapApp BuildSnapApp(string id = "demoapp", bool isGenesis = false, string rid = null, OSPlatform osPlatform = default)
        {
            var pushFeed = new SnapNugetFeed
            {
                Name            = "nuget.org",
                Source          = new Uri(NuGetConstants.V3FeedUrl),
                ProtocolVersion = NuGetProtocolVersion.V3,
                ApiKey          = "myapikey"
            };

            var updateFeedNuget = new SnapNugetFeed
            {
                Name            = "nuget.org",
                Source          = new Uri(NuGetConstants.V3FeedUrl),
                ProtocolVersion = NuGetProtocolVersion.V3,
                Username        = "******",
                Password        = "******"
            };

            var updateFeedHttp = new SnapHttpFeed
            {
                Source = new Uri("https://mydynamicupdatefeed.com")
            };

            var testChannel = new SnapChannel
            {
                Name       = "test",
                PushFeed   = pushFeed,
                UpdateFeed = updateFeedNuget,
                Current    = true
            };

            var stagingChannel = new SnapChannel
            {
                Name       = "staging",
                PushFeed   = pushFeed,
                UpdateFeed = updateFeedHttp
            };

            var productionChannel = new SnapChannel
            {
                Name       = "production",
                PushFeed   = pushFeed,
                UpdateFeed = updateFeedNuget
            };

            if (osPlatform == default)
            {
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    osPlatform = OSPlatform.Windows;
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    osPlatform = OSPlatform.Linux;
                }
            }

            if (osPlatform != OSPlatform.Windows && osPlatform != OSPlatform.Linux)
            {
                throw new NotSupportedException($"Unsupported OS platform: {osPlatform}");
            }

            var snapApp = new SnapApp
            {
                Id           = id,
                SuperVisorId = Guid.NewGuid().ToString(),
                Version      = new SemanticVersion(1, 0, 0),
                IsGenesis    = isGenesis,
                IsFull       = isGenesis,
                Channels     = new List <SnapChannel>
                {
                    testChannel,
                    stagingChannel,
                    productionChannel
                },
                Target = new SnapTarget
                {
                    Os        = osPlatform,
                    Framework = "netcoreapp2.1",
                    Rid       = rid ?? "win-x64",
                    Shortcuts = new List <SnapShortcutLocation>
                    {
                        SnapShortcutLocation.Desktop,
                        SnapShortcutLocation.Startup,
                        SnapShortcutLocation.StartMenu
                    },
                    PersistentAssets = new List <string>
                    {
                        "application.json"
                    }
                }
            };

            return(snapApp);
        }
예제 #6
0
        static async Task PushPackagesAsync([NotNull] PackOptions packOptions, [NotNull] ILog logger, [NotNull] ISnapFilesystem filesystem,
                                            [NotNull] INugetService nugetService, [NotNull] ISnapPackageManager snapPackageManager, [NotNull] IDistributedMutex distributedMutex, [NotNull] SnapAppsReleases snapAppsReleases,
                                            [NotNull] SnapApp snapApp, [NotNull] SnapChannel snapChannel,
                                            [NotNull] List <string> packages, CancellationToken cancellationToken)
        {
            if (packOptions == null)
            {
                throw new ArgumentNullException(nameof(packOptions));
            }
            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }
            if (filesystem == null)
            {
                throw new ArgumentNullException(nameof(filesystem));
            }
            if (nugetService == null)
            {
                throw new ArgumentNullException(nameof(nugetService));
            }
            if (snapPackageManager == null)
            {
                throw new ArgumentNullException(nameof(snapPackageManager));
            }
            if (distributedMutex == null)
            {
                throw new ArgumentNullException(nameof(distributedMutex));
            }
            if (snapAppsReleases == null)
            {
                throw new ArgumentNullException(nameof(snapAppsReleases));
            }
            if (snapApp == null)
            {
                throw new ArgumentNullException(nameof(snapApp));
            }
            if (snapChannel == null)
            {
                throw new ArgumentNullException(nameof(snapChannel));
            }
            if (packages == null)
            {
                throw new ArgumentNullException(nameof(packages));
            }
            if (packages.Count == 0)
            {
                throw new ArgumentException("Value cannot be an empty collection.", nameof(packages));
            }

            logger.Info('-'.Repeat(TerminalBufferWidth));

            var pushDegreeOfParallelism = Math.Min(Environment.ProcessorCount, packages.Count);

            var nugetSources          = snapApp.BuildNugetSources(filesystem.PathGetTempPath());
            var pushFeedPackageSource = nugetSources.Items.Single(x => x.Name == snapChannel.PushFeed.Name);

            if (pushFeedPackageSource.IsLocalOrUncPath())
            {
                filesystem.DirectoryCreateIfNotExists(pushFeedPackageSource.SourceUri.AbsolutePath);
            }

            if (snapChannel.UpdateFeed.HasCredentials())
            {
                if (!logger.Prompt("y|yes", "Update feed contains credentials. Do you want to continue? [y|n]", infoOnly: packOptions.YesToAllPrompts))
                {
                    logger.Error("Publish aborted.");
                    return;
                }
            }

            logger.Info("Ready to publish application!");

            logger.Info($"Id: {snapApp.Id}");
            logger.Info($"Rid: {snapApp.Target.Rid}");
            logger.Info($"Channel: {snapChannel.Name}");
            logger.Info($"Version: {snapApp.Version}");
            logger.Info($"Feed name: {snapChannel.PushFeed.Name}");

            if (!logger.Prompt("y|yes", "Are you ready to push release upstream? [y|n]", infoOnly: packOptions.YesToAllPrompts))
            {
                logger.Error("Publish aborted.");
                return;
            }

            var stopwatch = new Stopwatch();

            stopwatch.Restart();

            logger.Info($"Pushing packages to default channel: {snapChannel.Name}. Feed: {snapChannel.PushFeed.Name}.");

            await packages.ForEachAsync(async packageAbsolutePath =>
                                        await PushPackageAsync(nugetService, filesystem, distributedMutex,
                                                               nugetSources, pushFeedPackageSource, snapChannel, packageAbsolutePath, logger, cancellationToken), pushDegreeOfParallelism);

            logger.Info($"Successfully pushed {packages.Count} packages in {stopwatch.Elapsed.TotalSeconds:F1}s.");

            var skipInitialBlock = pushFeedPackageSource.IsLocalOrUncPath();

            await BlockUntilSnapUpdatedReleasesNupkgAsync(logger, snapPackageManager, snapAppsReleases,
                                                          snapApp, snapChannel, TimeSpan.FromSeconds(15), cancellationToken, skipInitialBlock, packOptions.SkipAwaitUpdate);
        }
예제 #7
0
        public async Task <SnapApp> UpdateAsync(string baseDirectory, SnapRelease snapRelease, SnapChannel snapChannel,
                                                ISnapProgressSource snapProgressSource = null, ILog logger = null, CancellationToken cancellationToken = default)
        {
            if (baseDirectory == null)
            {
                throw new ArgumentNullException(nameof(baseDirectory));
            }
            if (snapRelease == null)
            {
                throw new ArgumentNullException(nameof(snapRelease));
            }
            if (snapChannel == null)
            {
                throw new ArgumentNullException(nameof(snapChannel));
            }

            if (!_snapOs.Filesystem.DirectoryExists(baseDirectory))
            {
                logger?.Error($"Base directory does not exist: {baseDirectory}");
                return(null);
            }

            var nupkgAbsoluteFilename = _snapOs.Filesystem.PathCombine(baseDirectory, "packages", snapRelease.Filename);

            if (!_snapOs.Filesystem.FileExists(nupkgAbsoluteFilename))
            {
                logger?.Error($"Unable to apply full update because the nupkg does not exist: {nupkgAbsoluteFilename}");
                return(null);
            }

            snapProgressSource?.Raise(0);
            logger?.Debug("Attempting to get snap app details from nupkg");

            var nupkgFileStream = _snapOs.Filesystem.FileRead(nupkgAbsoluteFilename);

            using var packageArchiveReader = new PackageArchiveReader(nupkgFileStream);
            var snapApp = await _snapPack.GetSnapAppAsync(packageArchiveReader, cancellationToken);

            if (!snapApp.IsFull)
            {
                logger?.Error($"You can only update from a full nupkg. Snap id: {snapApp.Id}. Filename: {nupkgAbsoluteFilename}");
                return(null);
            }

            snapApp.SetCurrentChannel(snapChannel.Name);

            logger?.Info($"Updating snap id: {snapApp.Id}. Version: {snapApp.Version}. ");

            var appDirectory = GetApplicationDirectory(baseDirectory, snapApp.Version);

            snapProgressSource?.Raise(10);
            if (_snapOs.Filesystem.DirectoryExists(appDirectory))
            {
                _snapOs.KillAllProcessesInsideDirectory(appDirectory);
                logger?.Info($"Deleting existing app directory: {appDirectory}");
                await _snapOs.Filesystem.DirectoryDeleteAsync(appDirectory);
            }

            logger?.Info($"Creating app directory: {appDirectory}");
            _snapOs.Filesystem.DirectoryCreate(appDirectory);

            var packagesDirectory = GetPackagesDirectory(baseDirectory);

            if (!_snapOs.Filesystem.DirectoryExists(packagesDirectory))
            {
                logger?.Error($"Packages directory does not exist: {packagesDirectory}");
                return(null);
            }

            snapProgressSource?.Raise(30);

            logger?.Info($"Extracting nupkg to app directory: {appDirectory}");
            var extractedFiles = await _snapExtractor.ExtractAsync(appDirectory, snapRelease, packageArchiveReader, cancellationToken);

            if (!extractedFiles.Any())
            {
                logger?.Error($"Unknown error when attempting to extract nupkg: {nupkgAbsoluteFilename}");
                return(null);
            }

            snapProgressSource?.Raise(90);

            logger?.Info("Performing post install tasks");
            var nuspecReader = await packageArchiveReader.GetNuspecReaderAsync(cancellationToken);

            await InvokePostInstall(snapApp, nuspecReader,
                                    baseDirectory, appDirectory, snapApp.Version, false, logger, cancellationToken);

            logger?.Info("Post install tasks completed");

            snapProgressSource?.Raise(100);

            return(snapApp);
        }
예제 #8
0
        public async Task <SnapApp> InstallAsync(string nupkgAbsoluteFilename, string baseDirectory, SnapRelease snapRelease, SnapChannel snapChannel,
                                                 ISnapProgressSource snapProgressSource = null, ILog logger = null, CancellationToken cancellationToken = default, bool copyNupkgToPackagesDirectory = true)
        {
            if (baseDirectory == null)
            {
                throw new ArgumentNullException(nameof(baseDirectory));
            }
            if (snapChannel == null)
            {
                throw new ArgumentNullException(nameof(snapChannel));
            }

            snapProgressSource?.Raise(0);

            if (!_snapOs.Filesystem.FileExists(nupkgAbsoluteFilename))
            {
                logger?.Error($"Unable to find nupkg: {nupkgAbsoluteFilename}");
                return(null);
            }

            logger?.Debug("Attempting to get snap app details from nupkg");
            var nupkgFileStream = _snapOs.Filesystem.FileRead(nupkgAbsoluteFilename);

            using var packageArchiveReader = new PackageArchiveReader(nupkgFileStream);
            var snapApp = await _snapPack.GetSnapAppAsync(packageArchiveReader, cancellationToken);

            if (!snapApp.IsFull)
            {
                logger?.Error($"You can only install full nupkg. Snap id: {snapApp.Id}. Filename: {nupkgAbsoluteFilename}");
                return(null);
            }

            snapApp.SetCurrentChannel(snapChannel.Name);

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && snapApp.Target.Os != OSPlatform.Windows)
            {
                logger?.Error(
                    $"Unable to install snap because target OS {snapApp.Target.Os} does not match current OS: {OSPlatform.Windows.ToString()}. Snap id: {snapApp.Id}.");
                return(null);
            }

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && snapApp.Target.Os != OSPlatform.Linux)
            {
                logger?.Error($"Unable to install snap because target OS {snapApp.Target.Os} does not match current OS: {OSPlatform.Linux.ToString()}. Snap id: {snapApp.Id}.");
                return(null);
            }

            logger?.Info($"Installing snap id: {snapApp.Id}. Version: {snapApp.Version}.");

            if (snapApp.Target.PersistentAssets.Any())
            {
                logger?.Info($"Persistent assets: {string.Join(", ", snapApp.Target.PersistentAssets)}");
            }

            snapProgressSource?.Raise(10);
            if (_snapOs.Filesystem.DirectoryExists(baseDirectory))
            {
                _snapOs.KillAllProcessesInsideDirectory(baseDirectory);
                logger?.Info($"Deleting existing base directory: {baseDirectory}");
                await _snapOs.Filesystem.DirectoryDeleteAsync(baseDirectory, snapApp.Target.PersistentAssets);
            }

            snapProgressSource?.Raise(20);
            logger?.Info($"Creating base directory: {baseDirectory}");
            _snapOs.Filesystem.DirectoryCreate(baseDirectory);

            snapProgressSource?.Raise(30);
            var packagesDirectory = GetPackagesDirectory(baseDirectory);

            logger?.Info($"Creating packages directory: {packagesDirectory}");
            _snapOs.Filesystem.DirectoryCreate(packagesDirectory);

            snapProgressSource?.Raise(40);
            if (copyNupkgToPackagesDirectory)
            {
                var dstNupkgFilename = _snapOs.Filesystem.PathCombine(packagesDirectory, snapApp.BuildNugetFilename());
                logger?.Info($"Copying nupkg to {dstNupkgFilename}");
                await _snapOs.Filesystem.FileCopyAsync(nupkgAbsoluteFilename, dstNupkgFilename, cancellationToken);
            }

            snapProgressSource?.Raise(50);
            var appDirectory = GetApplicationDirectory(baseDirectory, snapApp.Version);

            logger?.Info($"Creating app directory: {appDirectory}");
            _snapOs.Filesystem.DirectoryCreate(appDirectory);

            snapProgressSource?.Raise(60);
            logger?.Info($"Extracting nupkg to app directory: {appDirectory}");
            var extractedFiles = await _snapExtractor.ExtractAsync(appDirectory, snapRelease, packageArchiveReader, cancellationToken);

            if (!extractedFiles.Any())
            {
                logger?.Error($"Unknown error when attempting to extract nupkg: {nupkgAbsoluteFilename}");
                return(null);
            }

            snapProgressSource?.Raise(90);
            logger?.Info("Performing post install tasks");
            var nuspecReader = await packageArchiveReader.GetNuspecReaderAsync(cancellationToken);

            await InvokePostInstall(snapApp, nuspecReader,
                                    baseDirectory, appDirectory, snapApp.Version, true, logger, cancellationToken);

            logger?.Info("Post install tasks completed");

            snapProgressSource?.Raise(100);

            return(snapApp);
        }
예제 #9
0
        public async Task TestBuildSnapApp_Throws_If_Multiple_Nuget_Push_Feed_Names()
        {
            await using var nugetTempDirectory = new DisposableDirectory(_baseFixture.WorkingDirectory, _fileSystem);

            var nugetOrgFeed = new SnapNugetFeed
            {
                Name            = "nuget.org",
                Source          = new Uri(NuGetConstants.V3FeedUrl),
                ProtocolVersion = NuGetProtocolVersion.V3,
                Username        = "******",
                Password        = "******",
                ApiKey          = "myapikey"
            };

            var nugetOrgFeed2 = new SnapNugetFeed
            {
                Name            = "nuget2.org",
                Source          = new Uri(NuGetConstants.V3FeedUrl),
                ProtocolVersion = NuGetProtocolVersion.V3,
                Username        = "******",
                Password        = "******",
                ApiKey          = "myapikey"
            };

            var testChannel = new SnapChannel
            {
                Name       = "test",
                PushFeed   = nugetOrgFeed,
                UpdateFeed = nugetOrgFeed,
                Current    = true
            };

            var stagingChannel = new SnapChannel
            {
                Name       = "staging",
                PushFeed   = nugetOrgFeed2,
                UpdateFeed = nugetOrgFeed2
            };

            var productionChannel = new SnapChannel
            {
                Name       = "production",
                PushFeed   = nugetOrgFeed,
                UpdateFeed = nugetOrgFeed
            };

            var snapAppBefore = new SnapApp
            {
                Id           = "demoapp",
                SuperVisorId = Guid.NewGuid().ToString(),
                Version      = new SemanticVersion(1, 0, 0),
                Channels     = new List <SnapChannel>
                {
                    testChannel,
                    stagingChannel,
                    productionChannel
                },
                Target = new SnapTarget
                {
                    Os        = OSPlatform.Windows,
                    Framework = "netcoreapp2.1",
                    Rid       = "win-x64",
                    Shortcuts = new List <SnapShortcutLocation>
                    {
                        SnapShortcutLocation.Desktop,
                        SnapShortcutLocation.Startup
                    },
                    PersistentAssets = new List <string>
                    {
                        "subdirectory",
                        "myjsonfile.json"
                    }
                }
            };

            var snapApps = new SnapApps(snapAppBefore);

            var ex = Assert.Throws <Exception>(() => snapApps.BuildSnapApp(snapAppBefore.Id, snapAppBefore.Target.Rid,
                                                                           snapAppBefore.BuildNugetSources(nugetTempDirectory), _fileSystem));

            Assert.Equal($"Multiple nuget push feeds is not supported: nuget.org,nuget2.org. Application id: {snapAppBefore.Id}", ex.Message);
        }
예제 #10
0
        public async Task TestBuildSnapApp()
        {
            await using var nugetTempDirectory = new DisposableDirectory(_baseFixture.WorkingDirectory, _fileSystem);

            var nugetOrgFeed = new SnapNugetFeed
            {
                Name            = "nuget.org",
                Source          = new Uri(NuGetConstants.V3FeedUrl),
                ProtocolVersion = NuGetProtocolVersion.V3,
                Username        = "******",
                Password        = "******",
                ApiKey          = "myapikey"
            };

            var updateFeedHttp = new SnapHttpFeed
            {
                Source = new Uri("https://mydynamicupdatefeed.com")
            };

            var testChannel = new SnapChannel
            {
                Name       = "test",
                PushFeed   = nugetOrgFeed,
                UpdateFeed = nugetOrgFeed,
                Current    = true
            };

            var stagingChannel = new SnapChannel
            {
                Name       = "staging",
                PushFeed   = nugetOrgFeed,
                UpdateFeed = updateFeedHttp
            };

            var productionChannel = new SnapChannel
            {
                Name       = "production",
                PushFeed   = nugetOrgFeed,
                UpdateFeed = nugetOrgFeed
            };

            var snapAppBefore = new SnapApp
            {
                Id      = "demoapp",
                MainExe = "demoapp",
                InstallDirectoryName = "demoapp",
                SuperVisorId         = Guid.NewGuid().ToString(),
                Version  = new SemanticVersion(1, 0, 0),
                Channels = new List <SnapChannel>
                {
                    testChannel,
                    stagingChannel,
                    productionChannel
                },
                Target = new SnapTarget
                {
                    Os        = OSPlatform.Windows,
                    Framework = "netcoreapp2.1",
                    Rid       = "win-x64",
                    Shortcuts = new List <SnapShortcutLocation>
                    {
                        SnapShortcutLocation.Desktop,
                        SnapShortcutLocation.Startup
                    },
                    PersistentAssets = new List <string>
                    {
                        "subdirectory",
                        "myjsonfile.json"
                    }
                }
            };

            var snapApps = new SnapApps(snapAppBefore);

            var snapAppAfter = snapApps.BuildSnapApp(snapAppBefore.Id, snapAppBefore.Target.Rid,
                                                     snapAppBefore.BuildNugetSources(nugetTempDirectory), _fileSystem);

            snapAppAfter.Version = snapAppBefore.Version.BumpMajor();

            // Generic
            Assert.Equal(snapAppBefore.Id, snapAppAfter.Id);
            Assert.Equal(snapAppBefore.InstallDirectoryName, snapAppAfter.InstallDirectoryName);
            Assert.Equal(snapAppBefore.MainExe, snapAppAfter.MainExe);
            Assert.NotNull(snapAppAfter.MainExe);
            Assert.Equal(snapAppBefore.SuperVisorId, snapAppAfter.SuperVisorId);
            Assert.True(snapAppBefore.Version < snapAppAfter.Version);

            // Target
            Assert.NotNull(snapAppBefore.Target);
            Assert.NotNull(snapAppAfter.Target);
            Assert.Equal(snapAppBefore.Target.Os, snapAppAfter.Target.Os);
            Assert.Equal(snapAppBefore.Target.Rid, snapAppAfter.Target.Rid);
            Assert.NotNull(snapAppBefore.Target.Framework);
            Assert.NotNull(snapAppAfter.Target.Framework);
            Assert.Equal(snapAppBefore.Target.Framework, snapAppAfter.Target.Framework);
            Assert.Equal(snapAppBefore.Target.Rid, snapAppAfter.Target.Rid);
            Assert.Equal(snapAppBefore.Target.Shortcuts, snapAppAfter.Target.Shortcuts);
            Assert.Equal(snapAppBefore.Target.PersistentAssets, snapAppAfter.Target.PersistentAssets);

            // Channels
            Assert.Equal(snapAppBefore.Channels.Count, snapAppAfter.Channels.Count);
            for (var index = 0; index < snapAppAfter.Channels.Count; index++)
            {
                var lhsChannel = snapAppBefore.Channels[index];
                var rhsChannel = snapAppAfter.Channels[index];

                Assert.Equal(lhsChannel.Name, rhsChannel.Name);
                Assert.NotNull(lhsChannel.PushFeed);
                Assert.NotNull(rhsChannel.PushFeed);
                Assert.NotNull(lhsChannel.UpdateFeed);
                Assert.NotNull(rhsChannel.UpdateFeed);

                if (index == 0)
                {
                    Assert.True(lhsChannel.Current);
                    Assert.True(rhsChannel.Current);
                }
                else
                {
                    Assert.False(lhsChannel.Current);
                    Assert.False(rhsChannel.Current);
                }

                var lhsNugetPushFeed = lhsChannel.PushFeed;
                var rhsNugetPushFeed = rhsChannel.PushFeed;

                Assert.Equal(lhsNugetPushFeed.Name, rhsNugetPushFeed.Name);
                Assert.Equal(lhsNugetPushFeed.Source, rhsNugetPushFeed.Source);
                Assert.Equal(lhsNugetPushFeed.ProtocolVersion, rhsNugetPushFeed.ProtocolVersion);
                Assert.Equal(lhsNugetPushFeed.ApiKey, rhsNugetPushFeed.ApiKey);
                Assert.Equal(lhsNugetPushFeed.Username, rhsNugetPushFeed.Username);

                // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
                if (lhsNugetPushFeed.IsPasswordEncryptionSupported())
                {
                    Assert.Equal(EncryptionUtility.DecryptString(lhsNugetPushFeed.Password), rhsNugetPushFeed.Password);
                }
                else
                {
                    Assert.Equal(lhsNugetPushFeed.Password, rhsNugetPushFeed.Password);
                }

                var lhsUpdateFeed = lhsChannel.UpdateFeed;
                var rhsUpdateFeed = rhsChannel.UpdateFeed;

                switch (rhsUpdateFeed)
                {
                case SnapNugetFeed rhsNugetUpdateFeed:
                    var lhsNugetUpdateFeed = (SnapNugetFeed)lhsUpdateFeed;
                    Assert.Equal(lhsNugetUpdateFeed.Name, rhsNugetUpdateFeed.Name);
                    Assert.Equal(lhsNugetUpdateFeed.Source, rhsNugetUpdateFeed.Source);
                    Assert.Equal(lhsNugetUpdateFeed.ProtocolVersion, rhsNugetUpdateFeed.ProtocolVersion);
                    Assert.Equal(lhsNugetUpdateFeed.ApiKey, rhsNugetUpdateFeed.ApiKey);
                    Assert.Equal(lhsNugetUpdateFeed.Username, rhsNugetUpdateFeed.Username);
                    Assert.Equal(
                        lhsNugetUpdateFeed.IsPasswordEncryptionSupported()
                                ? EncryptionUtility.DecryptString(lhsNugetUpdateFeed.Password)
                                : lhsNugetUpdateFeed.Password, rhsNugetUpdateFeed.Password);
                    break;

                case SnapHttpFeed rhsHttpUpdateFeed:
                    var lhsHttpUpdateFeed = (SnapHttpFeed)lhsUpdateFeed;
                    Assert.NotNull(lhsHttpUpdateFeed.Source);
                    Assert.NotNull(rhsHttpUpdateFeed.Source);
                    Assert.Equal(lhsHttpUpdateFeed.Source, rhsHttpUpdateFeed.Source);
                    break;

                default:
                    throw new NotSupportedException(rhsUpdateFeed.GetType().ToString());
                }
            }
        }
예제 #11
0
        public async Task TestBuildSnapFeedsFromNugetPackageSources(NuGetProtocolVersion protocolVersion)
        {
            await using var nugetTempDirectory = new DisposableDirectory(_baseFixture.WorkingDirectory, _fileSystem);

            var feedUrl = protocolVersion switch
            {
                NuGetProtocolVersion.V2 => NuGetConstants.V2FeedUrl,
                NuGetProtocolVersion.V3 => NuGetConstants.V3FeedUrl,
                _ => throw new NotSupportedException(protocolVersion.ToString())
            };

            var snapNugetFeed = new SnapNugetFeed
            {
                Name            = "nuget.org",
                ProtocolVersion = protocolVersion,
                Source          = new Uri(feedUrl),
                Username        = "******",
                Password        = "******",
                ApiKey          = "myapikey"
            };

            var snapChannel = new SnapChannel
            {
                Name       = "test",
                PushFeed   = snapNugetFeed,
                UpdateFeed = snapNugetFeed
            };

            var snapApp = new SnapApp
            {
                Channels = new List <SnapChannel> {
                    snapChannel
                }
            };

            var nugetPackageSources = snapApp.BuildNugetSources(nugetTempDirectory);

            Assert.NotNull(nugetPackageSources.Settings);
            Assert.Single(nugetPackageSources.Items);

            var snapFeeds = snapApp.BuildNugetSources(nugetTempDirectory);

            Assert.NotNull(snapFeeds.Settings);
            Assert.Single(snapFeeds.Items);

            var snapNugetFeedAfter = snapFeeds.Items.Single();

            Assert.Equal(snapNugetFeed.Name, snapNugetFeedAfter.Name);
            Assert.Equal((int)snapNugetFeed.ProtocolVersion, snapNugetFeedAfter.ProtocolVersion);
            Assert.Equal(snapNugetFeed.Source, snapNugetFeedAfter.SourceUri);
            Assert.Equal(snapNugetFeed.Username, snapNugetFeedAfter.Credentials.Username);
            var credential = snapNugetFeedAfter.Credentials;

            if (nugetPackageSources.IsPasswordEncryptionSupported())
            {
                Assert.False(credential.IsPasswordClearText);
                Assert.Equal(EncryptionUtility.DecryptString(snapNugetFeed.Password), credential.Password);
                Assert.Equal(snapNugetFeed.Password, credential.PasswordText);
            }
            else
            {
                Assert.True(credential.IsPasswordClearText);
                Assert.Equal(snapNugetFeed.Password, credential.Password);
            }
            Assert.Equal(snapNugetFeed.ApiKey, snapNugetFeedAfter.GetDecryptedValue(nugetPackageSources, ConfigurationConstants.ApiKeys));
        }
예제 #12
0
        static SnapApp BuildSnap()
        {
            var nugetOrgFeed = new SnapNugetFeed
            {
                Name            = "nuget.org",
                Source          = new Uri(NuGetConstants.V3FeedUrl),
                ProtocolVersion = NuGetProtocolVersion.V3,
                Username        = "******",
                Password        = "******",
                ApiKey          = "myapikey"
            };

            var updateFeedHttp = new SnapHttpFeed
            {
                Source = new Uri("https://mydynamicupdatefeed.com")
            };

            var testChannel = new SnapChannel
            {
                Name       = "test",
                PushFeed   = nugetOrgFeed,
                UpdateFeed = nugetOrgFeed,
                Current    = true
            };

            var stagingChannel = new SnapChannel
            {
                Name       = "staging",
                PushFeed   = nugetOrgFeed,
                UpdateFeed = updateFeedHttp
            };

            var productionChannel = new SnapChannel
            {
                Name       = "production",
                PushFeed   = nugetOrgFeed,
                UpdateFeed = nugetOrgFeed
            };

            var snapApp = new SnapApp
            {
                Id       = "demoapp",
                Version  = new SemanticVersion(1, 0, 0),
                Channels = new List <SnapChannel>
                {
                    testChannel,
                    stagingChannel,
                    productionChannel
                },
                Target = new SnapTarget
                {
                    Os        = OSPlatform.Windows,
                    Framework = "netcoreapp2.1",
                    Rid       = "win7-x64",
                    Shortcuts = new List <SnapShortcutLocation>
                    {
                        SnapShortcutLocation.Desktop,
                        SnapShortcutLocation.Desktop,
                        SnapShortcutLocation.StartMenu
                    },
                    PersistentAssets = new List <string>
                    {
                        "application.json"
                    }
                }
            };

            return(snapApp);
        }
예제 #13
0
        static async Task BlockUntilSnapUpdatedReleasesNupkgAsync([NotNull] ILog logger, [NotNull] ISnapPackageManager snapPackageManager,
                                                                  [NotNull] SnapAppsReleases snapAppsReleases, [NotNull] SnapApp snapApp,
                                                                  [NotNull] SnapChannel snapChannel, TimeSpan retryInterval, CancellationToken cancellationToken)
        {
            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }
            if (snapPackageManager == null)
            {
                throw new ArgumentNullException(nameof(snapPackageManager));
            }
            if (snapAppsReleases == null)
            {
                throw new ArgumentNullException(nameof(snapAppsReleases));
            }
            if (snapApp == null)
            {
                throw new ArgumentNullException(nameof(snapApp));
            }
            if (snapChannel == null)
            {
                throw new ArgumentNullException(nameof(snapChannel));
            }

            var stopwatch = new Stopwatch();

            stopwatch.Restart();

            logger.Info('-'.Repeat(TerminalBufferWidth));

            logger.Info(
                $"Waiting until uploaded release nupkg is available in feed: {snapChannel.PushFeed.Name}. " +
                $"Retry every {retryInterval.TotalSeconds:0.0}s.");

            var logDashes = false;

            while (!cancellationToken.IsCancellationRequested)
            {
sleep:
                await Task.Delay(retryInterval, cancellationToken);

                if (logDashes)
                {
                    logger.Info('-'.Repeat(TerminalBufferWidth));
                }

                logDashes = true;

                var(upstreamSnapAppsReleases, _, releasesMemoryStream) = await snapPackageManager.GetSnapsReleasesAsync(snapApp, logger, cancellationToken);

                if (releasesMemoryStream != null)
                {
                    await releasesMemoryStream.DisposeAsync();
                }
                if (upstreamSnapAppsReleases == null)
                {
                    goto sleep;
                }

                if (upstreamSnapAppsReleases.PackId == snapAppsReleases.PackId)
                {
                    logger.Info($"{snapChannel.PushFeed.Name} releases nupkg has been successfully updated to version: {upstreamSnapAppsReleases.Version}.\n" +
                                $"Pack id: {upstreamSnapAppsReleases.PackId:N}. \n" +
                                $"Completed in {stopwatch.Elapsed.TotalSeconds:0.0}s. ");
                    break;
                }

                logger.Info(
                    $"Current {snapChannel.PushFeed.Name} version: {upstreamSnapAppsReleases.Version}.\n" +
                    $"Current pack id: {upstreamSnapAppsReleases.PackId:N}\n" +
                    $"Local version: {snapAppsReleases.Version}. \n" +
                    $"Local pack id: {snapAppsReleases.PackId:N} \n" +
                    $"Retry in {retryInterval.TotalSeconds:0.0}s.");
            }

            logger.Info('-'.Repeat(TerminalBufferWidth));
        }
예제 #14
0
        public void TestBuildNugetSourcesFromSnapApp(NuGetProtocolVersion protocolVersion)
        {
            string feedUrl;

            switch (protocolVersion)
            {
            case NuGetProtocolVersion.V2:
                feedUrl = NuGetConstants.V2FeedUrl;
                break;

            case NuGetProtocolVersion.V3:
                feedUrl = NuGetConstants.V3FeedUrl;
                break;

            default:
                throw new NotSupportedException(protocolVersion.ToString());
            }

            var snapNugetFeed = new SnapNugetFeed
            {
                Name            = "nuget.org",
                ProtocolVersion = protocolVersion,
                Source          = new Uri(feedUrl),
                Username        = "******",
                Password        = "******",
                ApiKey          = "myapikey"
            };

            var snapChannel = new SnapChannel
            {
                Name       = "test",
                PushFeed   = snapNugetFeed,
                UpdateFeed = snapNugetFeed
            };

            var snapApp = new SnapApp
            {
                Channels = new List <SnapChannel> {
                    snapChannel
                }
            };

            var nuGetPackageSources = snapApp.BuildNugetSources(_baseFixture.NugetTempDirectory);

            Assert.Single(nuGetPackageSources.Items);

            var packageSource = nuGetPackageSources.Items.Single();

            Assert.True(packageSource.IsEnabled);
            Assert.True(packageSource.IsOfficial);
            Assert.False(packageSource.IsPersistable);
            Assert.False(packageSource.IsMachineWide);

            Assert.Equal(snapNugetFeed.Name, packageSource.Name);
            Assert.Equal(snapNugetFeed.Source.ToString(), packageSource.TrySourceAsUri.ToString());
            Assert.Equal((int)snapNugetFeed.ProtocolVersion, packageSource.ProtocolVersion);
            Assert.NotNull(packageSource.Credentials);

            var credential = packageSource.Credentials;

            Assert.Equal(snapNugetFeed.Username, credential.Username);
            if (nuGetPackageSources.IsPasswordEncryptionSupported())
            {
                Assert.False(credential.IsPasswordClearText);
                Assert.Equal(EncryptionUtility.DecryptString(snapNugetFeed.Password), credential.Password);
                Assert.Equal(snapNugetFeed.Password, credential.PasswordText);
            }
            else
            {
                Assert.True(credential.IsPasswordClearText);
                Assert.Equal(snapNugetFeed.Password, credential.Password);
            }
            Assert.Equal(snapNugetFeed.Name, credential.Source);

            Assert.Equal(snapNugetFeed.ApiKey, packageSource.GetDecryptedValue(nuGetPackageSources, ConfigurationConstants.ApiKeys));
        }