fix(ci): package cross-platform tarballs on Windows [CI SKIP]

This commit is contained in:
justme committed 2026-10-04 12:38:13 -07:00
1 parent 92b72d4443
commit d4b4869501
3 files changed
+55 -19

No files matched your search

+8
View File
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
+38
View File
@@ -0,0 +1,38 @@
using System.Formats.Tar;
using System.IO.Compression;
if (args.Length < 3)
{
Console.Error.WriteLine("usage: Monitor.Tar <source-directory> <archive-path> <executable-relative-path>...");
return 2;
}
string sourceDirectory = Path.GetFullPath(args[0]);
string archivePath = Path.GetFullPath(args[1]);
HashSet<string> executables = args.Skip(2).Select(path => path.Replace('\\', '/')).ToHashSet(StringComparer.Ordinal);
UnixFileMode executableMode = UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute |
UnixFileMode.GroupRead | UnixFileMode.GroupExecute |
UnixFileMode.OtherRead | UnixFileMode.OtherExecute;
UnixFileMode regularMode = UnixFileMode.UserRead | UnixFileMode.UserWrite |
UnixFileMode.GroupRead | UnixFileMode.OtherRead;
Directory.CreateDirectory(Path.GetDirectoryName(archivePath)!);
using FileStream fileStream = File.Create(archivePath);
using GZipStream gzipStream = new(fileStream, CompressionLevel.Optimal, leaveOpen: true);
using TarWriter writer = new(gzipStream, TarEntryFormat.Pax, leaveOpen: true);
foreach (string filePath in Directory.EnumerateFiles(sourceDirectory, "*", SearchOption.AllDirectories))
{
string relativePath = Path.GetRelativePath(sourceDirectory, filePath).Replace('\\', '/');
PaxTarEntry entry = new(TarEntryType.RegularFile, relativePath)
{
Mode = executables.Contains(relativePath) ? executableMode : regularMode,
DataStream = File.OpenRead(filePath)
};
using (entry.DataStream)
{
writer.WriteEntry(entry);
}
}
return 0;
+9 -19
View File
@@ -15,31 +15,21 @@ if ($version -ne $projectVersion) {
throw "Tag version $version does not match project version $projectVersion."
}
Add-Type -AssemblyName System.Formats.Tar
$tarProject = Join-Path $PSScriptRoot 'Monitor.Tar\Monitor.Tar.csproj'
$tarTool = Join-Path $PSScriptRoot 'Monitor.Tar\bin\Release\net10.0\Monitor.Tar.dll'
& dotnet build $tarProject -c Release --nologo
if ($LASTEXITCODE -ne 0) {
throw 'Could not build the cross-platform tar helper.'
}
$giteaBase = if ($env:GITEA_BASE) { $env:GITEA_BASE.TrimEnd('/') } else { 'http://localhost:3100' }
$netrc = Join-Path $env:TEMP ("monitor-gitea-$([guid]::NewGuid().ToString('N')).netrc")
$giteaHost = ([Uri]$giteaBase).Host
Set-Content -LiteralPath $netrc -Value "machine $giteaHost login justme password $($env:GITEA_TOKEN)" -Encoding ascii -NoNewline
function New-TarGzArchive([string]$SourceDirectory, [string]$ArchivePath, [string[]]$Executables) {
$tarFile = [IO.File]::Create($ArchivePath)
$gzip = [IO.Compression.GZipStream]::new($tarFile, [IO.Compression.CompressionLevel]::Optimal, $true)
$writer = [System.Formats.Tar.TarWriter]::new($gzip, [System.Formats.Tar.TarEntryFormat]::Pax, $true)
$executableMode = [System.IO.UnixFileMode]::UserRead -bor [System.IO.UnixFileMode]::UserWrite -bor [System.IO.UnixFileMode]::UserExecute -bor [System.IO.UnixFileMode]::GroupRead -bor [System.IO.UnixFileMode]::GroupExecute -bor [System.IO.UnixFileMode]::OtherRead -bor [System.IO.UnixFileMode]::OtherExecute
$regularMode = [System.IO.UnixFileMode]::UserRead -bor [System.IO.UnixFileMode]::UserWrite -bor [System.IO.UnixFileMode]::GroupRead -bor [System.IO.UnixFileMode]::OtherRead
try {
foreach ($file in Get-ChildItem -LiteralPath $SourceDirectory -File -Recurse) {
$relativePath = [IO.Path]::GetRelativePath($SourceDirectory, $file.FullName).Replace('\', '/')
$entry = [System.Formats.Tar.PaxTarEntry]::new([System.Formats.Tar.TarEntryType]::RegularFile, $relativePath)
$entry.Mode = if ($Executables -contains $relativePath) { $executableMode } else { $regularMode }
$entry.DataStream = [IO.File]::OpenRead($file.FullName)
try { $writer.WriteEntry($entry) } finally { $entry.DataStream.Dispose() }
}
}
finally {
$writer.Dispose()
$gzip.Dispose()
$tarFile.Dispose()
& dotnet $tarTool $SourceDirectory $ArchivePath @Executables
if ($LASTEXITCODE -ne 0) {
throw "Could not create tar archive $ArchivePath."
}
}