Skip to content

PublishContainer + GeneratePackageOnBuild results in race #47429

@MattKotsenas

Description

@MattKotsenas

Describe the bug

It appears that using container publish in conjunction with a project that sets <GeneratePackageOnBuild>true</GeneratePackageOnBuild> results in pack happening multiple times, which can lead to build failures if two packs collide.

I believe that the fix would need to be here in NuGet.Build.Tasks.Pack.targets

<Target Name="_PackAsBuildAfterTarget"
        AfterTargets="Build"
        Condition="'$(GeneratePackageOnBuild)' == 'true' AND '$(IsInnerBuild)' != 'true'"
        DependsOnTargets="Pack">
</Target>

To Reproduce

Create two projects that look like this:

console.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <EnableSdkContainerSupport>true</EnableSdkContainerSupport>
    <RuntimeIdentifiers>linux-x64;linux-arm64</RuntimeIdentifiers>
  </PropertyGroup>

  <ItemGroup>
    <ProjectReference Include="..\lib\lib.csproj" />
  </ItemGroup>

</Project>

lib.csproj

I've written a small code task to make it very likely that you'll hit the race.

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
  </PropertyGroup>

  <UsingTask TaskName="LockNupkgTask" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
    <ParameterGroup>
      <NupkgFile ParameterType="System.String" Required="true" />
    </ParameterGroup>
    <Task>
      <Using Namespace="System" />
      <Using Namespace="System.IO" />
      <Using Namespace="System.Threading" />
      <Code Type="Fragment" Language="cs">
        <![CDATA[
        if (!File.Exists(NupkgFile))
        {
            Log.LogError($"The package file '{NupkgFile}' does not exist.");
            return false;
        }
        
        try
        {
            using (var stream = new FileStream(NupkgFile, FileMode.Open, FileAccess.Read, FileShare.None))
            {
                Log.LogMessage($"Locked {NupkgFile} for 5 seconds...");
                Thread.Sleep(5000);
                Log.LogMessage("Releasing lock...");
            }
        }
        catch (Exception ex)
        {
            Log.LogError($"Failed to lock '{NupkgFile}': {ex.Message}");
        }
        ]]>
      </Code>
    </Task>
  </UsingTask>

  <Target Name="LockNupkg" AfterTargets="Pack">
    <LockNupkgTask NupkgFile="bin/Release/lib.1.0.0.nupkg" />
  </Target>

</Project>

Exceptions (if any)

C:\Program Files\dotnet\sdk\9.0.200\Sdks\NuGet.Build.Tasks.Pack\build\NuGet.Build.Tasks.Pack.targets(221,5): error : The process cannot access t
he file 'lib\bin\lib.1.0.0.nupkg' because it is being
used by another process.

and run like this:

dotnet publish -t:PublishContainer .\console -bl

Further technical details

.NET SDK:
Version: 9.0.200
Commit: 90e8b20
Workload version: 9.0.200-manifests.c4f6226a
MSBuild version: 17.13.8+cbc39bea8

Runtime Environment:
OS Name: Windows
OS Version: 10.0.26100
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\9.0.200\

.NET workloads installed:
[wasm-tools]
Installation Source: VS 17.12.35728.132
Manifest Version: 9.0.2/9.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\9.0.100\microsoft.net.workload.mono.toolchain.current\9.0.2\WorkloadManifest.json
Install Type: Msi

[aspire]
Installation Source: VS 17.12.35728.132, VS 17.14.35821.62
Manifest Version: 8.2.2/8.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.aspire\8.2.2\WorkloadManifest.json
Install Type: Msi

Configured to use loose manifests when installing new manifests.

Host:
Version: 9.0.2
Architecture: x64
Commit: 80aa709f5d

.NET SDKs installed:
3.1.426 [C:\Program Files\dotnet\sdk]
5.0.408 [C:\Program Files\dotnet\sdk]
6.0.136 [C:\Program Files\dotnet\sdk]
6.0.321 [C:\Program Files\dotnet\sdk]
6.0.428 [C:\Program Files\dotnet\sdk]
7.0.317 [C:\Program Files\dotnet\sdk]
8.0.113 [C:\Program Files\dotnet\sdk]
8.0.206 [C:\Program Files\dotnet\sdk]
8.0.309 [C:\Program Files\dotnet\sdk]
8.0.406 [C:\Program Files\dotnet\sdk]
9.0.103 [C:\Program Files\dotnet\sdk]
9.0.200 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
Microsoft.AspNetCore.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 9.0.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 9.0.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.13 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 9.0.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found:
x86 [C:\Program Files (x86)\dotnet]
registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables:
Not set

global.json file:
Not found

Learn more:
https://aka.ms/dotnet/info

Download .NET:
https://aka.ms/dotnet/download

Metadata

Metadata

Assignees

Labels

untriagedRequest triage from a team member

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions