-
Notifications
You must be signed in to change notification settings - Fork 256
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
Forced locked mode doesn't work cross platform #9195
Comments
Hi! Is there any chance of this getting prioritized? Just trying to plan. |
is this ever going to happen? |
I've given up. |
I can reproduce this issue on @nkolev92 helped me to find that
Transferring to |
This issue is plaguing us also. |
Hey all, The root problem here is that the SDK projects have different defaults depending on the environment they are being built in. Given that you are trying to build on linux, I think you need to explicitly reference the targeting pack to unblock yourself. |
@nkolev92 I don't understand what you mean. I am explicitly referencing the targeting pack: https://github.com/jabbera/nuget-locked-mode-bug/blob/e9977b0f1438fed2377afb4554abae13f899988f/bugdemo.csproj#L10 I also don't think anything that was mentioned would actually help my scenario. I am building on Linux but then running all of my tests on multiple platforms. As part of that step I am running a dotnet restore on windows where the lock file was generated on linux. I don't see how any of these suggestions will help me. |
Did you notice @kartheekp-ms's comment about the RIDS? And in my comment above I mention: #9195 (comment)
If you are going to build on different OSs, consider including the RuntimeIdentifier in your project explicitly instead of relying on environment defaults that the SDK sets. Hopefully that should make the |
using |
While not a solution, I'm now using the workaround below. It disables lock files on all platforms except Windows (the primary development + deployment target). This doesn't block me from using other OS's, littering my workspace with changes to <!-- Enable nuget lock files. -->
<RestorePackagesWithLockFile Condition="'$(OS)' == 'Windows_NT'">true</RestorePackagesWithLockFile>
<!-- On CI builds restore the exact versions as locked. -->
<RestoreLockedMode Condition="'$(OS)' == 'Windows_NT' And '$(ContinuousIntegrationBuild)' == 'true'">true</RestoreLockedMode>
<!-- Force nuget to ignore existing lock files. -->
<NuGetLockFilePath Condition="'$(OS)' != 'Windows_NT'">no.lock.file</NuGetLockFilePath> If you want, you could also have a lock file per OS. This prevents the lock files from being changed all the time between OS's, but also that when updating your dependencies it involves updating the lock files from multiple OS's: <!-- Enable nuget lock files. -->
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<!-- On CI builds restore the exact versions as locked. -->
<RestoreLockedMode Condition="'$(ContinuousIntegrationBuild)' == 'true'">true</RestoreLockedMode>
<!-- Lock file per OS. -->
<NuGetLockFilePath>packages.$(OS).lock.json</NuGetLockFilePath> |
Is there any update on this or perhaps an "official" workaround? Our primary development enviroment is windows (one dev is on macos), but we do all CI and deployments on Linux, with our primary distributable a Linux docker image. Despite the docker build/artifact we do primary development outside of docker, direct in vs/vscode. Ideally the lock file would be generated/updated there and then copied into our docker builds. I've added Prior to this, I had no rids specified in the project file, but my docker builds do a restore with I'd like to avoid having one lock file per OS. And I'd like to do the generation/updates of the locks on developer machines (of any flavor) via dotnet/msbuild as if docker wasn't in the picture. The work arounds by @Bouke don't really satisfy either case. If developers only used windows then perhaps his first suggestion could work. Is there any guidance for this scenario? |
I created an issue in dotnet/sdk to see if they're willing to remove the RID that's added when restoring/building on Windows, or alternatively help us understand if manually specifying the RID in the project file is unlikely to cause other issues, or any other recommendations they have. I don't see it mentioned elsewhere, so specifying the RID in the project file seems to "work for me", but MSBuild being what it is, I can't promise there isn't some edge case or scenario where it doesn't work: <PropertyGroup>
<RuntimeIdentifiers>win7-x86</RuntimeIdentifiers>
</PropertyGroup> It doesn't matter if you're building on Linux, specifying this in your project makes the RIDs consistent regardless of what platform you're restoring on, so locked mode should work. Once I get feedback from the SDK team, I'll see about updating docs. For this reason, I'm going to mark this as blocked on external. I don't see what else NuGet can do. I even spent a little time trying to re-imagine lock files implemented in a different way, but I think that NuGet needs the SDK to provide us with consistent inputs. Even if we changed the lock file format, we can't solve this problem for all scenarios, only this "easy" one where there are no RID-specific packages. |
@zivkan Is that assuming you'd always do a eg. It wouldn't work if you were trying to build on a Linux box and leveraging something like the Cache task's |
I don't have experience with the Cache task. Are you saying that it caches failures, and therefore will fail the build without running restore? If so, yes that's right. However, if it does not cache failures, and keeps re-running restore until the first successful restore, then there should not be any problem. If it caches failures, the only workaround I can think of is to either change the rid (use |
Actually, having tried that code sample on the linked page I am suspicious that it might be incorrect. Not running |
I think it is unclear what exactly do if one has Is a workaround needed? If yes, what should it be? For instance, would <PropertyGroup Condition="$(TargetFramework.Contains('-windows')) and $(PlatformTarget) == 'x64'">
<Platforms>x64</Platforms>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.Contains('-windows')) and $(PlatformTarget) == 'x86'">
<Platforms>x86</Platforms>
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
</PropertyGroup> work for libraries that restore dependencies based on developers updating lock files on any OS , are built on CI as in this thread and then distributed through Nuget (and also on WASM)? This probably starts to be a bit of an issue for libraries that would need to be mindful on package supply-chains (e.g. https://github.com/lumoin/Verifiable) and that would need to consider package locking, Nuget package sources and like that (also it would improve performance). I'll link dotnet/sdk#1906 and dotnet/sdk#9518 and their linked issues as they give further context on the issue at large in build system. And why it's a bit tough to figure out what works or not. |
In addition to the problem described above we depend on an ~700MB OS specific 3rd party vendor NuGet and want to avoid the cost for restoring the Windows NuGet when targeting Linux (on CI). As a workaround we use a lock file per RID and <PropertyGroup>
<MyRuntimeIdentifier Condition="$([MSBuild]::IsOSPlatform('Windows'))">win-x64</MyRuntimeIdentifier>
<MyRuntimeIdentifier Condition="$([MSBuild]::IsOSPlatform('Linux'))">linux-x64</MyRuntimeIdentifier>
<RuntimeIdentifier>$(MyRuntimeIdentifier)</RuntimeIdentifier>
<NuGetLockFilePath>packages.lock.$(RuntimeIdentifier).json</NuGetLockFilePath>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<RestoreLockedMode>true</RestoreLockedMode>
<DisableImplicitNuGetFallbackFolder>true</DisableImplicitNuGetFallbackFolder>
</PropertyGroup>
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'win-x64'">
<PackageReference Include="Some.Windows.Nuget" Version="..." />
</ItemGroup>
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'linux-x64'" >
<PackageReference Include="Some.Linux.Nuget" Version="..." />
</ItemGroup> Create lock files: dotnet restore -p:MyRuntimeIdentifier=linux-x64 --force-evaluate
dotnet restore -p:MyRuntimeIdentifier=win-x64 --force-evaluate and commit Then dotnet restore -p:MyRuntimeIdentifier=linux-x64
dotnet build --no-restore -p:MyRuntimeIdentifier=linux-x64
dotnet publish ./web/web.csproj --no-build --runtime linux-x64 |
Details about Problem
When running a dotnet restore --locked-mode from a linux environment where dotnet restore --force-evaluate was run on windows it fails. This makes things very difficult to test cross platform. (Build on a linux agent then run tests on windows). Note: it happens either way (lockfile generate on linux causes windows to fail)
NuGet product used: dotnet.exe
NuGet version (x.x.x.xxx):
dotnet.exe --version (if appropriate):
OS version (i.e. win10 v1607 (14393.321)): Windows 10 Enterprise: 10.0.18363 and Ubuntu 18..04 (WSL in my case, but repro's on build agents as well)
Worked before? If so, with which NuGet version: Unknown
Detailed repro steps so we can see the same problem
Other suggested things
Output of the diff:
The text was updated successfully, but these errors were encountered: