rr-wfm / MSBuild.Sdk.SqlProj

An MSBuild SDK that provides similar functionality to SQL Server Data Tools (.sqlproj) projects
MIT License
408 stars 46 forks source link

References to non .dacpac files should be validated #119

Closed knoxi closed 3 years ago

knoxi commented 3 years ago

I'm getting an exception building the dacpac. It looks like it's an error while calling a library by reflection.

Any idea how to dive into this and fix or workaround it?

2>    dotnet "C:\Users\User\.nuget\packages\msbuild.sdk.sqlproj\1.11.1\Sdk\../tools/netcoreapp5.0/DacpacTool.dll" build -o "obj\Debug\netstandard2.0\Scripts.Sample.Build.dacpac" -n "Scripts.Sample.Build" -v "1.0.0" -sv Sql130 -i "obj\Debug\netstandard2.0\Scripts.Sample.Build.InputFiles.txt" -r "C:\Repos\Scripts\bin\Debug\netstandard2.0\Scripts.dll;"   --predeploy Scripts\Script.PreDeployment.sql --postdeploy Scripts\Script.PostDeployment.sql --refactorlog ..\Scripts.Sample\Scripts.Sample.refactorlog
2>    Using package name Scripts.Sample.Build and version 1.0.0
2>    Using SQL Server version Sql130
2>    Adding reference to C:\Repos\Scripts\bin\Debug\netstandard2.0\Scripts.dll
2>    Unhandled exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
2>     ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
2>     ---> Microsoft.Data.Tools.Schema.SchemaModel.DataSchemaModelException: Failed to load C:\Repos\Scripts\bin\Debug\netstandard2.0\Scripts.dll.
2>     ---> Microsoft.Data.Tools.Schema.Sql.Build.SqlPackageException: End of Central Directory record could not be found.
2>     ---> System.IO.InvalidDataException: End of Central Directory record could not be found.
2>       at System.IO.Compression.ZipArchive.ReadEndOfCentralDirectory()
2>       at System.IO.Compression.ZipArchive..ctor(Stream stream, ZipArchiveMode mode, Boolean leaveOpen, Encoding entryNameEncoding)
2>       at System.IO.Packaging.ZipPackage..ctor(String path, FileMode packageFileMode, FileAccess packageFileAccess, FileShare share)
2>       at System.IO.Packaging.Package.Open(String path, FileMode packageMode, FileAccess packageAccess, FileShare packageShare)
2>       at Microsoft.Data.Tools.Schema.Sql.Build.SqlPackage.Artifact.InitializefromFile(FileInfo fileInfo, FileMode mode, FileAccess access)
2>       --- End of inner exception stack trace ---
2>       at Microsoft.Data.Tools.Schema.Sql.Build.SqlPackage.Artifact.InitializefromFile(FileInfo fileInfo, FileMode mode, FileAccess access)
2>       at Microsoft.Data.Tools.Schema.Sql.Build.SqlPackage.Artifact..ctor(FileInfo fileInfo, FileAccess access)
2>       at Microsoft.Data.Tools.Schema.Sql.Build.SqlPackage.Open(FileInfo fileInfo, FileAccess access)
2>       at Microsoft.Data.Tools.Schema.Sql.Build.SqlPackage.Open(String file, FileAccess access)
2>       at Microsoft.Data.Tools.Schema.SchemaModel.DataSchemaModel.AddReference(CustomSchemaData customData)
2>       --- End of inner exception stack trace ---
2>       at Microsoft.Data.Tools.Schema.SchemaModel.DataSchemaModel.ThrowReferenceLoadingException(Exception innerException, String fileName)
2>       at Microsoft.Data.Tools.Schema.SchemaModel.DataSchemaModel.AddReference(CustomSchemaData customData)
2>       at Microsoft.Data.Tools.Schema.SchemaModel.DataSchemaModel.OnCustomDataAdded(CustomSchemaData customData)
2>       at Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlSchemaModel.OnCustomDataAdded(CustomSchemaData customData)
2>       at Microsoft.Data.Tools.Schema.SchemaModel.DataSchemaModel.AddCustomData(CustomSchemaData customData, Boolean raiseEvents)
2>       at Microsoft.Data.Tools.Schema.SchemaModel.DataSchemaModel.AddCustomData(CustomSchemaData customData)
2>       --- End of inner exception stack trace ---
2>       at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
2>       at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
2>       at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
2>       at MSBuild.Sdk.SqlProj.DacpacTool.Extensions.AddCustomData(Object dataSchemaModel, Object customData) in /home/runner/work/MSBuild.Sdk.SqlProj/MSBuild.Sdk.SqlProj/src/DacpacTool/Extensions.cs:line 189
2>       at MSBuild.Sdk.SqlProj.DacpacTool.Extensions.AddReference(TSqlModel model, String referencePath, String externalParts) in /home/runner/work/MSBuild.Sdk.SqlProj/MSBuild.Sdk.SqlProj/src/DacpacTool/Extensions.cs:line 113
2>       at MSBuild.Sdk.SqlProj.DacpacTool.PackageBuilder.AddReference(String referenceFile) in /home/runner/work/MSBuild.Sdk.SqlProj/MSBuild.Sdk.SqlProj/src/DacpacTool/PackageBuilder.cs:line 34
2>       at MSBuild.Sdk.SqlProj.DacpacTool.Program.BuildDacpac(BuildOptions options) in /home/runner/work/MSBuild.Sdk.SqlProj/MSBuild.Sdk.SqlProj/src/DacpacTool/Program.cs:line 99
2>       --- End of inner exception stack trace ---
2>       at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
2>       at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
2>       at System.Delegate.DynamicInvokeImpl(Object[] args)
2>       at System.Delegate.DynamicInvoke(Object[] args)
2>       at System.CommandLine.Invocation.ModelBindingCommandHandler.InvokeAsync(InvocationContext context)
2>       at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext()
2>    --- End of stack trace from previous location ---
2>       at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseParseErrorReporting>b__21_0>d.MoveNext()
2>    --- End of stack trace from previous location ---
2>       at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<UseHelp>b__0>d.MoveNext()
2>    --- End of stack trace from previous location ---
2>       at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass25_0.<<UseVersionOption>b__0>d.MoveNext()
2>    --- End of stack trace from previous location ---
2>       at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass23_0.<<UseTypoCorrections>b__0>d.MoveNext()
2>    --- End of stack trace from previous location ---
2>       at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseSuggestDirective>b__22_0>d.MoveNext()
2>    --- End of stack trace from previous location ---
2>       at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseParseDirective>b__20_0>d.MoveNext()
2>    --- End of stack trace from previous location ---
2>       at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseDebugDirective>b__11_0>d.MoveNext()
2>    --- End of stack trace from previous location ---
2>       at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<RegisterWithDotnetSuggest>b__10_0>d.MoveNext()
2>    --- End of stack trace from previous location ---
2>       at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass14_0.<<UseExceptionHandler>b__0>d.MoveNext()
2>    C:\Users\User\.nuget\packages\msbuild.sdk.sqlproj\1.11.1\Sdk\Sdk.targets(196,5): error MSB3073: The command "dotnet "C:\Users\User\.nuget\packages\msbuild.sdk.sqlproj\1.11.1\Sdk\../tools/netcoreapp5.0/DacpacTool.dll" build -o "obj\Debug\netstandard2.0\Scripts.Sample.Build.dacpac" -n "Scripts.Sample.Build" -v "1.0.0" -sv Sql130 -i "obj\Debug\netstandard2.0\Scripts.Sample.Build.InputFiles.txt" -r "C:\Repos\Scripts\bin\Debug\netstandard2.0\Scripts.dll;"   --predeploy Scripts\Script.PreDeployment.sql --postdeploy Scripts\Script.PostDeployment.sql --refactorlog ..\Scripts.Sample\Scripts.Sample.refactorlog " exited with code 1.
2>  Done executing task "Exec" -- FAILED.
2>Done building target "CoreCompile" in project "Scripts.Sample.Build.csproj" -- FAILED.
jeffrosenberg commented 3 years ago

@knoxi can you please share your .csproj file with us? From the outputs and the exception you received, it looks to me like you have a ProjectReference to a project whose artifact is a .dll file as opposed to a .dacpac file, which won't work.

@jmezach looking at the code, I don't think we're being defensive in validating that references are dacpacs, maybe we should use this issue as an opportunity to add that check?

jmezach commented 3 years ago

@jeffrosenberg Yeah, that makes sense. I'll rename this issue to reflect that.

jeffrosenberg commented 3 years ago

@jmezach just let me know if you'd like to take this or if you'd like me to, this shouldn't be much work

jmezach commented 3 years ago

To be honest I'm a little bit burned out at the moment due to personal reasons so if you'd like to take this that would be much appreciated!

jeffrosenberg commented 3 years ago

No problem, I'll take care of this tonight or tomorrow :-)

knoxi commented 3 years ago

We have created a custom SSDT extension for advanced database scheme migrations. You can find it here: SSDT Data Migration

I used this code base to reproduce the error above, I have only modified the TestProject files referencing the SSDT extension project directly instead using the official package we published. Then I finally can see an error, otherwise I wasn't able to see something going wrong but the dacpac always had empty scripts instead merged content.

I have attached the changed project files. I also had to increase the output verbosity to see the detailed error.

CustomSSDTMigrationScripts.changed.csproj.zip

knoxi commented 3 years ago

Thanks for the updated release. I was able to fix my issue since I noticed that referenced project wouldn't work, I just added them for debugging purposes.