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()); }
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); } } } } }