nuke
nuke copied to clipboard
Migrate away from `BinaryFormatter`?
Usage Information
6.0.0-beta0001
Relevant Code / Invocations
Nuke.Common.Tooling.SettingsEntityExtensions.NewInstance
Expected Behavior
No exception
What actually happened?
Exception while using Docker Nuke wrapper
Stacktrace / Log
System.NotSupportedException: BinaryFormatter serialization and deserialization are disabled within this application. See https://aka.ms/binaryformatter for more information.
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream , Object )
at Nuke.Common.Tooling.SettingsEntityExtensions.NewInstance[T](T settingsEntity)
at Nuke.Common.Tools.Docker.DockerLoginSettingsExtensions.SetUsername[T](T toolSettings, String username)
at Build.<get_Login>b__11_5(DockerLoginSettings s) in /src/Apps/DebianPipeline/Build.cs:line 56
at Nuke.Common.Tools.Docker.DockerTasks.DockerLogin(Configure`1 configurator)
at Build.<get_Login>b__11_4() in /src/Apps/DebianPipeline/Build.cs:line 56
at Nuke.Common.Execution.BuildExecutor.<>c.<Execute>b__4_2(Action x)
at Nuke.Common.Utilities.Collections.EnumerableExtensions.ForEach[T](IEnumerable`1 enumerable, Action`1 action)
at Nuke.Common.Execution.BuildExecutor.Execute(NukeBuild build, ExecutableTarget target, IReadOnlyCollection`1 previouslyExecutedTargets, Boolean failureMode)
Anything else we should know?
BinaryFormatter
s are prohibited under certain circumstances. Although this usage within SettingsEntityExtensions
arguably has no security implications, the BinaryFormatter
might not be available generally for the entire app, which restricts usage of Nuke.
https://docs.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/5.0/binaryformatter-serialization-obsolete
It's more a limitation than a bug, but it's not exactly a new feature either, which is why I created a bug.
I used .NET 6.0 and I have the following properties in my csproj, which might influence the situation.
<PublishSingleFile>true</PublishSingleFile>
<SelfContained>true</SelfContained>
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
<PublishReadyToRun>true</PublishReadyToRun>
<PublishTrimmed>true</PublishTrimmed>
Just a heads-up: I crossed this before too and plan to replace with JSON serialization.
var newInstance = JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(settingsEntity));
[JsonObjectAttribute(MemberSerialization.Fields)]
class Settings {}
It's more a limitation than a bug, but it's not exactly a new feature either, which is why I created a bug.
@tyb-dev have you found a workaround ? I have the same problem with a selfcontained I tried <EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization> and noWarn but still does not work for me
It's more a limitation than a bug, but it's not exactly a new feature either, which is why I created a bug.
@tyb-dev have you found a workaround ? I have the same problem with a selfcontained I tried true and noWarn but still does not work for me
Not without changing Nuke itself.
It's more a limitation than a bug, but it's not exactly a new feature either, which is why I created a bug.
@tyb-dev have you found a workaround ? I have the same problem with a selfcontained I tried true and noWarn but still does not work for me
Not without changing Nuke itself.
I managed to workaround it by disabling "PublishTrimmed". It's twice as big as my ordinary binary but that should do it for now until the change is made. Thanks !!
In .NET 8 preview docker Restore step throws.
https://learn.microsoft.com/en-us/dotnet/core/compatibility/serialization/8.0/binaryformatter-disabled
Starting in .NET 8, the affected methods throw a NotSupportedException at run time across all project types except Windows Forms and WPF. The APIs continue to remain obsolete (as error) across all project types, including Windows Forms and WPF.
[ERR] Target Restore has thrown an exception
System.NotSupportedException: BinaryFormatter serialization and deserialization are disabled within this application. See https://aka.ms/binaryformatter for more information.
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph)
at Nuke.Common.Tooling.SettingsEntityExtensions.NewInstance[T](T settingsEntity) in /_/source/Nuke.Common/Tooling/SettingsEntity.NewInstance.cs:line 22
at Nuke.Common.Tools.DotNet.DotNetRestoreSettingsExtensions.SetProjectFile[T](T toolSettings, String projectFile) in /_/source/Nuke.Common/Tools/DotNet/DotNet.Generated.cs:line 6526
at Build.<get_Restore>b__7_2(DotNetRestoreSettings _) in /build/build/Build.cs:line 45
at Nuke.Common.Tools.DotNet.DotNetTasks.DotNetRestore(Configure`1 configurator) in /_/source/Nuke.Common/Tools/DotNet/DotNet.Generated.cs:line 361
at Build.<get_Restore>b__7_1() in /build/build/Build.cs:line 45
at Nuke.Common.Execution.BuildExecutor.<>c.<Execute>b__4_2(Action x) in /_/source/Nuke.Common/Execution/BuildExecutor.cs:line 112
at Nuke.Common.Utilities.Collections.EnumerableExtensions.ForEach[T](IEnumerable`1 enumerable, Action`1 action) in /_/source/Nuke.Common/Utilities/Collections/Enumerable.ForEach.cs:line 17
at Nuke.Common.Execution.BuildExecutor.Execute(NukeBuild build, ExecutableTarget target, IReadOnlyCollection`1 previouslyExecutedTargets, Boolean failureMode) in /_/source/Nuke.Common/Execution/BuildExecutor.cs:line 112
@voroninp you can use <EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
for the build project.
@matkoch just a head's up: starting with .NET 9, binary serialization will be removed (according to the current roadmap). Is this something where a contribution would help / be feasiable?
Please take a look: https://github.com/nuke-build/nuke/pull/1247
Workaround taken from https://github.com/nuke-build/nuke/issues/1282 which has been closed as a duplicate of this bug:
Add this to your Nuke project's csproj
file:
<PropertyGroup>
.. other existing properties ...
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
</PropertyGroup>
Would something like this solve it?
[PublicAPI]
public static partial class SettingsEntityExtensions
{
public static T NewInstance<T>(this T settingsEntity)
where T : ISettingsEntity
{
T newInstance = DeepCopyWithJson(settingsEntity);
if (newInstance is ToolSettings toolSettings)
{
toolSettings.ProcessArgumentConfigurator = ((ToolSettings) (object) settingsEntity).ProcessArgumentConfigurator;
toolSettings.ProcessLogger = ((ToolSettings) (object) settingsEntity).ProcessLogger;
toolSettings.ProcessExitHandler = ((ToolSettings) (object) settingsEntity).ProcessExitHandler;
}
return newInstance;
}
public static T DeepCopyWithJson<T>(T obj) where T: ISettingsEntity
{
string json = JsonSerializer.Serialize(obj);
return JsonSerializer.Deserialize<T>(json);
}
}
When will this be fixed?
The EnableUnsafeBinaryFormatterSerialization workaround is not working on at least the latest .NET 8 SDK, so a fix would be really appreciated.