Skip to content

Commit

Permalink
Merge pull request #67 from Deadpikle/feature/tar-zip-handling
Browse files Browse the repository at this point in the history
Use .NET built-in Tar and Zip handling
  • Loading branch information
xoofx authored Nov 13, 2024
2 parents d142349 + 63f9d63 commit 24654e5
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 5 deletions.
93 changes: 93 additions & 0 deletions src/DotNetReleaser.Tests/BasicTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Formats.Tar;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
Expand Down Expand Up @@ -110,6 +112,97 @@ public async Task TestBuild()
File.Delete(_configurationFile);
}

[Test]
public async Task TestMacOSTarZipAreExecutable()
{
EnsureTestsFolder();

File.Delete(_configurationFile);

await CreateConfiguration();

var config = await File.ReadAllTextAsync(_configurationFile);

if (Directory.Exists(_artifactsFolder))
{
Directory.Delete(_artifactsFolder, true);
}

config = "profile = \"custom\"" + Environment.NewLine + config;
config += @"
[msbuild.properties]
SelfContained = false
PublishSingleFile = false
PublishTrimmed = false
[[pack]]
rid = ""osx-x64""
kinds = [""tar"", ""zip""]
[nuget]
publish = false
";
config = config.Replace("\r\n", "\n").Replace("\n", Environment.NewLine);
await File.WriteAllTextAsync(_configurationFile, config);

var resultBuild = await CliWrap.Cli.Wrap(_releaserExe)
.WithArguments("build --force dotnet-releaser.toml")
.WithStandardOutputPipe(PipeTarget.ToDelegate(x => Console.Out.WriteLine(x)))
.WithStandardErrorPipe(PipeTarget.ToDelegate(x => Console.Error.WriteLine(x)))
.WithWorkingDirectory(_helloWorldFolder).ExecuteAsync();

Assert.True(Directory.Exists(_artifactsFolder));

var files = Directory.GetFiles(_artifactsFolder).Select(Path.GetFileName).OrderBy(x => x).ToList();

var expectedFiles = new List<string>()
{
"HelloWorld.0.1.0.osx-x64.tar.gz",
"HelloWorld.0.1.0.osx-x64.zip",
}.OrderBy(x => x).ToList();

foreach (var file in files)
{
Console.WriteLine($"-> {file}");
}

Assert.AreEqual(expectedFiles, files);

if (!OperatingSystem.IsWindows())
{
// ensure files are executable
var tar = Path.Combine(_artifactsFolder, "HelloWorld.0.1.0.osx-x64.tar.gz");
using FileStream fs = new(tar, FileMode.Open, FileAccess.Read);
using var gzip = new GZipStream(fs, CompressionMode.Decompress);
using var unzippedStream = new MemoryStream();
{
await gzip.CopyToAsync(unzippedStream);
unzippedStream.Seek(0, SeekOrigin.Begin);

using var reader = new TarReader(unzippedStream);

while (reader.GetNextEntry() is TarEntry entry)
{
if (entry.Name == "./HelloWorld")
{
Assert.IsTrue(entry.Mode.HasFlag(UnixFileMode.GroupExecute));
Assert.IsTrue(entry.Mode.HasFlag(UnixFileMode.OtherExecute));
Assert.IsTrue(entry.Mode.HasFlag(UnixFileMode.UserExecute));
break;
}
}
}
// extract zip files and check executable
var zippath = Path.Combine(_artifactsFolder, "HelloWorld.0.1.0.osx-x64.zip");
ZipFile.ExtractToDirectory(zippath, _artifactsFolder);
var fileMode = File.GetUnixFileMode(Path.Combine(_artifactsFolder, "HelloWorld"));
Assert.IsTrue(fileMode.HasFlag(UnixFileMode.GroupExecute));
Assert.IsTrue(fileMode.HasFlag(UnixFileMode.OtherExecute));
Assert.IsTrue(fileMode.HasFlag(UnixFileMode.UserExecute));
}

Directory.Delete(_artifactsFolder, true);
File.Delete(_configurationFile);
}

[Test]
public async Task TestBuildService()
{
Expand Down
51 changes: 51 additions & 0 deletions src/dotnet-releaser/Helpers/CompressionHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System.Formats.Tar;
using System.IO;
using System.IO.Compression;

namespace DotNetReleaser.Helpers;

internal static class CompressionHelper
{
public static string? MakeTarGz(ProjectPackageInfo projectPackageInfo, string publishDir, string artifactsFolder, string rid)
{
string? outputPath = null;
var publishPath = Path.Combine(Path.GetDirectoryName(projectPackageInfo.ProjectFullPath) ?? "", publishDir);
if (Directory.Exists(publishPath))
{
var gzipPath = Path.GetFullPath(Path.Combine(artifactsFolder,
projectPackageInfo.Name + "." + projectPackageInfo.Version + "." + rid + ".tar.gz"));
if (File.Exists(gzipPath))
{
return null; // file already exists
}
using FileStream fs = new(gzipPath, FileMode.CreateNew, FileAccess.Write);
using GZipStream gz = new(fs, CompressionMode.Compress, leaveOpen: true);
{
TarFile.CreateFromDirectory(publishPath, gz, includeBaseDirectory: false);
}
outputPath = gzipPath;
}
return outputPath;
}

public static string? MakeZip(ProjectPackageInfo projectPackageInfo, string publishDir, string artifactsFolder, string rid)
{
string? outputPath = null;
var publishPath = Path.Combine(Path.GetDirectoryName(projectPackageInfo.ProjectFullPath) ?? "", publishDir);
if (Directory.Exists(publishPath))
{
var zipPath = Path.GetFullPath(Path.Combine(artifactsFolder,
projectPackageInfo.Name + "." + projectPackageInfo.Version + "." + rid + ".zip"));
if (File.Exists(zipPath))
{
return null; // file already exists
}
using FileStream fs = new(zipPath, FileMode.CreateNew, FileAccess.Write);
{
ZipFile.CreateFromDirectory(publishPath, fs, compressionLevel: CompressionLevel.Optimal, includeBaseDirectory: false);
}
outputPath = zipPath;
}
return outputPath;
}
}
24 changes: 23 additions & 1 deletion src/dotnet-releaser/ReleaserApp.AppPackaging.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Security.Cryptography;
using System.Threading.Tasks;
using DotNetReleaser.Configuration;
using DotNetReleaser.Helpers;
using DotNetReleaser.Logging;
using Spectre.Console;

Expand Down Expand Up @@ -225,7 +226,28 @@ private async Task<List<AppPackageInfo>> BuildAppPackages(BuildInformation build

// Copy the file to the output
var path = result[0].ItemSpec;
path = CopyToArtifacts(path);
if (target == ReleaserConstants.DotNetReleaserPublishAndCreateTar)
{
path = CompressionHelper.MakeTarGz(projectPackageInfo, path, _config.ArtifactsFolder, rid);
if (path is null)
{
Error("Unable to make tar file with publish directory " + path + "; does the file already exist?");
break;
}
}
else if (target == ReleaserConstants.DotNetReleaserPublishAndCreateZip)
{
path = CompressionHelper.MakeZip(projectPackageInfo, path, _config.ArtifactsFolder, rid);
if (path is null)
{
Error("Unable to make zip file with publish directory " + path + "; does the file already exist?");
break;
}
}
else
{
path = CopyToArtifacts(path);
}

var sha256 = string.Join("", SHA256.HashData(await File.ReadAllBytesAsync(path)).Select(x => x.ToString("x2")));

Expand Down
9 changes: 5 additions & 4 deletions src/dotnet-releaser/dotnet-releaser.targets
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
<_DotNetReleaserGetPackageInfo Include="$(IsPackable)" Kind="IsNuGetPackable"/>
<_DotNetReleaserGetPackageInfo Include="$(IsTestProject)" Kind="IsTestProject"/>
<_DotNetReleaserGetPackageInfo Include="@(ProjectReference)" Kind="ProjectReference"/>
<_DotNetReleaserGetPackageInfo Include="$([System.IO.Path]::GetFullPath('$(PublishDir)'))" Kind="PublishDir"/>
</ItemGroup>
</Target>

Expand All @@ -116,14 +117,14 @@
<_DotNetReleaserPublishAndCreateRpm Include="$(RpmPath)" Kind="RpmPath"/>
</ItemGroup>
</Target>
<Target Name="DotNetReleaserPublishAndCreateZip" Outputs="@(_DotNetReleaserPublishAndCreateZip)" DependsOnTargets="CreateZip">
<Target Name="DotNetReleaserPublishAndCreateZip" Outputs="@(_DotNetReleaserPublishAndCreateZip)" DependsOnTargets="Publish">
<ItemGroup>
<_DotNetReleaserPublishAndCreateZip Include="$(ZipPath)" Kind="ZipPath"/>
<_DotNetReleaserPublishAndCreateZip Include="$(PublishDir)" Kind="PublishDir"/>
</ItemGroup>
</Target>
<Target Name="DotNetReleaserPublishAndCreateTar" Outputs="@(_DotNetReleaserPublishAndCreateTar)" DependsOnTargets="CreateTarball">
<Target Name="DotNetReleaserPublishAndCreateTar" Outputs="@(_DotNetReleaserPublishAndCreateTar)" DependsOnTargets="Publish">
<ItemGroup>
<_DotNetReleaserPublishAndCreateTar Include="$(TarballPath)" Kind="TarballPath"/>
<_DotNetReleaserPublishAndCreateTar Include="$(PublishDir)" Kind="PublishDir"/>
</ItemGroup>
</Target>
</Project>

0 comments on commit 24654e5

Please sign in to comment.