Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,23 @@ This option is useful in combination with `BuildProjectReferences=false` when
packing on CI, since at that point all that's run are the P2P protocol involving
`GetPackageContents`.

### Package Validation

[Package validation](https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/overview)
is a new feature in .NET 6 that allows you to validate that your multi-targeting
library packages offer consistent APIs across all targets. Since it's quite
important to validate that your packages are consistent across all targets,
NuGetizer turns this feature on by default for `Release` builds in multi-targeting
projects (unlike the default which is strictly opt-in).

You can turn this off by setting the following property at the project level:

```xml
<PropertyGroup>
<EnablePackageValidation>false</EnablePackageValidation>
</PropertyGroup>
```

<!-- include https://github.com/devlooped/sponsors/raw/main/footer.md -->
# Sponsors

Expand Down
60 changes: 60 additions & 0 deletions src/NuGetizer.Tasks/NuGetizer.PackageValidation.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<!--
***********************************************************************************************
NuGetizer.PackageValidation.targets

WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
created a backup copy. Incorrect changes to this file will make it
impossible to load or build your projects from the command-line or the IDE.

This targets file adds compatibility with the .NET SDK package validation feature
(see https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/overview).
***********************************************************************************************
-->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<PropertyGroup Condition="$(NuGetPackTaskAssemblyFile) == ''">
<NuGetPackTaskAssemblyFile Condition="'$(MSBuildRuntimeType)' == 'Core'">$(MSBuildSDKsPath)\NuGet.Build.Tasks.Pack\CoreCLR\NuGet.Build.Tasks.Pack.dll</NuGetPackTaskAssemblyFile>
<NuGetPackTaskAssemblyFile Condition="'$(MSBuildRuntimeType)' != 'Core'">$(MSBuildSDKsPath)\NuGet.Build.Tasks.Pack\Desktop\NuGet.Build.Tasks.Pack.dll</NuGetPackTaskAssemblyFile>
</PropertyGroup>

<UsingTask Condition="$(UsingMicrosoftNETSdk) == 'true' and Exists($(NuGetPackTaskAssemblyFile))"
TaskName="NuGet.Build.Tasks.GetProjectTargetFrameworksTask" AssemblyFile="$(NuGetPackTaskAssemblyFile)" />

<Target Name="AfterGetPackageContents" BeforeTargets="Pack" DependsOnTargets="GetPackageContents;GetPackageTargetPath">
<ItemGroup>
<_NuGetPackInput Include="@(_PackageContent -> WithMetadataValue('PackFolder', 'lib'));
@(_PackageContent -> WithMetadataValue('PackageFolder', 'lib'))" />
<NuGetPackInput Include="@(_PackageContent -> Distinct())" />
</ItemGroup>
</Target>

<!--
============================================================
_GetTargetFrameworksOutput
Read target frameworks from the project.
Cloned for compatibility from NuGet.Build.Tasks.Pack SDK.
============================================================
-->
<Target Name="_GetTargetFrameworksOutput" Returns="@(_TargetFrameworks)">

<PropertyGroup>
<_ProjectFrameworks/>
</PropertyGroup>

<GetProjectTargetFrameworksTask ProjectPath="$(MSBuildProjectFullPath)"
TargetFrameworks="$(TargetFrameworks)"
TargetFramework="$(TargetFramework)"
TargetFrameworkMoniker="$(TargetFrameworkMoniker)"
TargetPlatformIdentifier="$(TargetPlatformIdentifier)"
TargetPlatformVersion="$(TargetPlatformVersion)"
TargetPlatformMinVersion="$(TargetPlatformMinVersion)">
<Output TaskParameter="ProjectTargetFrameworks"
PropertyName="_ProjectFrameworks" />
</GetProjectTargetFrameworksTask>

<ItemGroup Condition=" '$(_ProjectFrameworks)' != '' ">
<_TargetFrameworks Include="$(_ProjectFrameworks.Split(';'))" />
</ItemGroup>
</Target>

</Project>
8 changes: 8 additions & 0 deletions src/NuGetizer.Tasks/NuGetizer.Shared.targets
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ Copyright (c) .NET Foundation. All rights reserved.
<EmitNuspec Condition="'$(EmitNuspec)' == ''">false</EmitNuspec>
<NuspecFile Condition="'$(NuspecFile)' == '' and '$(PackageId)' != ''">$(BaseOutputPath.TrimEnd('\'))\$(PackageId).nuspec</NuspecFile>
<NuspecFile Condition="'$(NuspecFile)' == '' and '$(PackageId)' == ''">$(BaseOutputPath.TrimEnd('\'))\$(AssemblyName).nuspec</NuspecFile>

<!-- We default package validation to true for Release multi-targeting projects, ensuring best-practices. It's opt-in in .NET6+ otherwise. -->
<EnablePackageValidation Condition="$(EnablePackageValidation) == '' and $(Configuration) == 'Release' and '$(TargetFrameworks)' != ''">true</EnablePackageValidation>
</PropertyGroup>

<PropertyGroup Label="Hidden">
Expand Down Expand Up @@ -291,5 +294,10 @@ Copyright (c) .NET Foundation. All rights reserved.

<!-- Cleanups improve the local development loop, by always ensure the fresly built packages can be restored from output -->
<Import Project="NuGetizer.Cleanup.targets" Condition="'$(CI)' != 'true' and '$(EnablePackCleanup)' != 'false' and '$(IsPackable)' == 'true' and '$(PackageId)' != ''" />

<!-- In NuGetizer.props, we point the pack targets to our metadata one, so it's imported last automatically, from the Sdk.targets.
So we only need to import again here if *not* using the UsingMicrosoftNETSdk -->
<Import Project="NuGetizer.PackageMetadata.targets" Condition="'$(NuGetizerPackageMetadataImported)' != 'true' and '$(UsingMicrosoftNETSdk)' != 'true'" />

<Import Project="NuGetizer.PackageValidation.targets" Condition="$(EnablePackageValidation) == 'true'" />
</Project>
2 changes: 1 addition & 1 deletion src/NuGetizer.Tasks/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Comprehensive and intuitive heuristics built from experience building nuget pack
* SourceLink support to populate [repository information in the package](https://devblogs.microsoft.com/nuget/introducing-source-code-link-for-nuget-packages/)
* Automatic `readme.md` inclusion in the package
* Support for [content includes in readme](https://www.cazzulino.com/pack-readme-includes.html)

* [Package validation](https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/overview) enabled by default for release multi-targeting packages.

It's strongly recommended that you install the [dotnet-nugetize](https://nuget.org/packages/dotnet-nugetize) tool to get the best experience with NuGetizer:

Expand Down
17 changes: 17 additions & 0 deletions src/NuGetizer.Tests/InlineProjectTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -800,5 +800,22 @@ public void when_private_assets_then_packs_transitively()
PackFolder = "Lib",
}));
}

[Fact]
public void when_validating_package_then_succeeds()
{
var result = Builder.BuildProject(
"""
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
<IsPackable>true</IsPackable>
<EnablePackageValidation>true</EnablePackageValidation>
</PropertyGroup>
</Project>
""", target: "Pack", output: output);

result.AssertSuccess(output);
}
}
}