From bbef222754e024e10d3df0f456d450eeb05a85ab Mon Sep 17 00:00:00 2001 From: John Luo Date: Mon, 28 Sep 2020 14:07:56 -0700 Subject: [PATCH] Use out-of-proc MSBuild evaluation (#674) * Use out-of-proc MSBuild evaluation This allows for support for new SDKs/TFMs without needing tye to target those TFMs * Combine restore and metadata evaluation * Batch process projects --- clean.cmd | 3 + clean.ps1 | 42 ++++ clean.sh | 38 ++++ src/Microsoft.Tye.Core/ApplicationFactory.cs | 97 +++++++++- .../ConfigModel/ConfigService.cs | 1 + .../Microsoft.Tye.Core.csproj | 2 +- src/Microsoft.Tye.Core/ProjectReader.cs | 180 ++++-------------- .../Microsoft.Tye.Extensions.csproj | 2 +- .../Microsoft.Tye.Hosting.Diagnostics.csproj | 2 +- .../Microsoft.Tye.Hosting.csproj | 4 +- src/tye-diag-agent/tye-diag-agent.csproj | 2 +- src/tye/ProjectEvaluation.targets | 40 ++++ src/tye/tye.csproj | 6 +- test/E2ETest/ApplicationFactoryTests.cs | 4 +- test/E2ETest/Microsoft.Tye.E2ETests.csproj | 2 +- ....Tye.Extensions.Configuration.Tests.csproj | 2 +- .../Test.Infrastructure.csproj | 2 +- test/UnitTests/Microsoft.Tye.UnitTests.csproj | 2 +- 18 files changed, 267 insertions(+), 164 deletions(-) create mode 100644 clean.cmd create mode 100644 clean.ps1 create mode 100644 clean.sh create mode 100644 src/tye/ProjectEvaluation.targets diff --git a/clean.cmd b/clean.cmd new file mode 100644 index 00000000..9442e584 --- /dev/null +++ b/clean.cmd @@ -0,0 +1,3 @@ +@ECHO OFF +SETLOCAL +PowerShell -NoProfile -NoLogo -ExecutionPolicy ByPass -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = ''; try { & '%~dp0clean.ps1' %*; exit $LASTEXITCODE } catch { write-host $_; exit 1 }" diff --git a/clean.ps1 b/clean.ps1 new file mode 100644 index 00000000..955b03c4 --- /dev/null +++ b/clean.ps1 @@ -0,0 +1,42 @@ +#requires -version 5 + +<# +.SYNOPSIS +Clean this repository. + +.DESCRIPTION +This script cleans this repository interactively, leaving downloaded infrastructure untouched. +Clean operation is interactive to avoid losing new but unstaged files. Press 'c' then [Enter] +to perform the proposed deletions. + +.EXAMPLE +Perform default clean operation. + + clean.ps1 + +.EXAMPLE +Clean everything but downloaded infrastructure and VS / VS Code folders. + + clean.ps1 -e .vs/ -e .vscode/ +#> + +[CmdletBinding(PositionalBinding = $false)] +param( + # Other lifecycle targets + [switch]$Help, # Show help + + # Capture the rest + [Parameter(ValueFromRemainingArguments = $true)] + [string[]]$GitArguments +) + +Set-StrictMode -Version 2 +$ErrorActionPreference = 'Stop' + +if ($Help) { + Get-Help $PSCommandPath + exit 0 +} + +git clean -dix -e .dotnet/ -e .tools/ @GitArguments +git checkout -- $(git ls-files -d) diff --git a/clean.sh b/clean.sh new file mode 100644 index 00000000..e52a5602 --- /dev/null +++ b/clean.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +set -euo pipefail + +# +# Functions +# +__usage() { + echo "Usage: $(basename "${BASH_SOURCE[0]}") + +Arguments: + ... Arguments passed to the 'git' command. Any number of arguments allowed. + +Description: + This script cleans the repository interactively, leaving downloaded infrastructure untouched. + Clean operation is interactive to avoid losing new but unstaged files. Press 'c' then [Enter] + to perform the proposed deletions. +" +} + +git_args=() + +while [[ $# -gt 0 ]]; do + case $1 in + -\?|-h|--help) + __usage + exit 0 + ;; + *) + git_args[${#git_args[*]}]="$1" + ;; + esac + shift +done + +# This incantation avoids unbound variable issues if git_args is empty +# https://stackoverflow.com/questions/7577052/bash-empty-array-expansion-with-set-u +git clean -dix -e .dotnet/ -e .tools/ ${git_args[@]+"${git_args[@]}"} diff --git a/src/Microsoft.Tye.Core/ApplicationFactory.cs b/src/Microsoft.Tye.Core/ApplicationFactory.cs index 7fe7cc39..9e34cd87 100644 --- a/src/Microsoft.Tye.Core/ApplicationFactory.cs +++ b/src/Microsoft.Tye.Core/ApplicationFactory.cs @@ -4,9 +4,12 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; +using System.Reflection; using System.Runtime.InteropServices; +using System.Text; using System.Threading.Tasks; using Microsoft.Tye.ConfigModel; @@ -74,6 +77,88 @@ namespace Microsoft.Tye config.Services.Where(filter.ServicesFilter).ToList() : config.Services; + var sw = Stopwatch.StartNew(); + // Project services will be restored and evaluated before resolving all other services. + // This batching will mitigate the performance cost of running MSBuild out of process. + var projectServices = services.Where(s => !string.IsNullOrEmpty(s.Project)); + var projectMetadata = new Dictionary(); + + using (var directory = TempDirectory.Create()) + { + var projectPath = Path.Combine(directory.DirectoryPath, Path.GetRandomFileName() + ".proj"); + + var sb = new StringBuilder(); + sb.AppendLine(""); + sb.AppendLine(" "); + + foreach (var project in projectServices) + { + var expandedProject = Environment.ExpandEnvironmentVariables(project.Project!); + project.ProjectFullPath = Path.Combine(config.Source.DirectoryName!, expandedProject); + + if (!File.Exists(project.ProjectFullPath)) + { + throw new CommandException($"Failed to locate project: '{project.ProjectFullPath}'."); + } + + sb.AppendLine($" $"{kvp.Name}={kvp.Value}").Aggregate((a, b) => a + ";" + b) : string.Empty)}\" />"); + } + sb.AppendLine(@" "); + + sb.AppendLine($@" "); + sb.AppendLine($@" "); + + sb.AppendLine(" "); + sb.AppendLine(""); + File.WriteAllText(projectPath, sb.ToString()); + + output.WriteDebugLine("Restoring and evaluating projects"); + + var msbuildEvaluationResult = await ProcessUtil.RunAsync( + "dotnet", + $"build " + + $"\"{projectPath}\" " + + $"/p:CustomAfterMicrosoftCommonTargets={Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, "ProjectEvaluation.targets")} " + + $"/nologo", + throwOnError: false, + workingDirectory: directory.DirectoryPath); + + // 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 + // running these targets we don't really care as long as we get the data. + if (msbuildEvaluationResult.ExitCode != 0) + { + output.WriteDebugLine($"Evaluating project failed with exit code {msbuildEvaluationResult.ExitCode}:" + + $"{Environment.NewLine}Ouptut: {msbuildEvaluationResult.StandardOutput}" + + $"{Environment.NewLine}Error: {msbuildEvaluationResult.StandardError}"); + } + + var msbuildEvaluationOutput = msbuildEvaluationResult + .StandardOutput + .Split(Environment.NewLine); + + foreach (var line in msbuildEvaluationOutput) + { + if (line.Trim().StartsWith("Microsoft.Tye metadata: ")) + { + var values = line.Split(':', 3); + var projectName = values[1].Trim(); + var metadataPath = values[2].Trim(); + projectMetadata.Add(projectName, metadataPath); + + output.WriteDebugLine($"Resolved metadata for service {projectName} at {metadataPath}"); + } + } + + output.WriteDebugLine($"Restore and project evaluation took: {sw.Elapsed.TotalMilliseconds}ms"); + } + foreach (var configService in services) { ServiceBuilder service; @@ -87,9 +172,7 @@ namespace Microsoft.Tye if (!string.IsNullOrEmpty(configService.Project)) { - var expandedProject = Environment.ExpandEnvironmentVariables(configService.Project); - var projectFile = new FileInfo(Path.Combine(config.Source.DirectoryName!, expandedProject)); - var project = new DotnetProjectServiceBuilder(configService.Name!, projectFile); + var project = new DotnetProjectServiceBuilder(configService.Name!, new FileInfo(configService.ProjectFullPath)); service = project; project.Build = configService.Build ?? true; @@ -107,7 +190,13 @@ namespace Microsoft.Tye // to prompt for the registry name. project.ContainerInfo = new ContainerInfo() { UseMultiphaseDockerfile = false, }; - await ProjectReader.ReadProjectDetailsAsync(output, project); + // If project evaluation is successful this should not happen, therefore an exception will be thrown. + if (!projectMetadata.ContainsKey(configService.Name)) + { + throw new CommandException($"Evaluated project metadata file could not be found for service {configService.Name}"); + } + + ProjectReader.ReadProjectDetails(output, project, projectMetadata[configService.Name]); // Do k8s by default. project.ManifestInfo = new KubernetesManifestInfo(); diff --git a/src/Microsoft.Tye.Core/ConfigModel/ConfigService.cs b/src/Microsoft.Tye.Core/ConfigModel/ConfigService.cs index aabebe9f..a131f937 100644 --- a/src/Microsoft.Tye.Core/ConfigModel/ConfigService.cs +++ b/src/Microsoft.Tye.Core/ConfigModel/ConfigService.cs @@ -25,6 +25,7 @@ namespace Microsoft.Tye.ConfigModel public Dictionary DockerFileArgs { get; set; } = new Dictionary(); public string? DockerFileContext { get; set; } public string? Project { get; set; } + public string? ProjectFullPath { get; set; } public string? Include { get; set; } public string? Repository { get; set; } public bool? Build { get; set; } diff --git a/src/Microsoft.Tye.Core/Microsoft.Tye.Core.csproj b/src/Microsoft.Tye.Core/Microsoft.Tye.Core.csproj index 79d85550..6b5f88c4 100644 --- a/src/Microsoft.Tye.Core/Microsoft.Tye.Core.csproj +++ b/src/Microsoft.Tye.Core/Microsoft.Tye.Core.csproj @@ -1,7 +1,7 @@  - net5.0 + netcoreapp3.1 Tye Microsoft.Tye.Core Microsoft.Tye.Core diff --git a/src/Microsoft.Tye.Core/ProjectReader.cs b/src/Microsoft.Tye.Core/ProjectReader.cs index e2203c4d..3fe82da1 100644 --- a/src/Microsoft.Tye.Core/ProjectReader.cs +++ b/src/Microsoft.Tye.Core/ProjectReader.cs @@ -10,15 +10,9 @@ using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Runtime.Loader; using System.Threading.Tasks; using Microsoft.Build.Construction; -using Microsoft.Build.Definition; -using Microsoft.Build.Evaluation; -using Microsoft.Build.Execution; -using Microsoft.Build.Framework; using Microsoft.Build.Locator; -using Microsoft.Build.Logging; using Semver; namespace Microsoft.Tye @@ -61,7 +55,7 @@ namespace Microsoft.Tye } } - public static Task ReadProjectDetailsAsync(OutputContext output, DotnetProjectServiceBuilder project) + public static void ReadProjectDetails(OutputContext output, DotnetProjectServiceBuilder project, string metadataFile) { if (output is null) { @@ -73,14 +67,12 @@ namespace Microsoft.Tye throw new ArgumentNullException(nameof(project)); } - if (!Directory.Exists(project.ProjectFile.DirectoryName)) + if (project is null) { - throw new CommandException($"Failed to locate directory: '{project.ProjectFile.DirectoryName}'."); + throw new ArgumentNullException(nameof(metadataFile)); } - EnsureMSBuildRegistered(output, project.ProjectFile); - - EvaluateProject(output, project); + EvaluateProject(output, project, metadataFile); if (!SemVersion.TryParse(project.Version, out var version)) { @@ -88,8 +80,6 @@ namespace Microsoft.Tye version = new SemVersion(0, 1, 0); project.Version = version.ToString(); } - - return Task.CompletedTask; } private static void EnsureMSBuildRegistered(OutputContext? output, FileInfo projectFile) @@ -138,118 +128,40 @@ namespace Microsoft.Tye } } - [MethodImpl(MethodImplOptions.NoInlining)] - private static void LogIt(OutputContext output) - { - output.WriteDebugLine("Loaded: " + typeof(ProjectInstance).Assembly.FullName); - output.WriteDebugLine("Loaded From: " + typeof(ProjectInstance).Assembly.Location); - } - // Do not load MSBuild types before using EnsureMSBuildRegistered. [MethodImpl(MethodImplOptions.NoInlining)] - private static void EvaluateProject(OutputContext output, DotnetProjectServiceBuilder project) + private static void EvaluateProject(OutputContext output, DotnetProjectServiceBuilder project, string metadataFile) { var sw = Stopwatch.StartNew(); - // Currently we only log at debug level. - var logger = new ConsoleLogger( - verbosity: LoggerVerbosity.Normal, - write: message => output.WriteDebug(message), - colorSet: null, - colorReset: null); - - // We need to isolate projects from each other for testing. MSBuild does not support - // loading the same project twice in the same collection. - var projectCollection = new ProjectCollection(); - - ProjectInstance projectInstance; - Microsoft.Build.Evaluation.Project msbuildProject; + var metadata = new Dictionary(); + var metadataKVPs = File.ReadLines(metadataFile).Select(l => l.Split(new[] { ':' }, 2)); - try + foreach (var metadataKVP in metadataKVPs) { - output.WriteDebugLine($"Loading project '{project.ProjectFile.FullName}'."); - msbuildProject = Microsoft.Build.Evaluation.Project.FromFile(project.ProjectFile.FullName, new ProjectOptions() - { - ProjectCollection = projectCollection, - GlobalProperties = project.BuildProperties - }); - projectInstance = msbuildProject.CreateProjectInstance(); - output.WriteDebugLine($"Loaded project '{project.ProjectFile.FullName}'."); - } - catch (Exception ex) - { - throw new CommandException($"Failed to load project: '{project.ProjectFile.FullName}'.", ex); - } - - try - { - AssemblyLoadContext.Default.Resolving += ResolveAssembly; - - output.WriteDebugLine($"Restoring project '{project.ProjectFile.FullName}'."); - - // Similar to what MSBuild does for restore: - // https://github.com/microsoft/msbuild/blob/3453beee039fb6f5ccc54ac783ebeced31fec472/src/MSBuild/XMake.cs#L1417 - // - // We need to do restore as a separate operation - var restoreRequest = new BuildRequestData( - projectInstance, - targetsToBuild: new[] { "Restore" }, - hostServices: null, - flags: BuildRequestDataFlags.ClearCachesAfterBuild | BuildRequestDataFlags.SkipNonexistentTargets | BuildRequestDataFlags.IgnoreMissingEmptyAndInvalidImports); - - var parameters = new BuildParameters(projectCollection) + if (!string.IsNullOrEmpty(metadataKVP[1])) { - Loggers = new[] { logger, }, - }; - - // We don't really look at the result, because it's not clear we should halt totally - // if restore fails. - var restoreResult = BuildManager.DefaultBuildManager.Build(parameters, restoreRequest); - output.WriteDebugLine($"Restored project '{project.ProjectFile.FullName}'."); - - msbuildProject.MarkDirty(); - projectInstance = msbuildProject.CreateProjectInstance(); - - var targets = new List() - { - "ResolveReferences", - "ResolvePackageDependenciesDesignTime", - "PrepareResources", - "GetAssemblyAttributes", - }; - - var result = projectInstance.Build( - targets: targets.ToArray(), - 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 - // running these targets we don't really care as long as we get the data. - } - finally - { - AssemblyLoadContext.Default.Resolving -= ResolveAssembly; + metadata.Add(metadataKVP[0], metadataKVP[1].Trim()); + } } // Reading a few different version properties to be more resilient. - var version = - projectInstance.GetProperty("AssemblyInformationalVersion")?.EvaluatedValue ?? - projectInstance.GetProperty("InformationalVersion")?.EvaluatedValue ?? - projectInstance.GetProperty("Version").EvaluatedValue; + var version = GetMetadataValueOrNull("AssemblyInformationalVersion") ?? + GetMetadataValueOrNull("InformationalVersion") ?? + GetMetadataValueOrEmpty("Version"); project.Version = version; output.WriteDebugLine($"Found application version: {version}"); - var targetFrameworks = projectInstance.GetPropertyValue("TargetFrameworks"); - project.TargetFrameworks = targetFrameworks.Split(';', StringSplitOptions.RemoveEmptyEntries) ?? Array.Empty(); + project.TargetFrameworks = GetMetadataValueOrNull("TargetFrameworks")?.Split(';', StringSplitOptions.RemoveEmptyEntries) ?? Array.Empty(); // Figure out if functions app. // If so, run app with function host. - project.RunCommand = projectInstance.GetPropertyValue("RunCommand"); - project.RunArguments = projectInstance.GetPropertyValue("RunArguments"); - project.TargetPath = projectInstance.GetPropertyValue("TargetPath"); - project.PublishDir = projectInstance.GetPropertyValue("PublishDir"); - project.AssemblyName = projectInstance.GetPropertyValue("AssemblyName"); - project.IntermediateOutputPath = projectInstance.GetPropertyValue("IntermediateOutputPath"); + project.RunCommand = GetMetadataValueOrEmpty("RunCommand"); + project.RunArguments = GetMetadataValueOrEmpty("RunArguments"); + project.TargetPath = GetMetadataValueOrEmpty("TargetPath"); + project.PublishDir = GetMetadataValueOrEmpty("PublishDir"); + project.AssemblyName = GetMetadataValueOrEmpty("AssemblyName"); + project.IntermediateOutputPath = GetMetadataValueOrEmpty("IntermediateOutputPath"); output.WriteDebugLine($"RunCommand={project.RunCommand}"); output.WriteDebugLine($"RunArguments={project.RunArguments}"); @@ -263,63 +175,37 @@ namespace Microsoft.Tye project.TargetPath = Path.Combine(project.ProjectFile.DirectoryName!, NormalizePath(project.TargetPath)); project.PublishDir = Path.Combine(project.ProjectFile.DirectoryName!, NormalizePath(project.PublishDir)); - var targetFramework = projectInstance.GetPropertyValue("TargetFramework"); + var targetFramework = GetMetadataValueOrEmpty("TargetFramework"); project.TargetFramework = targetFramework; output.WriteDebugLine($"Found target framework: {targetFramework}"); // TODO: Parse the name and version manually out of the TargetFramework field if it's non-null - project.TargetFrameworkName = projectInstance.GetPropertyValue("_ShortFrameworkIdentifier"); - project.TargetFrameworkVersion = projectInstance.GetPropertyValue("_ShortFrameworkVersion") ?? projectInstance.GetPropertyValue("_TargetFrameworkVersionWithoutV"); + project.TargetFrameworkName = GetMetadataValueOrEmpty("_ShortFrameworkIdentifier"); + project.TargetFrameworkVersion = GetMetadataValueOrNull("_ShortFrameworkVersion") ?? GetMetadataValueOrEmpty("_TargetFrameworkVersionWithoutV"); - var sharedFrameworks = projectInstance.GetItems("FrameworkReference").Select(i => i.EvaluatedInclude).ToList(); + var sharedFrameworks = GetMetadataValueOrNull("FrameworkReference")?.Split(';') ?? Enumerable.Empty(); project.Frameworks.AddRange(sharedFrameworks.Select(s => new Framework(s))); output.WriteDebugLine($"Found shared frameworks: {string.Join(", ", sharedFrameworks)}"); // determine container base image if (project.ContainerInfo != null) { - project.ContainerInfo.BaseImageName = projectInstance.GetPropertyValue("ContainerBaseImage"); - project.ContainerInfo.BaseImageTag = projectInstance.GetPropertyValue("ContainerBaseTag"); - } - - bool PropertyIsTrue(string property) - { - return projectInstance.GetPropertyValue(property) is string s && !string.IsNullOrEmpty(s) && bool.Parse(s); + project.ContainerInfo.BaseImageName = GetMetadataValueOrEmpty("ContainerBaseImage"); + project.ContainerInfo.BaseImageTag = GetMetadataValueOrEmpty("ContainerBaseTag"); } project.IsAspNet = project.Frameworks.Any(f => f.Name == "Microsoft.AspNetCore.App") || - projectInstance.GetPropertyValue("MicrosoftNETPlatformLibrary") == "Microsoft.AspNetCore.App" || - PropertyIsTrue("_AspNetCoreAppSharedFxIsEnabled") || - PropertyIsTrue("UsingMicrosoftNETSdkWeb"); + GetMetadataValueOrEmpty("MicrosoftNETPlatformLibrary") == "Microsoft.AspNetCore.App" || + MetadataIsTrue("_AspNetCoreAppSharedFxIsEnabled") || + MetadataIsTrue("UsingMicrosoftNETSdkWeb"); output.WriteDebugLine($"IsAspNet={project.IsAspNet}"); output.WriteDebugLine($"Evaluation Took: {sw.Elapsed.TotalMilliseconds}ms"); - // The Microsoft.Build.Locator doesn't handle the loading of other assemblies - // that are shipped with MSBuild (ex NuGet). - // - // This means that the set of assemblies that need special handling depends on the targets - // that we run :( - // - // This is workaround for this limitation based on the targets we need to run - // to resolve references and versions. - // - // See: https://github.com/microsoft/MSBuildLocator/issues/86 - Assembly? ResolveAssembly(AssemblyLoadContext context, AssemblyName assemblyName) - { - if (assemblyName.Name is object) - { - var msbuildDirectory = Environment.GetEnvironmentVariable("MSBuildExtensionsPath")!; - var assemblyFilePath = Path.Combine(msbuildDirectory, assemblyName.Name + ".dll"); - if (File.Exists(assemblyFilePath)) - { - return context.LoadFromAssemblyPath(assemblyFilePath); - } - } - - return default; - } + string? GetMetadataValueOrNull(string key) => metadata!.TryGetValue(key, out var value) ? value : null; + string GetMetadataValueOrEmpty(string key) => metadata!.TryGetValue(key, out var value) ? value : string.Empty; + bool MetadataIsTrue(string key) => metadata!.TryGetValue(key, out var value) && bool.Parse(value); } private static string NormalizePath(string path) diff --git a/src/Microsoft.Tye.Extensions/Microsoft.Tye.Extensions.csproj b/src/Microsoft.Tye.Extensions/Microsoft.Tye.Extensions.csproj index 979268cd..0ca4ab55 100644 --- a/src/Microsoft.Tye.Extensions/Microsoft.Tye.Extensions.csproj +++ b/src/Microsoft.Tye.Extensions/Microsoft.Tye.Extensions.csproj @@ -1,7 +1,7 @@ - net5.0 + netcoreapp3.1 diff --git a/src/Microsoft.Tye.Hosting.Diagnostics/Microsoft.Tye.Hosting.Diagnostics.csproj b/src/Microsoft.Tye.Hosting.Diagnostics/Microsoft.Tye.Hosting.Diagnostics.csproj index d0f0afb5..3b0db741 100644 --- a/src/Microsoft.Tye.Hosting.Diagnostics/Microsoft.Tye.Hosting.Diagnostics.csproj +++ b/src/Microsoft.Tye.Hosting.Diagnostics/Microsoft.Tye.Hosting.Diagnostics.csproj @@ -1,7 +1,7 @@  - net5.0 + netcoreapp3.1 Diagnostics collector and exporter for .NET Core applications. Microsoft.Tye.Hosting.Diagnostics Microsoft.Tye.Hosting.Diagnostics diff --git a/src/Microsoft.Tye.Hosting/Microsoft.Tye.Hosting.csproj b/src/Microsoft.Tye.Hosting/Microsoft.Tye.Hosting.csproj index 97a6f467..9e26f6f2 100644 --- a/src/Microsoft.Tye.Hosting/Microsoft.Tye.Hosting.csproj +++ b/src/Microsoft.Tye.Hosting/Microsoft.Tye.Hosting.csproj @@ -2,7 +2,7 @@ Library - net5.0 + netcoreapp3.1 Orchestration host APIs. Microsoft.Tye.Hosting Microsoft.Tye.Hosting @@ -17,7 +17,7 @@ - + diff --git a/src/tye-diag-agent/tye-diag-agent.csproj b/src/tye-diag-agent/tye-diag-agent.csproj index 53b67503..6278740f 100644 --- a/src/tye-diag-agent/tye-diag-agent.csproj +++ b/src/tye-diag-agent/tye-diag-agent.csproj @@ -1,7 +1,7 @@ - net5.0 + netcoreapp3.1 Microsoft.Tye diff --git a/src/tye/ProjectEvaluation.targets b/src/tye/ProjectEvaluation.targets new file mode 100644 index 00000000..fbcdd7f6 --- /dev/null +++ b/src/tye/ProjectEvaluation.targets @@ -0,0 +1,40 @@ + + + + <_MicrosoftTye_MetadataFile>$([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)MicrosoftTye.ProjectMetadata.txt')) + <_MicrosoftTye_ProjectFrameworkReference>@(FrameworkReference, '%3B') + + + + <_MicrosoftTye_ProjectMetadata Include="AssemblyInformationalVersion: $(AssemblyInformationalVersion)" /> + <_MicrosoftTye_ProjectMetadata Include="InformationalVersion: $(InformationalVersion)" /> + <_MicrosoftTye_ProjectMetadata Include="Version: $(Version)" /> + <_MicrosoftTye_ProjectMetadata Include="TargetFrameworks: $(TargetFrameworks)" /> + <_MicrosoftTye_ProjectMetadata Include="RunCommand: $(RunCommand)" /> + <_MicrosoftTye_ProjectMetadata Include="RunArguments: $(RunArguments)" /> + <_MicrosoftTye_ProjectMetadata Include="TargetPath: $(TargetPath)" /> + <_MicrosoftTye_ProjectMetadata Include="PublishDir: $(PublishDir)" /> + <_MicrosoftTye_ProjectMetadata Include="AssemblyName: $(AssemblyName)" /> + <_MicrosoftTye_ProjectMetadata Include="IntermediateOutputPath: $(IntermediateOutputPath)" /> + <_MicrosoftTye_ProjectMetadata Include="TargetFramework: $(TargetFramework)" /> + <_MicrosoftTye_ProjectMetadata Include="_ShortFrameworkIdentifier: $(_ShortFrameworkIdentifier)" /> + <_MicrosoftTye_ProjectMetadata Include="_ShortFrameworkVersion: $(_ShortFrameworkVersion)" /> + <_MicrosoftTye_ProjectMetadata Include="_TargetFrameworkVersionWithoutV: $(_TargetFrameworkVersionWithoutV)" /> + <_MicrosoftTye_ProjectMetadata Include="FrameworkReference: $(_MicrosoftTye_ProjectFrameworkReference)" /> + <_MicrosoftTye_ProjectMetadata Include="ContainerBaseImage: $(ContainerBaseImage)" /> + <_MicrosoftTye_ProjectMetadata Include="ContainerBaseTag: $(ContainerBaseTag)" /> + <_MicrosoftTye_ProjectMetadata Include="MicrosoftNETPlatformLibrary: $(MicrosoftNETPlatformLibrary)" /> + <_MicrosoftTye_ProjectMetadata Include="_AspNetCoreAppSharedFxIsEnabled: $(_AspNetCoreAppSharedFxIsEnabled)" /> + <_MicrosoftTye_ProjectMetadata Include="UsingMicrosoftNETSdkWeb: $(UsingMicrosoftNETSdkWeb)" /> + + + + + + + + \ No newline at end of file diff --git a/src/tye/tye.csproj b/src/tye/tye.csproj index 27957d32..16cef0c8 100644 --- a/src/tye/tye.csproj +++ b/src/tye/tye.csproj @@ -2,7 +2,7 @@ Exe - net5.0 + netcoreapp3.1 Microsoft.Tye tye Microsoft.Tye @@ -10,6 +10,10 @@ true + + + + diff --git a/test/E2ETest/ApplicationFactoryTests.cs b/test/E2ETest/ApplicationFactoryTests.cs index b32f7261..c9fc7071 100644 --- a/test/E2ETest/ApplicationFactoryTests.cs +++ b/test/E2ETest/ApplicationFactoryTests.cs @@ -118,8 +118,8 @@ services: var exception = await Assert.ThrowsAsync(async () => await ApplicationFactory.CreateAsync(outputContext, projectFile)); - var wrongProjectPath = Path.Combine(projectDirectory.DirectoryPath, "backend1"); - Assert.Equal($"Failed to locate directory: '{wrongProjectPath}'.", exception.Message); + var wrongProjectPath = Path.Combine(projectDirectory.DirectoryPath, "backend1/backend.csproj"); + Assert.Equal($"Failed to locate project: '{wrongProjectPath}'.", exception.Message); } } } diff --git a/test/E2ETest/Microsoft.Tye.E2ETests.csproj b/test/E2ETest/Microsoft.Tye.E2ETests.csproj index 4e6cb53e..c1106d7e 100644 --- a/test/E2ETest/Microsoft.Tye.E2ETests.csproj +++ b/test/E2ETest/Microsoft.Tye.E2ETests.csproj @@ -2,7 +2,7 @@ - net5.0 + netcoreapp3.1 Microsoft.Tye.E2ETest true true diff --git a/test/Microsoft.Tye.Extensions.Configuration.Tests/Microsoft.Tye.Extensions.Configuration.Tests.csproj b/test/Microsoft.Tye.Extensions.Configuration.Tests/Microsoft.Tye.Extensions.Configuration.Tests.csproj index 16490ce8..dffc8b0d 100644 --- a/test/Microsoft.Tye.Extensions.Configuration.Tests/Microsoft.Tye.Extensions.Configuration.Tests.csproj +++ b/test/Microsoft.Tye.Extensions.Configuration.Tests/Microsoft.Tye.Extensions.Configuration.Tests.csproj @@ -1,7 +1,7 @@ - net5.0 + netcoreapp3.1 true diff --git a/test/Test.Infrastructure/Test.Infrastructure.csproj b/test/Test.Infrastructure/Test.Infrastructure.csproj index 9a82f29a..8cc2cfb9 100644 --- a/test/Test.Infrastructure/Test.Infrastructure.csproj +++ b/test/Test.Infrastructure/Test.Infrastructure.csproj @@ -1,7 +1,7 @@  - net5.0 + netcoreapp3.1 false XUnit disable diff --git a/test/UnitTests/Microsoft.Tye.UnitTests.csproj b/test/UnitTests/Microsoft.Tye.UnitTests.csproj index 72487d8b..cda06b56 100644 --- a/test/UnitTests/Microsoft.Tye.UnitTests.csproj +++ b/test/UnitTests/Microsoft.Tye.UnitTests.csproj @@ -1,7 +1,7 @@ - net5.0 + netcoreapp3.1 Microsoft.Tye.UnitTests true true