protected override async Task BeforeStartAsync(IReadOnlyCollection <string> args)
        {
            var deploymentService = App.AppRootScope.Deepest().Lifetime.Resolve <DeploymentService>();
            var readService       = App.AppRootScope.Deepest().Lifetime.Resolve <IDeploymentTargetReadService>();

            ImmutableArray <DeploymentTarget> targets = await readService.GetDeploymentTargetsAsync(CancellationToken);

            if (targets.Length != 1)
            {
                throw new DeployerAppException("The test target has not been created");
            }

            const string packageVersion = "MilouDeployerWebTest 1.2.4";

            Guid         deploymentTaskId   = Guid.NewGuid();
            const string deploymentTargetId = TestDataCreator.Testtarget;
            var          deploymentTask     = new DeploymentTask(packageVersion, deploymentTargetId, deploymentTaskId);

            DeploymentTaskResult deploymentTaskResult = await deploymentService.ExecuteDeploymentAsync(
                deploymentTask,
                App.Logger,
                App.CancellationTokenSource.Token);

            if (!deploymentTaskResult.ExitCode.IsSuccess)
            {
                throw new DeployerAppException($"Initial deployment failed, metadata: {deploymentTaskResult.Metadata}; test configuration: {TestConfiguration}");
            }

            TestStartup.TestConfiguration = TestConfiguration;

            _webHost = WebHost.CreateDefaultBuilder()
                       .UseKestrel(options =>
            {
                options.Listen(IPAddress.Loopback,
                               TestSiteHttpPort.Port);
            })
                       .UseContentRoot(TestConfiguration.SiteAppRoot.FullName)
                       .UseStartup <TestStartup>().Build();

            await _webHost.StartAsync(App.CancellationTokenSource.Token);

            CancellationToken.Register(() => _webHost.StopAsync());
        }
Exemple #2
0
        private async Task StartProcessingAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                DeploymentTask deploymentTask = _queue.Take(stoppingToken);

                deploymentTask.Status = WorkTaskStatus.Started;
                _runningTasks.Add(deploymentTask, stoppingToken);

                _logger.Information("Deployment target worker has taken {DeploymentTask}", deploymentTask);

                deploymentTask.Status = WorkTaskStatus.Started;

                _logger.Information("Executing deployment task {DeploymentTask}", deploymentTask);

                await Task.Delay(TimeSpan.FromMilliseconds(500), stoppingToken);

                DeploymentTaskResult result =
                    await _deploymentService.ExecuteDeploymentAsync(deploymentTask, _logger, stoppingToken);

                if (result.ExitCode.IsSuccess)
                {
                    _logger.Information("Executed deployment task {DeploymentTask}", deploymentTask);

                    deploymentTask.Status = WorkTaskStatus.Done;
                    deploymentTask.Log("{\"Message\": \"Work task completed\"}");
                }
                else
                {
                    _logger.Error("Failed to deploy task {DeploymentTask}, result {Result}",
                                  deploymentTask,
                                  result.Metadata);

                    deploymentTask.Status = WorkTaskStatus.Failed;
                    deploymentTask.Log("{\"Message\": \"Work task failed\"}");
                }
            }

            _queue?.Dispose();
        }
        public async Task <DeploymentTaskResult> ExecuteDeploymentAsync(
            [NotNull] DeploymentTask deploymentTask,
            ILogger logger,
            CancellationToken cancellationToken)
        {
            if (deploymentTask == null)
            {
                throw new ArgumentNullException(nameof(deploymentTask));
            }

            DateTime  start     = _customClock.UtcNow().UtcDateTime;
            Stopwatch stopwatch = Stopwatch.StartNew();

            (ExitCode, DateTime)result;

            DirectoryInfo deploymentJobsDirectory = EnsureDeploymentJobsDirectoryExists();

            DeploymentTarget deploymentTarget = null;

            try
            {
                deploymentTarget = await _targetSource.GetDeploymentTargetAsync(deploymentTask.DeploymentTargetId,
                                                                                cancellationToken);

                VerifyPreReleaseAllowed(deploymentTask.SemanticVersion,
                                        deploymentTarget,
                                        deploymentTask.PackageId,
                                        logger);

                VerifyAllowedPackageIsAllowed(deploymentTarget, deploymentTask.PackageId, logger);

                result = await RunDeploymentToolAsync(deploymentTask,
                                                      deploymentJobsDirectory,
                                                      deploymentTarget,
                                                      logger,
                                                      cancellationToken);
            }
            catch (Exception ex) when(!ex.IsFatal())
            {
                result = (ExitCode.Failure, _customClock.UtcNow().UtcDateTime);
                logger.Error(ex, "Error deploying");
            }

            stopwatch.Stop();

            string metadataContent = LogJobMetadata(deploymentTask,
                                                    start,
                                                    result.Item2,
                                                    stopwatch,
                                                    result.Item1,
                                                    deploymentJobsDirectory,
                                                    deploymentTarget);

            var deploymentTaskResult = new DeploymentTaskResult(deploymentTask.DeploymentTaskId,
                                                                deploymentTask.DeploymentTargetId,
                                                                result.Item1,
                                                                start,
                                                                result.Item2,
                                                                metadataContent);

            await _mediator.Publish(new DeploymentMetadataLogNotification(deploymentTask, deploymentTaskResult),
                                    cancellationToken);

            return(deploymentTaskResult);
        }
        public async Task AutoDeployAsync([NotNull] IReadOnlyCollection <PackageVersion> packageIdentifiers)
        {
            if (packageIdentifiers == null)
            {
                throw new ArgumentNullException(nameof(packageIdentifiers));
            }

            _logger.Information("Received hook for packages {Packages}", string.Join(", ", packageIdentifiers.Select(p => p.ToString())));

            IReadOnlyCollection <DeploymentTarget> deploymentTargets =
                (await _targetSource.GetDeploymentTargetsAsync(CancellationToken.None))
                .SafeToReadOnlyCollection();

            DeploymentTarget[] withAutoDeploy = deploymentTargets.Where(t => t.AutoDeployEnabled).ToArray();

            if (!withAutoDeploy.Any())
            {
                _logger.Information("No target has auto deploy enabled");
            }
            else
            {
                foreach (DeploymentTarget deploymentTarget in withAutoDeploy)
                {
                    foreach (PackageVersion packageIdentifier in packageIdentifiers)
                    {
                        if (deploymentTarget.PackageId.Equals(
                                packageIdentifier.PackageId,
                                StringComparison.OrdinalIgnoreCase))
                        {
                            bool allowDeployment =
                                !packageIdentifier.Version.IsPrerelease || deploymentTarget.AllowPreRelease;

                            if (allowDeployment)
                            {
                                AppVersion metadata = await _monitoringService.GetAppMetadataAsync(
                                    deploymentTarget,
                                    CancellationToken.None);

                                if (metadata.SemanticVersion != null)
                                {
                                    if (packageIdentifier.Version > metadata.SemanticVersion)
                                    {
                                        _logger.Information("Auto deploying package {PackageIdentifier} to target {Name} from web hook", packageIdentifier, deploymentTarget.Name);

                                        DeploymentTaskResult result =
                                            await
                                            _deploymentService.ExecuteDeploymentAsync(
                                                new DeploymentTask(
                                                    $"{packageIdentifier.PackageId}, {packageIdentifier.Version.ToNormalizedString()}",
                                                    deploymentTarget.Id, Guid.NewGuid()
                                                    ),
                                                _logger,
                                                CancellationToken.None);

                                        _logger.Information("Deployed package {PackageIdentifier} to target {Name} from web hook with result {Result}", packageIdentifier, deploymentTarget.Name, result);
                                    }
                                    else
                                    {
                                        _logger.Information("Auto deployment skipped for {PackageIdentifier} since deployed version is higher {V}", packageIdentifier, metadata.SemanticVersion.ToNormalizedString());
                                    }
                                }
                                else
                                {
                                    _logger.Information("Auto deployment skipped for {PackageIdentifier} since the target version could not be determined", packageIdentifier);
                                }
                            }
                            else
                            {
                                _logger.Information("Auto deployment skipped for {PackageIdentifier} since the target does not allow pre-release", packageIdentifier);
                            }
                        }
                        else
                        {
                            _logger.Information("No package id matched {PackageIdentifier} for target {Name}", packageIdentifier, deploymentTarget.Name);
                        }
                    }
                }
            }
        }