Skip to content

[release/9.0] Revert change to follow symlinks of dotnet host #116242

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

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
f80f87e
Merge commit '5da49f4e834fd5ecc3bd3fac5af227a2578ee664'
Apr 2, 2025
6cb529b
Merge commit '61286199e9baf51ff405be507f30503e55d0b626'
Apr 3, 2025
5bd5e7c
Merge commit '3fa4ed5c06384da6baba5615e50c4ce29b63356b'
Apr 8, 2025
6634b48
Merge commit '207cda3445ce8ac74ae548cd27ed482f36f6fb04'
Apr 11, 2025
ea67322
Merge commit '38d99eb2f25d814e7344b5c400a350553b2aee21'
Apr 14, 2025
e36e4d1
Merge commit '34e64ad57037093849bbb60a79666b2a3f3746c2'
Apr 15, 2025
aa6edbd
Update branding to 9.0.6 (#115385)
vseanreesermsft May 8, 2025
7e47914
[release/9.0] Update dependencies from dotnet/emsdk (#114702)
dotnet-maestro[bot] May 12, 2025
c57a3cc
Merge commit 'e36e4d1a8f8dfb08d7e3a6041459c9791d732c01' into internal…
vseanreesermsft May 13, 2025
b5288ce
Merge pull request #115535 from vseanreesermsft/internal-merge-9.0-20…
jozkee May 14, 2025
71b9dc5
Merge pull request #115497 from jozkee/release/9.0-staging
jozkee May 15, 2025
dda82ff
update macos signing to use pme (#115634)
github-actions[bot] May 16, 2025
df01702
[release/9.0] [Mono] Fix c11 ARM64 atomics to issue full memory barri…
github-actions[bot] May 16, 2025
40579d1
Revert change to follow symlinks of dotnet host
agocke May 2, 2025
9763cdd
Adapt symbolic link tests
agocke May 5, 2025
586355f
Conditional behavior based on OS
agocke May 6, 2025
a30fb37
Add unit test for success with symlinks
agocke May 13, 2025
ea6384a
Add self-contained test as well
agocke May 13, 2025
9ccf540
Add test with split files
agocke May 28, 2025
dad7916
Simplify dir handling
agocke May 28, 2025
bcf5e93
Simplify test code
agocke Jun 3, 2025
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
2 changes: 1 addition & 1 deletion NuGet.config
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<clear />
<!--Begin: Package sources managed by Dependency Flow automation. Do not edit the sources below.-->
<!-- Begin: Package sources from dotnet-emsdk -->
<add key="darc-pub-dotnet-emsdk-78f6f07" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-emsdk-78f6f07d/nuget/v3/index.json" />
<add key="darc-pub-dotnet-emsdk-e3d8e8e" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-emsdk-e3d8e8ea/nuget/v3/index.json" />
<!-- End: Package sources from dotnet-emsdk -->
<!-- Begin: Package sources from dotnet-sdk -->
<add key="darc-pub-dotnet-sdk-b562a30" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-sdk-b562a300/nuget/v3/index.json" />
Expand Down
12 changes: 6 additions & 6 deletions eng/Version.Details.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,18 @@
<Sha>6aaf3af113593a4c993854bff4141bbc73061ea5</Sha>
<SourceBuild RepoName="cecil" ManagedOnly="true" />
</Dependency>
<Dependency Name="Microsoft.NET.Workload.Emscripten.Current.Manifest-9.0.100.Transport" Version="9.0.5-servicing.25212.1">
<Dependency Name="Microsoft.NET.Workload.Emscripten.Current.Manifest-9.0.100.Transport" Version="9.0.6-servicing.25258.2">
<Uri>https://github.com/dotnet/emsdk</Uri>
<Sha>78f6f07d38e8755e573039a8aa04e131d3e59b76</Sha>
<Sha>e3d8e8ea6df192d864698cdd76984d74135d0d13</Sha>
</Dependency>
<Dependency Name="Microsoft.NET.Workload.Emscripten.Current.Manifest-9.0.100" Version="9.0.5">
<Dependency Name="Microsoft.NET.Workload.Emscripten.Current.Manifest-9.0.100" Version="9.0.6">
<Uri>https://github.com/dotnet/emsdk</Uri>
<Sha>78f6f07d38e8755e573039a8aa04e131d3e59b76</Sha>
<Sha>e3d8e8ea6df192d864698cdd76984d74135d0d13</Sha>
</Dependency>
<!-- Intermediate is necessary for source build. -->
<Dependency Name="Microsoft.SourceBuild.Intermediate.emsdk" Version="9.0.5-servicing.25212.1">
<Dependency Name="Microsoft.SourceBuild.Intermediate.emsdk" Version="9.0.6-servicing.25258.2">
<Uri>https://github.com/dotnet/emsdk</Uri>
<Sha>78f6f07d38e8755e573039a8aa04e131d3e59b76</Sha>
<Sha>e3d8e8ea6df192d864698cdd76984d74135d0d13</Sha>
<SourceBuild RepoName="emsdk" ManagedOnly="true" />
</Dependency>
<!-- Intermediate is necessary for source build. -->
Expand Down
8 changes: 4 additions & 4 deletions eng/Versions.props
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<Project>
<PropertyGroup>
<!-- The .NET product branding version -->
<ProductVersion>9.0.5</ProductVersion>
<ProductVersion>9.0.6</ProductVersion>
<!-- File version numbers -->
<MajorVersion>9</MajorVersion>
<MinorVersion>0</MinorVersion>
<PatchVersion>5</PatchVersion>
<PatchVersion>6</PatchVersion>
<SdkBandVersion>9.0.100</SdkBandVersion>
<PackageVersionNet8>8.0.$([MSBuild]::Add($(PatchVersion),11))</PackageVersionNet8>
<PackageVersionNet7>7.0.20</PackageVersionNet7>
Expand Down Expand Up @@ -243,8 +243,8 @@
Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml
like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-9_0_100_Transport
-->
<MicrosoftNETWorkloadEmscriptenCurrentManifest90100TransportVersion>9.0.5-servicing.25212.1</MicrosoftNETWorkloadEmscriptenCurrentManifest90100TransportVersion>
<MicrosoftNETWorkloadEmscriptenCurrentManifest90100Version>9.0.5</MicrosoftNETWorkloadEmscriptenCurrentManifest90100Version>
<MicrosoftNETWorkloadEmscriptenCurrentManifest90100TransportVersion>9.0.6-servicing.25258.2</MicrosoftNETWorkloadEmscriptenCurrentManifest90100TransportVersion>
<MicrosoftNETWorkloadEmscriptenCurrentManifest90100Version>9.0.6</MicrosoftNETWorkloadEmscriptenCurrentManifest90100Version>
<MicrosoftNETRuntimeEmscriptenVersion>$(MicrosoftNETWorkloadEmscriptenCurrentManifest90100Version)</MicrosoftNETRuntimeEmscriptenVersion>
<!-- workloads -->
<SwixPackageVersion>1.1.87-gba258badda</SwixPackageVersion>
Expand Down
13 changes: 7 additions & 6 deletions eng/pipelines/common/macos-sign-with-entitlements.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ steps:
- task: EsrpCodeSigning@5
displayName: 'ESRP CodeSigning'
inputs:
ConnectedServiceName: 'DotNet-Engineering-Services_KeyVault'
AppRegistrationClientId: '28ec6507-2167-4eaa-a294-34408cf5dd0e'
AppRegistrationTenantId: '72f988bf-86f1-41af-91ab-2d7cd011db47'
AuthAKVName: 'EngKeyVault'
AuthCertName: 'DotNetCore-ESRP-AuthCert'
AuthSignCertName: 'DotNetCore-ESRP-AuthSignCert'
ConnectedServiceName: 'DotNetBuildESRP'
UseMSIAuthentication: true
EsrpClientId: '28ec6507-2167-4eaa-a294-34408cf5dd0e'
AppRegistrationClientId: '0ecbcdb7-8451-4cbe-940a-4ed97b08b955'
AppRegistrationTenantId: '975f013f-7f24-47e8-a7d3-abc4752bf346'
AuthAKVName: 'DotNetEngKeyVault'
AuthSignCertName: 'DotNet-ESRP-AuthSignCert'
FolderPath: '$(Build.ArtifactStagingDirectory)/'
Pattern: 'mac_entitled_to_sign.zip'
UseMinimatch: true
Expand Down
238 changes: 222 additions & 16 deletions src/installer/tests/HostActivation.Tests/SymbolicLinks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;

using FluentAssertions;
using Microsoft.DotNet.Cli.Build.Framework;
Expand All @@ -21,6 +23,166 @@ public SymbolicLinks(SymbolicLinks.SharedTestState fixture)
sharedTestState = fixture;
}

[Theory]
[InlineData("a/b/SymlinkToFrameworkDependentApp")]
[InlineData("a/SymlinkToFrameworkDependentApp")]
public void Symlink_all_files_fx(string symlinkRelativePath)
{
using var testDir = TestArtifact.Create("symlink");
Directory.CreateDirectory(Path.Combine(testDir.Location, Path.GetDirectoryName(symlinkRelativePath)));

// Symlink every file in the app directory
var symlinks = new List<SymLink>();
try
{
foreach (var file in Directory.EnumerateFiles(sharedTestState.FrameworkDependentApp.Location))
{
var fileName = Path.GetFileName(file);
var symlinkPath = Path.Combine(testDir.Location, symlinkRelativePath, fileName);
Directory.CreateDirectory(Path.GetDirectoryName(symlinkPath));
symlinks.Add(new SymLink(symlinkPath, file));
}

var result = Command.Create(Path.Combine(testDir.Location, symlinkRelativePath, Path.GetFileName(sharedTestState.FrameworkDependentApp.AppExe)))
.CaptureStdErr()
.CaptureStdOut()
.DotNetRoot(TestContext.BuiltDotNet.BinPath)
.Execute();

// This should succeed on all platforms, but for different reasons:
// * Windows: The apphost will look next to the symlink for the app dll and find the symlinked dll
// * Unix: The apphost will look next to the resolved apphost for the app dll and find the real thing
result
.Should().Pass()
.And.HaveStdOutContaining("Hello World");
}
finally
{
foreach (var symlink in symlinks)
{
symlink.Dispose();
}
}
}

[Theory]
[InlineData("a/b/SymlinkToFrameworkDependentApp")]
[InlineData("a/SymlinkToFrameworkDependentApp")]
public void Symlink_split_files_fx(string symlinkRelativePath)
{
using var testDir = TestArtifact.Create("symlink");

// Split the app into two directories, one for the apphost and one for the rest of the files
var appHostDir = Path.Combine(testDir.Location, "apphost");
var appFilesDir = Path.Combine(testDir.Location, "appfiles");
Directory.CreateDirectory(appHostDir);
Directory.CreateDirectory(appFilesDir);

var appHostName = Path.GetFileName(sharedTestState.FrameworkDependentApp.AppExe);

File.Copy(
sharedTestState.FrameworkDependentApp.AppExe,
Path.Combine(appHostDir, appHostName));

foreach (var file in Directory.EnumerateFiles(sharedTestState.FrameworkDependentApp.Location))
{
var fileName = Path.GetFileName(file);
if (fileName != appHostName)
{
File.Copy(file, Path.Combine(appFilesDir, fileName));
}
}

// Symlink all of the above into a single directory
var targetPath = Path.Combine(testDir.Location, symlinkRelativePath);
Directory.CreateDirectory(targetPath);
var symlinks = new List<SymLink>();
try
{
foreach (var file in Directory.EnumerateFiles(appFilesDir))
{
var fileName = Path.GetFileName(file);
var symlinkPath = Path.Combine(targetPath, fileName);
Directory.CreateDirectory(Path.GetDirectoryName(symlinkPath));
symlinks.Add(new SymLink(symlinkPath, file));
}
symlinks.Add(new SymLink(
Path.Combine(targetPath, appHostName),
Path.Combine(appHostDir, appHostName)));

Console.ReadLine();
var result = Command.Create(Path.Combine(targetPath, appHostName))
.CaptureStdErr()
.CaptureStdOut()
.DotNetRoot(TestContext.BuiltDotNet.BinPath)
.Execute();

if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
// On Windows, the apphost will look next to the symlink for the app dll and find the symlinks
result
.Should().Pass()
.And.HaveStdOutContaining("Hello World");
}
else
{
// On Unix, the apphost will not find the app files next to the symlink
result
.Should().Fail()
.And.HaveStdErrContaining("The application to execute does not exist");
}
}
finally
{
foreach (var symlink in symlinks)
{
symlink.Dispose();
}
}
}

[Theory]
[InlineData("a/b/SymlinkToFrameworkDependentApp")]
[InlineData("a/SymlinkToFrameworkDependentApp")]
public void Symlink_all_files_self_contained(string symlinkRelativePath)
{
using var testDir = TestArtifact.Create("symlink");
Directory.CreateDirectory(Path.Combine(testDir.Location, Path.GetDirectoryName(symlinkRelativePath)));

// Symlink every file in the app directory
var symlinks = new List<SymLink>();
try
{
foreach (var file in Directory.EnumerateFiles(sharedTestState.SelfContainedApp.Location))
{
var fileName = Path.GetFileName(file);
var symlinkPath = Path.Combine(testDir.Location, symlinkRelativePath, fileName);
Directory.CreateDirectory(Path.GetDirectoryName(symlinkPath));
symlinks.Add(new SymLink(symlinkPath, file));
}

var result = Command.Create(Path.Combine(testDir.Location, symlinkRelativePath, Path.GetFileName(sharedTestState.FrameworkDependentApp.AppExe)))
.CaptureStdErr()
.CaptureStdOut()
.DotNetRoot(TestContext.BuiltDotNet.BinPath)
.Execute();

// This should succeed on all platforms, but for different reasons:
// * Windows: The apphost will look next to the symlink for the files and find the symlinks
// * Unix: The apphost will look next to the resolved apphost for the files and find the real thing
result
.Should().Pass()
.And.HaveStdOutContaining("Hello World");
}
finally
{
foreach (var symlink in symlinks)
{
symlink.Dispose();
}
}
}

[Theory]
[InlineData ("a/b/SymlinkToApphost")]
[InlineData ("a/SymlinkToApphost")]
Expand All @@ -33,12 +195,23 @@ public void Run_apphost_behind_symlink(string symlinkRelativePath)
var symlinkFullPath = Path.Combine(testDir.Location, symlinkRelativePath);

using var symlink = new SymLink(symlinkFullPath, sharedTestState.SelfContainedApp.AppExe);
Command.Create(symlinkFullPath)
var result = Command.Create(symlinkFullPath)
.CaptureStdErr()
.CaptureStdOut()
.Execute()
.Should().Pass()
.And.HaveStdOutContaining("Hello World");
.Execute();

if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
result
.Should().Fail()
.And.HaveStdErrContaining("The application to execute does not exist");
}
else
{
result
.Should().Pass()
.And.HaveStdOutContaining("Hello World");
}
}
}

Expand All @@ -63,12 +236,23 @@ public void Run_apphost_behind_transitive_symlinks(string firstSymlinkRelativePa
Directory.CreateDirectory(Path.GetDirectoryName(symlink1Path));
using var symlink1 = new SymLink(symlink1Path, symlink2Path);

Command.Create(symlink1.SrcPath)
var result = Command.Create(symlink1.SrcPath)
.CaptureStdErr()
.CaptureStdOut()
.Execute()
.Should().Pass()
.And.HaveStdOutContaining("Hello World");
.Execute();

if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
result
.Should().Fail()
.And.HaveStdErrContaining("The application to execute does not exist");
}
else
{
result
.Should().Pass()
.And.HaveStdOutContaining("Hello World");
}
}
}

Expand All @@ -86,13 +270,24 @@ public void Run_framework_dependent_app_behind_symlink(string symlinkRelativePat
Directory.CreateDirectory(Path.Combine(testDir.Location, Path.GetDirectoryName(symlinkRelativePath)));

using var symlink = new SymLink(Path.Combine(testDir.Location, symlinkRelativePath), sharedTestState.FrameworkDependentApp.AppExe);
Command.Create(symlink.SrcPath)
var result = Command.Create(symlink.SrcPath)
.CaptureStdErr()
.CaptureStdOut()
.DotNetRoot(TestContext.BuiltDotNet.BinPath)
.Execute()
.Should().Pass()
.And.HaveStdOutContaining("Hello World");
.Execute();

if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
result
.Should().Fail()
.And.HaveStdErrContaining("The application to execute does not exist");
}
else
{
result
.Should().Pass()
.And.HaveStdOutContaining("Hello World");
}
}
}

Expand Down Expand Up @@ -144,12 +339,23 @@ public void Put_dotnet_behind_symlink()
var dotnetSymlink = Path.Combine(testDir.Location, Binaries.DotNet.FileName);

using var symlink = new SymLink(dotnetSymlink, TestContext.BuiltDotNet.DotnetExecutablePath);
Command.Create(symlink.SrcPath, sharedTestState.SelfContainedApp.AppDll)
var result = Command.Create(symlink.SrcPath, sharedTestState.SelfContainedApp.AppDll)
.CaptureStdErr()
.CaptureStdOut()
.Execute()
.Should().Pass()
.And.HaveStdOutContaining("Hello World");
.Execute();

if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
result
.Should().Fail()
.And.HaveStdErrContaining($"[{Path.Combine(testDir.Location, "host", "fxr")}] does not exist");
}
else
{
result
.Should().Pass()
.And.HaveStdOutContaining("Hello World");
}
}
}

Expand Down
Loading
Loading