Browse Source

WIP

davidfowl/build-earlier
David Fowler 7 years ago
parent
commit
3a67a5c3a4
  1. 97
      src/Microsoft.Tye.Core/ApplicationBuilderExtensions.cs
  2. 8
      src/Microsoft.Tye.Core/ApplicationFactory.cs
  3. 1
      src/Microsoft.Tye.Core/ConfigModel/ConfigService.cs
  4. 2
      src/Microsoft.Tye.Core/ContainerServiceBuilder.cs
  5. 30
      src/Microsoft.Tye.Core/OutputContext.cs
  6. 33
      src/Microsoft.Tye.Core/ProjectReader.cs
  7. 2
      src/Microsoft.Tye.Core/ProjectServiceBuilder.cs
  8. 7
      src/Microsoft.Tye.Core/Serialization/ConfigServiceParser.cs
  9. 2
      src/Microsoft.Tye.Hosting/Model/ProjectRunInfo.cs
  10. 1
      src/Microsoft.Tye.Hosting/Model/V1/V1RunInfo.cs
  11. 25
      src/Microsoft.Tye.Hosting/ProcessRunner.cs
  12. 93
      src/Microsoft.Tye.Hosting/TransformProjectsIntoContainers.cs
  13. 1
      src/Microsoft.Tye.Hosting/TyeDashboardApi.cs
  14. 6
      src/Microsoft.Tye.Hosting/TyeHost.cs
  15. 5
      src/tye/ApplicationBuilderExtensions.cs
  16. 24
      src/tye/Program.RunCommand.cs
  17. 29
      test/E2ETest/TyeRunTests.cs
  18. 1
      test/UnitTests/TyeDeserializationTests.cs

97
src/Microsoft.Tye.Core/ApplicationBuilderExtensions.cs

@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.Tye
{
public static class ApplicationBuilderExtensions
{
public static async Task<bool> TransformProjectsIntoContainersAync(this ApplicationBuilder application, OutputContext output)
{
var targets = new[] { "Restore", "Publish" };
for (var i = 0; i < application.Services.Count; i++)
{
var service = application.Services[i];
if (!(service is ProjectServiceBuilder project))
{
continue;
}
if (!await ProjectReader.ReadProjectDetailsAsync(output, project, targets))
{
return false;
}
PopulateProjectDefaults(project);
static string DetermineContainerImage(ProjectServiceBuilder project)
{
return $"mcr.microsoft.com/dotnet/core/sdk:{project.TargetFrameworkVersion}";
}
// We transform the project information into the following docker command:
// docker run -w /app -v {publishDir}:/app -it {image} dotnet {outputfile}.dll
var containerImage = DetermineContainerImage(project);
var outputFileName = project.AssemblyName + ".dll";
var containerService = new ContainerServiceBuilder(service.Name, containerImage)
{
Replicas = project.Replicas,
Args = $"dotnet {outputFileName} {project.Args}",
WorkingDirectory = "/app"
};
containerService.Volumes.Add(new VolumeBuilder(source: project.PublishDir, name: null, target: "/app"));
// Make volume mapping works when running as a container
containerService.Volumes.AddRange(project.Volumes);
containerService.Bindings.AddRange(project.Bindings);
containerService.EnvironmentVariables.AddRange(project.EnvironmentVariables);
application.Services[i] = containerService;
}
return true;
}
public static async Task<bool> BuildProjectsAsync(this ApplicationBuilder application, OutputContext output)
{
var targets = new string[] { "Restore", "Build" };
foreach (var service in application.Services)
{
if (service is ProjectServiceBuilder project)
{
if (!await ProjectReader.ReadProjectDetailsAsync(output, project, targets))
{
return false;
}
PopulateProjectDefaults(project);
}
}
return true;
}
private static void PopulateProjectDefaults(ProjectServiceBuilder project)
{
if (project.Bindings.Count == 0 && project.IsAspNet)
{
// HTTP is the default binding
project.Bindings.Add(new BindingBuilder()
{
Protocol = "http"
});
project.Bindings.Add(new BindingBuilder()
{
Name = "https",
Protocol = "https"
});
}
}
}
}

8
src/Microsoft.Tye.Core/ApplicationFactory.cs

@ -14,7 +14,7 @@ namespace Microsoft.Tye
{
public static class ApplicationFactory
{
public static async Task<ApplicationBuilder> CreateAsync(OutputContext output, FileInfo source)
public static async Task<ApplicationBuilder> CreateAsync(OutputContext output, FileInfo source, bool populateProjectInformation = true)
{
if (source is null)
{
@ -57,11 +57,13 @@ namespace Microsoft.Tye
var project = new ProjectServiceBuilder(configService.Name!, projectFile);
service = project;
project.Build = configService.Build ?? true;
project.Args = configService.Args;
project.Replicas = configService.Replicas ?? 1;
await ProjectReader.ReadProjectDetailsAsync(output, project);
if (populateProjectInformation)
{
await ProjectReader.ReadProjectDetailsAsync(output, project);
}
// We don't apply more container defaults here because we might need
// to prompt for the registry name.

1
src/Microsoft.Tye.Core/ConfigModel/ConfigService.cs

@ -15,7 +15,6 @@ namespace Microsoft.Tye.ConfigModel
public bool External { get; set; }
public string? Image { get; set; }
public string? Project { get; set; }
public bool? Build { get; set; }
public string? Executable { get; set; }
public string? WorkingDirectory { get; set; }
public string? Args { get; set; }

2
src/Microsoft.Tye.Core/ContainerServiceBuilder.cs

@ -23,5 +23,7 @@ namespace Microsoft.Tye
public List<EnvironmentVariableBuilder> EnvironmentVariables { get; } = new List<EnvironmentVariableBuilder>();
public List<VolumeBuilder> Volumes { get; } = new List<VolumeBuilder>();
public string? WorkingDirectory { get; set; }
}
}

30
src/Microsoft.Tye.Core/OutputContext.cs

@ -178,22 +178,28 @@ namespace Microsoft.Tye
public void StdOut(string line)
{
if (output.Verbosity >= Verbosity.Debug)
{
output.Console.SetTerminalForegroundColor(ConsoleColor.Gray);
output.Console.Out.WriteLine(new string(' ', output.indent + IndentAmount) + line);
output.Console.ResetTerminalForegroundColor();
}
//if (output.Verbosity >= Verbosity.Debug)
//{
// output.Console.SetTerminalForegroundColor(ConsoleColor.Gray);
// output.Console.Out.WriteLine(new string(' ', output.indent + IndentAmount) + line);
// output.Console.ResetTerminalForegroundColor();
//}
output.Console.SetTerminalForegroundColor(ConsoleColor.Gray);
output.Console.Out.WriteLine(new string(' ', output.indent + IndentAmount) + line);
output.Console.ResetTerminalForegroundColor();
}
public void StdErr(string line)
{
if (output.Verbosity >= Verbosity.Info)
{
output.Console.SetTerminalForegroundColor(ConsoleColor.Red);
output.Console.Out.WriteLine(new string(' ', output.indent + IndentAmount) + line);
output.Console.ResetTerminalForegroundColor();
}
//if (output.Verbosity >= Verbosity.Info)
//{
// output.Console.SetTerminalForegroundColor(ConsoleColor.Red);
// output.Console.Out.WriteLine(new string(' ', output.indent + IndentAmount) + line);
// output.Console.ResetTerminalForegroundColor();
//}
output.Console.SetTerminalForegroundColor(ConsoleColor.Red);
output.Console.Out.WriteLine(new string(' ', output.indent + IndentAmount) + line);
output.Console.ResetTerminalForegroundColor();
}
}

33
src/Microsoft.Tye.Core/ProjectReader.cs

@ -60,7 +60,7 @@ namespace Microsoft.Tye
}
}
public static Task ReadProjectDetailsAsync(OutputContext output, ProjectServiceBuilder project)
public static Task<bool> ReadProjectDetailsAsync(OutputContext output, ProjectServiceBuilder project, string[]? targets = null)
{
if (output is null)
{
@ -74,7 +74,7 @@ namespace Microsoft.Tye
EnsureMSBuildRegistered(output, project.ProjectFile);
EvaluateProject(output, project);
var result = EvaluateProject(output, project, targets);
if (!SemVersion.TryParse(project.Version, out var version))
{
@ -83,7 +83,7 @@ namespace Microsoft.Tye
project.Version = version.ToString();
}
return Task.CompletedTask;
return Task.FromResult(result);
}
private static void EnsureMSBuildRegistered(OutputContext? output, FileInfo projectFile)
@ -141,8 +141,10 @@ namespace Microsoft.Tye
// Do not load MSBuild types before using EnsureMSBuildRegistered.
[MethodImpl(MethodImplOptions.NoInlining)]
private static void EvaluateProject(OutputContext output, ProjectServiceBuilder project)
private static bool EvaluateProject(OutputContext output, ProjectServiceBuilder project, string[]? targets = null)
{
var result = true;
var sw = Stopwatch.StartNew();
// We need to isolate projects from each other for testing. MSBuild does not support
@ -168,17 +170,19 @@ namespace Microsoft.Tye
// Currently we only log at debug level.
var logger = new ConsoleLogger(
verbosity: LoggerVerbosity.Normal,
verbosity: LoggerVerbosity.Quiet,
write: message => output.WriteDebug(message),
colorSet: null,
colorReset: null);
try
{
targets ??= new[] { "Restore", "ResolveReferences", "ResolvePackageDependenciesDesignTime", "PrepareResources", "GetAssemblyAttributes" };
output.WriteDebugLine($"Executing targtes: {string.Join(", ", targets)}");
AssemblyLoadContext.Default.Resolving += ResolveAssembly;
var result = projectInstance.Build(
targets: new[] { "Restore", "ResolveReferences", "ResolvePackageDependenciesDesignTime", "PrepareResources", "GetAssemblyAttributes", },
loggers: new[] { logger, });
result = projectInstance.Build(targets, loggers: new[] { logger });
// If the build fails, we're not really blocked from doing our work.
// For now we just log the output to debug. There are errors that occur during
@ -234,6 +238,7 @@ namespace Microsoft.Tye
output.WriteDebugLine($"Evaluation Took: {sw.Elapsed.TotalMilliseconds}ms");
return result;
// The Microsoft.Build.Locator doesn't handle the loading of other assemblies
// that are shipped with MSBuild (ex NuGet).
//
@ -246,14 +251,12 @@ namespace Microsoft.Tye
// See: https://github.com/microsoft/MSBuildLocator/issues/86
Assembly? ResolveAssembly(AssemblyLoadContext context, AssemblyName assemblyName)
{
if (assemblyName.Name is object && assemblyName.Name.StartsWith("NuGet."))
var msbuildDirectory = Environment.GetEnvironmentVariable("MSBuildExtensionsPath")!;
var assemblyFilePath = Path.Combine(msbuildDirectory, assemblyName.Name + ".dll");
if (File.Exists(assemblyFilePath))
{
var msbuildDirectory = Environment.GetEnvironmentVariable("MSBuildExtensionsPath")!;
var assemblyFilePath = Path.Combine(msbuildDirectory, assemblyName.Name + ".dll");
if (File.Exists(assemblyFilePath))
{
return context.LoadFromAssemblyPath(assemblyFilePath);
}
return context.LoadFromAssemblyPath(assemblyFilePath);
}
return default;

2
src/Microsoft.Tye.Core/ProjectServiceBuilder.cs

@ -19,8 +19,6 @@ namespace Microsoft.Tye
public int Replicas { get; set; } = 1;
public bool Build { get; set; }
public string? Args { get; set; }
public FrameworkCollection Frameworks { get; } = new FrameworkCollection();

7
src/Microsoft.Tye.Core/Serialization/ConfigServiceParser.cs

@ -45,13 +45,6 @@ namespace Tye.Serialization
case "project":
service.Project = YamlParser.GetScalarValue(key, child.Value);
break;
case "build":
if (!bool.TryParse(YamlParser.GetScalarValue(key, child.Value), out var build))
{
throw new TyeYamlException(child.Value.Start, CoreStrings.FormatMustBeABoolean(key));
}
service.Build = build;
break;
case "executable":
service.Executable = YamlParser.GetScalarValue(key, child.Value);
break;

2
src/Microsoft.Tye.Hosting/Model/ProjectRunInfo.cs

@ -13,7 +13,6 @@ namespace Microsoft.Tye.Hosting.Model
{
ProjectFile = project.ProjectFile;
Args = project.Args;
Build = project.Build;
TargetFramework = project.TargetFramework;
TargetFrameworkName = project.TargetFrameworkName;
TargetFrameworkVersion = project.TargetFrameworkVersion;
@ -26,7 +25,6 @@ namespace Microsoft.Tye.Hosting.Model
}
public string? Args { get; }
public bool Build { get; }
public FileInfo ProjectFile { get; }
public string TargetFrameworkName { get; set; } = default!;
public string TargetFrameworkVersion { get; set; } = default!;

1
src/Microsoft.Tye.Hosting/Model/V1/V1RunInfo.cs

@ -10,7 +10,6 @@ namespace Microsoft.Tye.Hosting.Model.V1
{
public V1RunInfoType Type { get; set; }
public string? Args { get; set; }
public bool Build { get; set; }
public string? Project { get; set; }
public string? WorkingDirectory { get; set; }
public List<V1DockerVolume>? VolumeMappings { get; set; }

25
src/Microsoft.Tye.Hosting/ProcessRunner.cs

@ -56,7 +56,7 @@ namespace Microsoft.Tye.Hosting
return KillRunningProcesses(application.Services);
}
private async Task LaunchService(Application application, Service service)
private Task LaunchService(Application application, Service service)
{
var serviceDescription = service.Description;
var serviceName = serviceDescription.Name;
@ -96,27 +96,6 @@ namespace Microsoft.Tye.Hosting
var processInfo = new ProcessInfo(new Task[service.Description.Replicas]);
if (service.Status.ProjectFilePath != null &&
service.Description.RunInfo is ProjectRunInfo project2 &&
project2.Build &&
_options.BuildProjects)
{
// Sometimes building can fail because of file locking (like files being open in VS)
_logger.LogInformation("Building project {ProjectFile}", service.Status.ProjectFilePath);
service.Logs.OnNext($"dotnet build \"{service.Status.ProjectFilePath}\" /nologo");
var buildResult = await ProcessUtil.RunAsync("dotnet", $"build \"{service.Status.ProjectFilePath}\" /nologo", throwOnError: false, workingDirectory: workingDirectory);
service.Logs.OnNext(buildResult.StandardOutput);
if (buildResult.ExitCode != 0)
{
_logger.LogInformation("Building {ProjectFile} failed with exit code {ExitCode}: \r\n" + buildResult.StandardOutput, service.Status.ProjectFilePath, buildResult.ExitCode);
return;
}
}
async Task RunApplicationAsync(IEnumerable<(int ExternalPort, int Port, string? Protocol)> ports)
{
// Make sure we yield before trying to start the process, this is important so we don't block startup
@ -298,6 +277,8 @@ namespace Microsoft.Tye.Hosting
}
service.Items[typeof(ProcessInfo)] = processInfo;
return Task.CompletedTask;
}
private Task KillRunningProcesses(IDictionary<string, Service> services)

93
src/Microsoft.Tye.Hosting/TransformProjectsIntoContainers.cs

@ -1,93 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Tye.Hosting.Model;
namespace Microsoft.Tye.Hosting
{
public class TransformProjectsIntoContainers : IApplicationProcessor
{
private readonly ILogger _logger;
public TransformProjectsIntoContainers(ILogger logger)
{
_logger = logger;
}
public Task StartAsync(Application application)
{
// This transforms a ProjectRunInfo into a container
var tasks = new List<Task>();
foreach (var s in application.Services.Values)
{
if (s.Description.RunInfo is ProjectRunInfo project)
{
tasks.Add(TransformProjectToContainer(s, project));
}
}
return Task.WhenAll(tasks);
}
private async Task TransformProjectToContainer(Service service, ProjectRunInfo project)
{
var serviceDescription = service.Description;
var serviceName = serviceDescription.Name;
service.Status.ProjectFilePath = project.ProjectFile.FullName;
var targetFramework = project.TargetFramework;
// Sometimes building can fail because of file locking (like files being open in VS)
_logger.LogInformation("Publishing project {ProjectFile}", service.Status.ProjectFilePath);
var publishCommand = $"publish \"{service.Status.ProjectFilePath}\" --framework {targetFramework} /nologo";
service.Logs.OnNext($"dotnet {publishCommand}");
var buildResult = await ProcessUtil.RunAsync("dotnet", publishCommand, throwOnError: false);
service.Logs.OnNext(buildResult.StandardOutput);
if (buildResult.ExitCode != 0)
{
_logger.LogInformation("Publishing {ProjectFile} failed with exit code {ExitCode}: \r\n" + buildResult.StandardOutput, service.Status.ProjectFilePath, buildResult.ExitCode);
// Null out the RunInfo so that
serviceDescription.RunInfo = null;
return;
}
// We transform the project information into the following docker command:
// docker run -w /app -v {publishDir}:/app -it {image} dotnet {outputfile}.dll
var containerImage = DetermineContainerImage(project);
var outputFileName = project.AssemblyName + ".dll";
var dockerRunInfo = new DockerRunInfo(containerImage, $"dotnet {outputFileName} {project.Args}")
{
WorkingDirectory = "/app"
};
dockerRunInfo.VolumeMappings.Add(new DockerVolume(source: project.PublishOutputPath, name: null, target: "/app"));
// Make volume mapping works when running as a container
dockerRunInfo.VolumeMappings.AddRange(project.VolumeMappings);
// Change the project into a container info
serviceDescription.RunInfo = dockerRunInfo;
}
private static string DetermineContainerImage(ProjectRunInfo project)
{
return $"mcr.microsoft.com/dotnet/core/sdk:{project.TargetFrameworkVersion}";
}
public Task StopAsync(Application application)
{
return Task.CompletedTask;
}
}
}

1
src/Microsoft.Tye.Hosting/TyeDashboardApi.cs

@ -151,7 +151,6 @@ namespace Microsoft.Tye.Hosting
{
v1RunInfo.Type = V1RunInfoType.Project;
v1RunInfo.Args = projectRunInfo.Args;
v1RunInfo.Build = projectRunInfo.Build;
v1RunInfo.Project = projectRunInfo.ProjectFile.FullName;
}

6
src/Microsoft.Tye.Hosting/TyeHost.cs

@ -264,12 +264,6 @@ namespace Microsoft.Tye.Hosting
new ProcessRunner(logger, replicaRegistry, ProcessRunnerOptions.FromArgs(args, servicesToDebug))
};
// If the docker command is specified then transform the ProjectRunInfo into DockerRunInfo
if (args.Contains("--docker"))
{
processors.Insert(0, new TransformProjectsIntoContainers(logger));
}
return new AggregateApplicationProcessor(processors);
}

5
src/tye/ApplicationBuilderExtensions.cs

@ -43,7 +43,10 @@ namespace Microsoft.Tye
}
else if (service is ContainerServiceBuilder container)
{
var dockerRunInfo = new DockerRunInfo(container.Image, container.Args);
var dockerRunInfo = new DockerRunInfo(container.Image, container.Args)
{
WorkingDirectory = container.WorkingDirectory
};
foreach (var mapping in container.Volumes)
{

24
src/tye/Program.RunCommand.cs

@ -7,6 +7,7 @@ using System.CommandLine;
using System.CommandLine.Invocation;
using System.CommandLine.IO;
using System.IO;
using System.Linq;
using System.Threading;
using Microsoft.Tye.ConfigModel;
using Microsoft.Tye.Extensions;
@ -64,7 +65,7 @@ namespace Microsoft.Tye
Required = false
});
command.Handler = CommandHandler.Create<IConsole, FileInfo, string[]>(async (console, path, debug) =>
command.Handler = CommandHandler.Create<IConsole, FileInfo, string[], bool, bool>(async (console, path, debug, docker, nobuild) =>
{
// Workaround for https://github.com/dotnet/command-line-api/issues/723#issuecomment-593062654
if (path is null)
@ -72,8 +73,25 @@ namespace Microsoft.Tye
throw new CommandException("No project or solution file was found.");
}
var output = new OutputContext(console, Verbosity.Quiet);
var application = await ApplicationFactory.CreateAsync(output, path);
// Populate project information if docker is false and we're not building
var populateProjectInformation = nobuild && !docker;
var output = new OutputContext(console, Verbosity.Debug);
var application = await ApplicationFactory.CreateAsync(output, path, populateProjectInformation);
if (docker)
{
if (!await application.TransformProjectsIntoContainersAync(output))
{
return;
}
}
else if (!populateProjectInformation)
{
if (!await application.BuildProjectsAsync(output))
{
return;
}
}
await application.ProcessExtensionsAsync(ExtensionContext.OperationKind.LocalRun);

29
test/E2ETest/TyeRunTests.cs

@ -61,7 +61,7 @@ namespace E2ETest
var client = new HttpClient(new RetryHandler(handler));
await RunHostingApplication(application, Array.Empty<string>(), async (app, uri) =>
await RunHostingApplication(application, outputContext, Array.Empty<string>(), async (app, uri) =>
{
var testUri = await GetServiceUrl(client, uri, "test-project");
@ -88,7 +88,7 @@ namespace E2ETest
var client = new HttpClient(new RetryHandler(handler));
await RunHostingApplication(application, Array.Empty<string>(), async (app, uri) =>
await RunHostingApplication(application, outputContext, Array.Empty<string>(), async (app, uri) =>
{
var frontendUri = await GetServiceUrl(client, uri, "frontend");
var backendUri = await GetServiceUrl(client, uri, "backend");
@ -119,7 +119,7 @@ namespace E2ETest
var client = new HttpClient(new RetryHandler(handler));
await RunHostingApplication(application, new[] { "--docker" }, async (app, uri) =>
await RunHostingApplication(application, outputContext, new[] { "--docker" }, async (app, uri) =>
{
// Make sure we're running containers
Assert.True(app.Services.All(s => s.Value.Description.RunInfo is DockerRunInfo));
@ -166,7 +166,7 @@ namespace E2ETest
var client = new HttpClient(new RetryHandler(handler));
await RunHostingApplication(application, Array.Empty<string>(), async (app, uri) =>
await RunHostingApplication(application, outputContext, Array.Empty<string>(), async (app, uri) =>
{
var frontendUri = await GetServiceUrl(client, uri, "frontend");
var backendUri = await GetServiceUrl(client, uri, "backend");
@ -210,7 +210,7 @@ namespace E2ETest
var client = new HttpClient(new RetryHandler(handler));
await RunHostingApplication(application, Array.Empty<string>(), async (app, uri) =>
await RunHostingApplication(application, outputContext, Array.Empty<string>(), async (app, uri) =>
{
var frontendUri = await GetServiceUrl(client, uri, "frontend");
var backendUri = await GetServiceUrl(client, uri, "backend");
@ -249,7 +249,7 @@ namespace E2ETest
var client = new HttpClient(new RetryHandler(handler));
var args = new[] { "--docker" };
await RunHostingApplication(application, args, async (app, serviceApi) =>
await RunHostingApplication(application, outputContext, args, async (app, serviceApi) =>
{
var serviceUri = await GetServiceUrl(client, serviceApi, "volume-test");
@ -264,7 +264,7 @@ namespace E2ETest
Assert.Equal("Things saved to the volume!", await client.GetStringAsync(serviceUri));
});
await RunHostingApplication(application, args, async (app, serviceApi) =>
await RunHostingApplication(application, outputContext, args, async (app, serviceApi) =>
{
var serviceUri = await GetServiceUrl(client, serviceApi, "volume-test");
@ -306,6 +306,7 @@ namespace E2ETest
{
await RunHostingApplication(
application,
outputContext,
new[] { "--docker" },
async (app, uri) =>
{
@ -358,6 +359,7 @@ namespace E2ETest
await RunHostingApplication(
application,
outputContext,
new[] { "--docker" },
async (app, uri) =>
{
@ -409,7 +411,7 @@ namespace E2ETest
var client = new HttpClient(new RetryHandler(handler));
var args = new[] { "--docker" };
await RunHostingApplication(application, args, async (app, serviceApi) =>
await RunHostingApplication(application, outputContext, args, async (app, serviceApi) =>
{
var serviceUri = await GetServiceUrl(client, serviceApi, "volume-test");
@ -437,7 +439,7 @@ namespace E2ETest
var client = new HttpClient(new RetryHandler(handler));
await RunHostingApplication(application, Array.Empty<string>(), async (app, uri) =>
await RunHostingApplication(application, outputContext, Array.Empty<string>(), async (app, uri) =>
{
var ingressUri = await GetServiceUrl(client, uri, "ingress");
var appAUri = await GetServiceUrl(client, uri, "appA");
@ -486,7 +488,7 @@ namespace E2ETest
var client = new HttpClient(new RetryHandler(handler));
await RunHostingApplication(application, Array.Empty<string>(), async (app, uri) =>
await RunHostingApplication(application, outputContext, Array.Empty<string>(), async (app, uri) =>
{
var nginxUri = await GetServiceUrl(client, uri, "nginx");
var appAUri = await GetServiceUrl(client, uri, "appA");
@ -534,8 +536,13 @@ namespace E2ETest
return $"{binding.Protocol ?? "http"}://localhost:{binding.Port}";
}
private async Task RunHostingApplication(ApplicationBuilder application, string[] args, Func<Application, Uri, Task> execute)
private async Task RunHostingApplication(ApplicationBuilder application, OutputContext outputContext, string[] args, Func<Application, Uri, Task> execute)
{
if (args.Contains("--docker"))
{
await application.TransformProjectsIntoContainersAync(outputContext);
}
await using var host = new TyeHost(application.ToHostingApplication(), args)
{
Sink = _sink,

1
test/UnitTests/TyeDeserializationTests.cs

@ -180,7 +180,6 @@ ingress:
.Single();
Assert.NotNull(otherService);
Assert.Equal(otherService.Args, service.Args);
Assert.Equal(otherService.Build, service.Build);
Assert.Equal(otherService.Executable, service.Executable);
Assert.Equal(otherService.External, service.External);
Assert.Equal(otherService.Image, service.Image);

Loading…
Cancel
Save