Skip to content

Clean up containers packaging, leaning into NuGet's expected patterns #49518

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
135 changes: 72 additions & 63 deletions src/Containers/packaging/package.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@
<RepositoryType>git</RepositoryType>
<PackageTags>containers;docker;Microsoft.NET.Build.Containers</PackageTags>
<PackageReadmeFile>README.md</PackageReadmeFile>
<TargetsForTfmSpecificContentInPackage>$(TargetsForTfmSpecificContentInPackage);PreparePackageReleaseNotesFromFile;AddItemsForPackaging;$(GenerateNuspecDependsOn);</TargetsForTfmSpecificContentInPackage>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="../Microsoft.NET.Build.Containers/Microsoft.NET.Build.Containers.csproj"
SetTargetFramework="TargetFramework=$(TargetFramework)"
SetTargetFramework="TargetFramework=$(SdkTargetFramework)"
OutputItemType="ContainerLibraryOutput"/>

<ProjectReference Include="../../Cli/Microsoft.DotNet.Cli.Utils/Microsoft.DotNet.Cli.Utils.csproj"
Expand All @@ -34,76 +35,84 @@

<ProjectReference Include="../Microsoft.NET.Build.Containers/Microsoft.NET.Build.Containers.csproj"
SetTargetFramework="TargetFramework=$(VSCompatTargetFramework)"
OutputItemType="ContainerLibraryOutputNet472" Condition="'$(DotNetBuildSourceOnly)' != 'true'" />
OutputItemType="ContainerLibraryOutputNet472"
Condition="'$(DotNetBuildSourceOnly)' != 'true'" />

<ProjectReference Include="../containerize/containerize.csproj" PrivateAssets="all" IncludeAssets="runtime" ReferenceOutputAssembly="true" Condition="'$(DotNetBuildSourceOnly)' != 'true'" />
<ProjectReference Include="../containerize/containerize.csproj"
PrivateAssets="all"
IncludeAssets="runtime"
ReferenceOutputAssembly="true"
OutputItemType="ContainerizeBinaryOutput"
Condition="'$(DotNetBuildSourceOnly)' != 'true'" />
</ItemGroup>

<Target Name="PreparePackageReleaseNotesFromFile" BeforeTargets="GenerateNuspec">
<PropertyGroup>
<PackageReleaseNotesFile>../docs/ReleaseNotes/v8.0.300.md</PackageReleaseNotesFile>
<PackageReleaseNotes>$([System.IO.File]::ReadAllText($(PackageReleaseNotesFile)))</PackageReleaseNotes>
</PropertyGroup>
</Target>

<Target Name="AddItemsForPackaging" AfterTargets="Build">
<MSBuild Projects="../Microsoft.NET.Build.Containers/Microsoft.NET.Build.Containers.csproj" Properties="TargetFramework=$(VSCompatTargetFramework)" Targets="ResolveAssemblyReferences" Condition="'$(DotNetBuildSourceOnly)' != 'true'">
<Output TaskParameter="TargetOutputs" ItemName="_AllNet472ContainerTaskDependencies" />
</MSBuild>
<ItemGroup Condition="'$(DotNetBuildSourceOnly)' != 'true'">
<NecessaryNet472ContainerTaskDependencies Include="@(_AllNet472ContainerTaskDependencies)" Condition="(
$([MSBuild]::ValueOrDefault('%(_AllNet472ContainerTaskDependencies.NuGetPackageId)', '').Contains('NuGet')) or
$([MSBuild]::ValueOrDefault('%(_AllNet472ContainerTaskDependencies.NuGetPackageId)', '').Contains('Newtonsoft')) or
$([MSBuild]::ValueOrDefault('%(_AllNet472ContainerTaskDependencies.NuGetPackageId)', '').Contains('Microsoft.Extensions'))
) and
%(_AllNet472ContainerTaskDependencies.NuGetIsFrameworkReference) != true" />

<!-- containerize folder -->
<Content Include="$(OutDir)containerize.dll" Pack="true" PackagePath="containerize/" />
<Content Include="$(OutDir)containerize.runtimeconfig.json" Pack="true" PackagePath="containerize/" />
<Content Include="$(OutDir)Newtonsoft.Json.dll" Pack="true" PackagePath="containerize/" />
<Content Include="$(OutDir)NuGet.*.dll" Pack="true" PackagePath="containerize/" />
<Content Include="$(OutDir)Microsoft.DotNet.Cli.Utils.dll" Pack="true" PackagePath="containerize/" />
<Content Include="$(OutDir)System.CommandLine.dll" Pack="true" PackagePath="containerize/" />
<Content Include="$(OutDir)Valleysoft.DockerCredsProvider.dll" Pack="true" PackagePath="containerize/" />
<Content Include="$(OutDir)Microsoft.Extensions.*.dll" Pack="true" PackagePath="containerize/" />
<Content Include="@(ContainerLibraryOutput)" Pack="true" PackagePath="containerize/" />
<ItemGroup>
<!-- These things are static, just always include them-->
<Content Include="README.md" Pack="true" PackagePath="" />
<Content Include="build/**" Pack="true" PackagePath="build/" />
</ItemGroup>

<!-- net472 tasks -->
<!-- dependencies -->
<Content Include="@(NecessaryNet472ContainerTaskDependencies)" Pack="true" PackagePath="tasks/$(VSCompatTargetFramework)/" />
<!-- actual DLL -->
<Content Include="@(ContainerLibraryOutputNet472)" Pack="true" PackagePath="tasks/$(VSCompatTargetFramework)/" />
</ItemGroup>
<MSBuild Projects="../Microsoft.NET.Build.Containers/Microsoft.NET.Build.Containers.csproj" Properties="TargetFramework=$(TargetFramework)" Targets="ResolveAssemblyReferences">
<Output TaskParameter="TargetOutputs" ItemName="_AllNetContainerTaskDependencies" />
</MSBuild>
<ItemGroup>
<NecessaryNetContainerTaskDependencies Include="@(_AllNetContainerTaskDependencies)" Condition="(
$([MSBuild]::ValueOrDefault('%(_AllNetContainerTaskDependencies.NuGetPackageId)', '').Contains('NuGet')) or
$([MSBuild]::ValueOrDefault('%(_AllNetContainerTaskDependencies.NuGetPackageId)', '').Contains('Newtonsoft')) or
$([MSBuild]::ValueOrDefault('%(_AllNetContainerTaskDependencies.NuGetPackageId)', '').Contains('Valleysoft')) or
$([MSBuild]::ValueOrDefault('%(_AllNetContainerTaskDependencies.NuGetPackageId)', '').Contains('Microsoft.Extensions'))
) and
%(_AllNetContainerTaskDependencies.NuGetIsFrameworkReference) != true" />
<Target Name="PreparePackageReleaseNotesFromFile">
<PropertyGroup>
<PackageReleaseNotesFile>../docs/ReleaseNotes/v8.0.300.md</PackageReleaseNotesFile>
<PackageReleaseNotes>$([System.IO.File]::ReadAllText($(PackageReleaseNotesFile)))</PackageReleaseNotes>
</PropertyGroup>
</Target>

<!-- root folder -->
<Content Include="README.md" Pack="true" PackagePath="" />
<!-- We need to depend on ResolveProjectReferences so that the 'OutputItemTypes' from the ProjectReferences above are populated.
`dotnet build` + GeneratePackageOnBuild does that automatically, but
`dotnet pack` + GeneratePackageOnBuild does not (because that would be an inifite loop) -->
<Target Name="AddItemsForPackaging" DependsOnTargets="ResolveProjectReferences">
<!-- build the containerize folder with the containerize binary and its dependencies -->
<MSBuild Projects="../containerize/containerize.csproj" Targets="ResolveAssemblyReferences" Condition="'$(DotNetBuildSourceOnly)' != 'true'">
<Output TaskParameter="TargetOutputs" ItemName="_AllContainerExeDependencies" />
</MSBuild>
<MSBuild Projects="../containerize/containerize.csproj" Targets="GetCopyToOutputDirectoryItems" Condition="'$(DotNetBuildSourceOnly)' != 'true'">
<Output TaskParameter="TargetOutputs" ItemName="ContainerizeBinaryOutput" />
</MSBuild>
<ItemGroup Condition="'$(DotNetBuildSourceOnly)' != 'true'">
<NecessaryContainerizeBinaryDependencies Include="@(_AllContainerExeDependencies)"
Condition="'%(_AllContainerExeDependencies.FrameworkReferenceName)' == ''" />
<_ContainerizeBinaryDependency Include="@(NecessaryContainerizeBinaryDependencies)" />
<_ContainerizeBinaryDependency Include="@(ContainerizeBinaryOutput)" />
<TfmSpecificPackageFile Include="@(_ContainerizeBinaryDependency)" PackagePath="containerize/" />
</ItemGroup>

<!-- tasks folder -->
<!-- net7.0 tasks -->
<!-- dependencies -->
<Content Include="@(NecessaryNetContainerTaskDependencies)" Pack="true" PackagePath="tasks/$(TargetFramework)/" />
<Content Include="@(DotNetCliUtilsLibraryOutput)" Pack="true" PackagePath="tasks/$(TargetFramework)/" />
<!-- build the VS Task directory from the Tasks project built for net472 -->
<MSBuild Projects="../Microsoft.NET.Build.Containers/Microsoft.NET.Build.Containers.csproj" Properties="TargetFramework=$(VSCompatTargetFramework)" Targets="ResolveAssemblyReferences" Condition="'$(DotNetBuildSourceOnly)' != 'true'">
<Output TaskParameter="TargetOutputs" ItemName="_AllNet472ContainerTaskDependencies" />
</MSBuild>
<ItemGroup Condition="'$(DotNetBuildSourceOnly)' != 'true'">
<NecessaryNet472ContainerTaskDependencies Include="@(_AllNet472ContainerTaskDependencies)" Condition="(
$([MSBuild]::ValueOrDefault('%(_AllNet472ContainerTaskDependencies.NuGetPackageId)', '').Contains('NuGet')) or
$([MSBuild]::ValueOrDefault('%(_AllNet472ContainerTaskDependencies.NuGetPackageId)', '').Contains('Newtonsoft')) or
$([MSBuild]::ValueOrDefault('%(_AllNet472ContainerTaskDependencies.NuGetPackageId)', '').Contains('Microsoft.Extensions'))
) and
%(_AllNet472ContainerTaskDependencies.NuGetIsFrameworkReference) != true" />
<_ContainerTaskFrameworkDependency Include="@(NecessaryNet472ContainerTaskDependencies)" PackagePath="tasks/$(VSCompatTargetFramework)/" />
<_ContainerTaskFrameworkDependency Include="@(ContainerLibraryOutputNet472)" PackagePath="tasks/$(VSCompatTargetFramework)/" />
<TfmSpecificPackageFile Include="@(_ContainerTaskFrameworkDependency)" PackagePath="tasks/$(VSCompatTargetFramework)/" />
</ItemGroup>

<!-- runtime deps json -->
<Content Include="$(ArtifactsDir)bin/Microsoft.NET.Build.Containers/$(Configuration)/$(TargetFramework)/Microsoft.NET.Build.Containers.deps.json" Pack="true" PackagePath="tasks/$(TargetFramework)" />
<!-- actual DLL -->
<Content Include="@(ContainerLibraryOutput)" Pack="true" PackagePath="tasks/$(TargetFramework)/" />
<!-- build the CLI Task directory from the Tasks project build for the netcore TFM -->
<MSBuild Projects="../Microsoft.NET.Build.Containers/Microsoft.NET.Build.Containers.csproj" Properties="TargetFramework=$(SdkTargetFramework)" Targets="ResolveAssemblyReferences">
<Output TaskParameter="TargetOutputs" ItemName="_AllNetContainerTaskDependencies" />
</MSBuild>
<ItemGroup>
<NecessaryNetContainerTaskDependencies Include="@(_AllNetContainerTaskDependencies)" Condition="(
$([MSBuild]::ValueOrDefault('%(_AllNetContainerTaskDependencies.NuGetPackageId)', '').Contains('NuGet')) or
$([MSBuild]::ValueOrDefault('%(_AllNetContainerTaskDependencies.NuGetPackageId)', '').Contains('Newtonsoft')) or
$([MSBuild]::ValueOrDefault('%(_AllNetContainerTaskDependencies.NuGetPackageId)', '').Contains('Valleysoft')) or
$([MSBuild]::ValueOrDefault('%(_AllNetContainerTaskDependencies.NuGetPackageId)', '').Contains('Microsoft.Extensions'))
) and
%(_AllNetContainerTaskDependencies.NuGetIsFrameworkReference) != true" />

<!-- build folder -->
<Content Include="build/**" Pack="true" PackagePath="build/" />
</ItemGroup>
<_ContainerTaskCoreDependency Include="@(NecessaryNetContainerTaskDependencies)" />
<_ContainerTaskCoreDependency Include="@(DotNetCliUtilsLibraryOutput)" />
<_ContainerTaskCoreDependency Include="$(ArtifactsDir)bin/Microsoft.NET.Build.Containers/$(Configuration)/$(SdkTargetFramework)/Microsoft.NET.Build.Containers.deps.json" />
<_ContainerTaskCoreDependency Include="@(ContainerLibraryOutput)" />
<TfmSpecificPackageFile Include="@(_ContainerTaskCoreDependency)" PackagePath="tasks/$(SdkTargetFramework)/" />
</ItemGroup>
</Target>

<!-- Hacky workaround for the fact that we don't publish the package yet. -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,13 @@ public void PackageContentTest()
{
string ignoredZipFileEntriesPrefix = "package/services/metadata";
var netTFM = ToolsetInfo.CurrentTargetFramework;
IReadOnlyList<string> packageContents = new List<string>()
var expectedPackageContents = new List<string>
{
"_rels/.rels",
"[Content_Types].xml",
"build/Microsoft.NET.Build.Containers.props",
"build/Microsoft.NET.Build.Containers.targets",
"containerize/containerize.deps.json",
"containerize/containerize.dll",
"containerize/containerize.runtimeconfig.json",
"containerize/Microsoft.DotNet.Cli.Utils.dll",
Expand Down Expand Up @@ -102,6 +103,9 @@ public void PackageContentTest()
"containerize/NuGet.Protocol.dll",
"containerize/NuGet.Versioning.dll",
"containerize/System.CommandLine.dll",
"containerize/System.IO.Hashing.dll",
"containerize/System.Security.Cryptography.Pkcs.dll",
"containerize/System.Security.Cryptography.ProtectedData.dll",
"containerize/Valleysoft.DockerCredsProvider.dll",
"Icon.png",
"Microsoft.NET.Build.Containers.nuspec",
Expand Down Expand Up @@ -129,18 +133,22 @@ public void PackageContentTest()
$"tasks/{netTFM}/NuGet.Packaging.dll",
$"tasks/{netTFM}/NuGet.Versioning.dll",
$"tasks/{netTFM}/Valleysoft.DockerCredsProvider.dll"
};
}.ToHashSet();

(string? packageFilePath, string? packageVersion) = ToolsetUtils.GetContainersPackagePath();
using ZipArchive archive = new(File.OpenRead(packageFilePath ?? string.Empty), ZipArchiveMode.Read, false);

IEnumerable<string> actualEntries = archive.Entries
var actualEntries = archive.Entries
.Select(e => e.FullName)
.Where(e => !e.StartsWith(ignoredZipFileEntriesPrefix, StringComparison.InvariantCultureIgnoreCase))
.OrderBy(e => e);
.ToHashSet();

expectedPackageContents.Except(actualEntries)
.Should()
.BeEmpty($"{Path.GetFileName(packageFilePath)} is missing expected entries. Please add the entry to the list, if the addition is expected.");

actualEntries
actualEntries.Except(expectedPackageContents)
.Should()
.BeEquivalentTo(packageContents, $"{Path.GetFileName(packageFilePath)} content differs from expected. Please add the entry to the list, if the addition is expected.");
.BeEmpty($"{Path.GetFileName(packageFilePath)} contains unexpected entries. Please remove the entry from the list, if the removal is expected.");
}
}
Loading