Skip to content

Commit c63daff

Browse files
authored
Universal Packages: Call chmod on executable when extracting from zip on Unix-based OS (#625)
1 parent caec4f5 commit c63daff

File tree

3 files changed

+53
-8
lines changed

3 files changed

+53
-8
lines changed

Directory.Build.props

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@
66
<BaseArtifactsPath>$(MSBuildThisFileDirectory)artifacts\</BaseArtifactsPath>
77
<EnableDefaultNoneItems>false</EnableDefaultNoneItems>
88
<NoWarn>$(NoWarn);NU5128;SA0001</NoWarn>
9-
<RestoreUseStaticGraphEvaluation>true</RestoreUseStaticGraphEvaluation>
9+
<!--
10+
Disabling static graph restore due to a bug related to NuGetAuditSuppress.
11+
See: https://github.com/NuGet/Home/issues/14300
12+
-->
13+
<RestoreUseStaticGraphEvaluation>false</RestoreUseStaticGraphEvaluation>
1014
<RestoreSerializeGlobalProperties>true</RestoreSerializeGlobalProperties>
1115
<UseArtifactsOutput>false</UseArtifactsOutput>
1216
<IsTestProject Condition="$(MSBuildProjectName.EndsWith('UnitTests'))">true</IsTestProject>

Directory.Solution.props

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
<Project>
22
<PropertyGroup>
3-
<RestoreUseStaticGraphEvaluation>true</RestoreUseStaticGraphEvaluation>
3+
<!--
4+
Disabling static graph restore due to a bug related to NuGetAuditSuppress.
5+
See: https://github.com/NuGet/Home/issues/14300
6+
-->
7+
<RestoreUseStaticGraphEvaluation>false</RestoreUseStaticGraphEvaluation>
48
<RestoreSerializeGlobalProperties>true</RestoreSerializeGlobalProperties>
59
</PropertyGroup>
610
</Project>

src/UniversalPackages/DownloadUniversalPackages.cs

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,12 @@ private void CreatePackageListJson(IReadOnlyCollection<UniversalPackage> package
410410
// Download only if needed
411411
if (!Directory.Exists(artifactToolPath))
412412
{
413-
bool downloadResult = DownloadAndExtractArchive("ArtifactTool", releaseInfo.Value.DownloadUri, artifactToolPath, isZip: true);
413+
bool downloadResult = DownloadAndExtractArchive(
414+
"ArtifactTool",
415+
releaseInfo.Value.DownloadUri,
416+
artifactToolPath,
417+
GetArtifactToolExeName(),
418+
isZip: true);
414419
if (!downloadResult)
415420
{
416421
return null;
@@ -421,8 +426,7 @@ private void CreatePackageListJson(IReadOnlyCollection<UniversalPackage> package
421426

422427
string? GetArtifactToolExePath(string dir)
423428
{
424-
string exeName = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "artifacttool.exe" : "artifacttool";
425-
string exePath = Path.Combine(dir, exeName);
429+
string exePath = Path.Combine(dir, GetArtifactToolExeName());
426430
if (File.Exists(exePath))
427431
{
428432
return exePath;
@@ -431,6 +435,9 @@ private void CreatePackageListJson(IReadOnlyCollection<UniversalPackage> package
431435
Log.LogError($"ArtifactTool '{exePath}' was not found.");
432436
return null;
433437
}
438+
439+
static string GetArtifactToolExeName()
440+
=> RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "artifacttool.exe" : "artifacttool";
434441
}
435442

436443
private (string Version, string DownloadUri)? GetArtifactToolReleaseInfo(string osName, string arch, string patVar)
@@ -621,7 +628,12 @@ private string GetArtifactToolReleaseInfoUrl(string osName, string arch)
621628
// Download only if needed
622629
if (!Directory.Exists(credentialProviderDir))
623630
{
624-
bool downloadResult = DownloadAndExtractArchive("Artifacts Credential Provider", releaseInfo.Value.DownloadUri, credentialProviderDir, isZip: RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
631+
bool downloadResult = DownloadAndExtractArchive(
632+
"Artifacts Credential Provider",
633+
releaseInfo.Value.DownloadUri,
634+
credentialProviderDir,
635+
GetArtifactsCredentialProviderRelativePath(),
636+
isZip: RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
625637
if (!downloadResult)
626638
{
627639
return null;
@@ -638,7 +650,9 @@ private string GetArtifactToolReleaseInfoUrl(string osName, string arch)
638650
return null;
639651
}
640652

641-
string GetArtifactsCredentialProviderExePath(string dir) => Path.Combine(dir, "plugins", "netcore", "CredentialProvider.Microsoft", exeName);
653+
string GetArtifactsCredentialProviderExePath(string dir) => Path.Combine(dir, GetArtifactsCredentialProviderRelativePath());
654+
655+
string GetArtifactsCredentialProviderRelativePath() => Path.Combine("plugins", "netcore", "CredentialProvider.Microsoft", exeName);
642656
}
643657

644658
private (string Version, string DownloadUri)? GetArtifactsCredentialProviderReleaseInfo()
@@ -737,7 +751,7 @@ private string GetArtifactToolReleaseInfoUrl(string osName, string arch)
737751
return (version, downloadUri);
738752
}
739753

740-
private bool DownloadAndExtractArchive(string displayName, string downloadUri, string path, bool isZip)
754+
private bool DownloadAndExtractArchive(string displayName, string downloadUri, string path, string exeRelativePath, bool isZip)
741755
{
742756
string? archiveDownloadPath = null;
743757
string? archiveExtractPath = null;
@@ -766,6 +780,28 @@ private bool DownloadAndExtractArchive(string displayName, string downloadUri, s
766780
if (isZip)
767781
{
768782
ZipFile.ExtractToDirectory(archiveDownloadPath, archiveExtractPath);
783+
784+
// Zip archives do not preserve Unix file permissions, so we need to set the executable bit manually.
785+
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
786+
{
787+
string exePath = Path.Combine(archiveExtractPath, exeRelativePath);
788+
if (!File.Exists(exePath))
789+
{
790+
Log.LogError($"Failed to set executable bit on {exePath}. File not found.");
791+
return false;
792+
}
793+
794+
int exitCode = ProcessHelper.Execute(
795+
"/bin/chmod",
796+
$"+x \"{exePath}\"",
797+
processStdOut: message => Log.LogMessage(MessageImportance.Low, message),
798+
processStdErr: message => Log.LogError(message));
799+
if (exitCode != 0)
800+
{
801+
Log.LogError($"Failed to set executable bit on {exePath}. chmod failed with exit code: {exitCode}");
802+
return false;
803+
}
804+
}
769805
}
770806
else
771807
{
@@ -792,6 +828,7 @@ private bool DownloadAndExtractArchive(string displayName, string downloadUri, s
792828
destination.Delete(true);
793829
}
794830

831+
Log.LogMessage(MessageImportance.Low, $"Moving {archiveExtractPath} to {destination.FullName}");
795832
destination.Parent?.Create();
796833
Directory.Move(archiveExtractPath, destination.FullName);
797834

0 commit comments

Comments
 (0)