diff --git a/docs/list-of-diagnostics.md b/docs/list-of-diagnostics.md index de9870c99cb..d47feae2d76 100644 --- a/docs/list-of-diagnostics.md +++ b/docs/list-of-diagnostics.md @@ -10,6 +10,7 @@ | `ASPIRE004` | Warning | '\[ProjectName\]' is referenced by an Aspire Host project, but it is not an executable. Did you mean to set IsAspireProjectResource="false"? | [src/Aspire.Hosting.AppHost/build/Aspire.Hosting.AppHost.in.targets](../src/Aspire.Hosting.AppHost/build/Aspire.Hosting.AppHost.in.targets) | | `ASPIRE005` | Error | (Deprecated) This diagnostic is no longer used. | | | `ASPIRE007` | Error | '\[ProjectName\]' project requires a reference to "Aspire.AppHost.Sdk" with version "9.0.0" or greater to work correctly. Please add the following line after the Project declaration ``. | [src/Aspire.Hosting.AppHost/build/Aspire.Hosting.AppHost.in.targets](../src/Aspire.Hosting.AppHost/build/Aspire.Hosting.AppHost.in.targets) | +| `ASPIRE008` | Error | '\[ProjectName\]' project requires GenerateAssemblyInfo to be enabled. The Aspire AppHost relies on assembly metadata attributes to locate required dependencies. Please remove <GenerateAssemblyInfo>false</GenerateAssemblyInfo> from your project file or set it to true. | [src/Aspire.Hosting.AppHost/build/Aspire.Hosting.AppHost.in.targets](../src/Aspire.Hosting.AppHost/build/Aspire.Hosting.AppHost.in.targets) | ## Analyzer Warnings diff --git a/src/Aspire.Hosting.AppHost/build/Aspire.Hosting.AppHost.in.targets b/src/Aspire.Hosting.AppHost/build/Aspire.Hosting.AppHost.in.targets index 1a4abcfb0ee..6dc900c6f83 100644 --- a/src/Aspire.Hosting.AppHost/build/Aspire.Hosting.AppHost.in.targets +++ b/src/Aspire.Hosting.AppHost/build/Aspire.Hosting.AppHost.in.targets @@ -268,6 +268,14 @@ namespace Projects%3B HelpLink="https://aka.ms/aspire/diagnostics/aspire007" /> + + + + diff --git a/tests/Aspire.Hosting.Tests/MSBuildTests.cs b/tests/Aspire.Hosting.Tests/MSBuildTests.cs index 8969f620382..fbbd5a657a8 100644 --- a/tests/Aspire.Hosting.Tests/MSBuildTests.cs +++ b/tests/Aspire.Hosting.Tests/MSBuildTests.cs @@ -370,4 +370,88 @@ the Aspire.AppHost.SDK targets that will automatically add these references to p // and ASPIRE004 warning should be emitted for the Library project reference Assert.Contains("warning ASPIRE004", output); } + + /// + /// Tests that when GenerateAssemblyInfo is set to false, a build error is emitted. + /// + [Fact] + public void GenerateAssemblyInfoFalse_EmitsError() + { + var repoRoot = MSBuildUtils.GetRepoRoot(); + using var tempDirectory = new TestTempDirectory(); + + var appHostDirectory = Path.Combine(tempDirectory.Path, "AppHost"); + Directory.CreateDirectory(appHostDirectory); + + File.WriteAllText(Path.Combine(appHostDirectory, "AppHost.csproj"), + $""" + + + + Exe + net8.0 + enable + enable + true + false + + + true + 9.0.0 + <_AspireUseTaskHostFactory>true + + + + + + + + """); + + File.WriteAllText(Path.Combine(appHostDirectory, "AppHost.cs"), + """ + var builder = DistributedApplication.CreateBuilder(); + builder.Build().Run(); + """); + + CreateDirectoryBuildFiles(appHostDirectory, repoRoot); + + // Build should fail + var output = new StringBuilder(); + var outputDone = new ManualResetEvent(false); + using var process = new Process(); + process.StartInfo = new ProcessStartInfo("dotnet", "build --disable-build-servers") + { + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true, + WorkingDirectory = appHostDirectory + }; + process.OutputDataReceived += (sender, e) => + { + if (e.Data == null) + { + outputDone.Set(); + } + else + { + output.AppendLine(e.Data); + } + }; + process.Start(); + process.BeginOutputReadLine(); + + Assert.True(process.WaitForExit(milliseconds: 180_000), "dotnet build command timed out after 3 minutes."); + Assert.True(outputDone.WaitOne(millisecondsTimeout: 60_000), "Timed out waiting for output to complete."); + + var buildOutput = output.ToString(); + + // Build should fail with ASPIRE008 error + Assert.NotEqual(0, process.ExitCode); + Assert.Contains("error ASPIRE008", buildOutput); + Assert.Contains("GenerateAssemblyInfo", buildOutput); + } }