Improve make-pkg.ps1

Add a hack inject dotnet runtime 6.0+ to support create cross platform zip on windows.
This commit is contained in:
halx99 2023-12-27 22:55:35 +08:00
parent 54daf354cd
commit 9af781f419
2 changed files with 180 additions and 45 deletions

2
.gitattributes vendored
View File

@ -1,5 +1,5 @@
# Auto detect text files and perform LF normalization # Auto detect text files and perform LF normalization
* text=auto * text=auto eol=lf
# Custom for Visual Studio # Custom for Visual Studio
*.cs diff=csharp *.cs diff=csharp
*.sln merge=union *.sln merge=union

View File

@ -1,12 +1,10 @@
param( param(
$version = $null $version = $null
) )
Write-Host "Creating package $pkg_file_path ..."
$AX_ROOT = (Resolve-Path $PSScriptRoot/../..).Path $AX_ROOT = (Resolve-Path $PSScriptRoot/../..).Path
if(!$version -or ($version -eq 'auto')) { if (!$version -or ($version -eq 'auto')) {
$axver_file = (Resolve-Path $AX_ROOT/core/axmolver.h.in).Path $axver_file = (Resolve-Path $AX_ROOT/core/axmolver.h.in).Path
$axver_content = $(Get-Content -Path $axver_file) $axver_content = $(Get-Content -Path $axver_file)
function parse_axver($part) { function parse_axver($part) {
@ -16,7 +14,7 @@ if(!$version -or ($version -eq 'auto')) {
$axver = "$(parse_axver 'MAJOR').$(parse_axver 'MINOR').$(parse_axver 'PATCH')" $axver = "$(parse_axver 'MAJOR').$(parse_axver 'MINOR').$(parse_axver 'PATCH')"
$git_prog = (Get-Command 'git' -ErrorAction SilentlyContinue).Source $git_prog = (Get-Command 'git' -ErrorAction SilentlyContinue).Source
if($git_prog) { if ($git_prog) {
$branchName = $(git -C $AX_ROOT branch --show-current) $branchName = $(git -C $AX_ROOT branch --show-current)
if ($branchName -eq 'dev') { if ($branchName -eq 'dev') {
$commitHash = $(git -C $AX_ROOT rev-parse --short=7 HEAD) $commitHash = $(git -C $AX_ROOT rev-parse --short=7 HEAD)
@ -51,29 +49,34 @@ $excludes = @(
$pkg_file_name = "axmol-$version.zip" $pkg_file_name = "axmol-$version.zip"
$pkg_file_path = $(Join-Path $AX_ROOT $pkg_file_name) $pkg_file_path = $(Join-Path $AX_ROOT $pkg_file_name)
Write-Host "Creating package $pkg_file_path ..."
$compress_args = @{ $compress_args = @{
Path = $AX_ROOT Path = $AX_ROOT
CompressionLevel = 'Optimal' CompressionLevel = 'Optimal'
DestinationPath = $pkg_file_path DestinationPath = $pkg_file_path
RelativeBasePath = $AX_ROOT RelativeBasePath = $AX_ROOT
Exclude = $excludes Exclude = $excludes
Prefix = "axmol-$version" Prefix = "axmol-$version"
} }
# Compress-Archive @compress -PassThru # Compress-Archive @compress -PassThru
function Compress-ArchiveEx() { function Compress-ArchiveEx() {
param( param(
$Path, $Path,
$CompressionLevel = 'Optimal', $CompressionLevel = 'Optimal',
$DestinationPath, $DestinationPath,
$Exclude, $Exclude,
$Prefix = '', $Prefix = '',
$RelativeBasePath = '', $RelativeBasePath = '',
[switch]$Force [switch]$Force
) )
if($RelativeBasePath) { $Script:S_IFREG = 0x8000
# $S_IFDIR = 0x4000
if ($RelativeBasePath) {
Push-Location $RelativeBasePath Push-Location $RelativeBasePath
} }
@ -85,69 +88,201 @@ function Compress-ArchiveEx() {
Add-Type -AssemblyName System.IO.Compression Add-Type -AssemblyName System.IO.Compression
Add-Type -AssemblyName System.IO.Compression.FileSystem Add-Type -AssemblyName System.IO.Compression.FileSystem
} }
$archive = [System.IO.Compression.ZipFile]::Open($DestinationPath, [System.IO.Compression.ZipArchiveMode]::Create)
$pwsh_ver = $PSVersionTable.PSVersion.ToString()
if (([System.Version]$pwsh_ver -ge [System.Version]'7.0.0.0') -and $IsWindows) {
if (-not ([System.Management.Automation.PSTypeName]'UnixFileStream').Type) {
Add-Type -TypeDefinition @"
// A hack to create unix style .zip on windows
// refers:
// - https://github.com/dotnet/runtime/blob/main/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipVersion.cs#L24
// - https://github.com/dotnet/runtime/blob/main/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs#L529C26-L529C50
using System.Text;
using System.IO;
using System.IO.Compression;
public class MyZipFile : ZipArchive
{
public UnixFileStream Stream { get; set; }
public MyZipFile(UnixFileStream stream, ZipArchiveMode mode, bool leaveOpen) : base(stream, mode, leaveOpen)
{
Stream = stream;
}
protected override void Dispose(bool disposing)
{
if (disposing)
Stream.IsDisposing = true;
base.Dispose(disposing);
}
}
public class UnixFileStream : FileStream
{
internal enum ZipVersionMadeByPlatform : byte
{
Windows = 0,
Unix = 3
}
// public const uint DirectoryFileHeaderSignatureConstant = 0x02014B50;
// public const uint LocalFileHeaderSignatureConstant = 0x04034B50;
int m_hints = -1;
int m_hints2 = -1;
public UnixFileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool useAsync) : base(path, mode, access, share, bufferSize, useAsync)
{
}
public override void WriteByte(byte value)
{
if (m_hints2 != -1) ++m_hints;
if (IsDisposing)
{
if (m_hints != -1) ++m_hints;
if (m_hints == 2)
{ // hint: CurrentZipPlatform: hack set to unix
value = (byte)ZipVersionMadeByPlatform.Unix;
}
}
base.WriteByte(value);
}
public override void Write(byte[] array, int offset, int count)
{
if (IsDisposing)
{ // hint: entryHeaderSignature
if ((count == 4 && array[0] == 0x50 && array[1] == 0x4b && array[2] == 0x01 && array[3] == 0x02) || m_hints != -1)
++m_hints;
if (m_hints == 17) // hint: filepath
{
var path = Encoding.UTF8.GetString(array);
array = Encoding.UTF8.GetBytes(path.Replace('\\', '/'));
m_hints = -1;
}
}
if ((count == 4 && array[0] == 0x50 && array[1] == 0x4b && array[2] == 0x03 && array[3] == 0x04) || m_hints2 != -1)
++m_hints2;
if (m_hints2 == 10) {
var path = Encoding.UTF8.GetString(array);
array = Encoding.UTF8.GetBytes(path.Replace('\\', '/'));
m_hints2 = -1;
}
base.Write(array, offset, count);
}
public bool IsDisposing { set; get; } = false;
public static ZipArchive CreateUnixZipFile(string archiveFileName)
{
var fs = new UnixFileStream(archiveFileName, FileMode.CreateNew, FileAccess.Write, FileShare.None, bufferSize: 0x1000, useAsync: false);
try
{
return new MyZipFile(fs, ZipArchiveMode.Create, leaveOpen: false);
}
catch
{
fs.Dispose();
throw;
}
}
}
"@
}
$archive = [UnixFileStream]::CreateUnixZipFile($DestinationPath)
}
else {
$archive = [System.IO.Compression.ZipFile]::Open($DestinationPath, [System.IO.Compression.ZipArchiveMode]::Create)
}
$compressionLevelValue = @{ $compressionLevelValue = @{
'Optimal' = [System.IO.Compression.CompressionLevel]::Optimal 'Optimal' = [System.IO.Compression.CompressionLevel]::Optimal
'Fastest' = [System.IO.Compression.CompressionLevel]::Fastest 'Fastest' = [System.IO.Compression.CompressionLevel]::Fastest
'NoCompression' = [System.IO.Compression.CompressionLevel]::NoCompression 'NoCompression' = [System.IO.Compression.CompressionLevel]::NoCompression
}[$CompressionLevel] }[$CompressionLevel]
[array]$Excludes = $Exclude [array]$Excludes = $Exclude
[array]$Paths = $Path [array]$Paths = $Path
$_is_exclude = { $_is_exclude = {
param($uxpath) param($uxpath)
foreach($exclude in $Excludes) { foreach ($exclude in $Excludes) {
if($uxpath -like $exclude) { if ($uxpath -like $exclude) {
return $true return $true
} }
} }
return $false return $false
} }
$Script:total = 0 $Script:total = 0
$_zip_add = { $_zip_add = {
param($archive, $path, $compressionLevel, $prefix) param($archive, $path, $compressionLevel, $prefix)
if(!$path.LinkType) { if (!$path.LinkType) {
# -RelativeBasePath add in powershell 7.4 which github ci is 7.2 not support # -RelativeBasePath add in powershell 7.4 which github ci is 7.2 not support
$rname = $(Resolve-Path -Path $path -Relative).Replace('\', '/') $rname = $(Resolve-Path -Path $path -Relative).Replace('\', '/')
if ($rname.StartsWith('./')) { $rname = $rname.TrimStart('./') } if ($rname.StartsWith('./')) { $rname = $rname.TrimStart('./') }
$excluded = (&$_is_exclude -uxpath $rname) $excluded = (&$_is_exclude -uxpath $rname)
if(!$excluded) { if (!$excluded) {
if($prefix) { $rname = Join-Path $prefix $rname }
if (!$path.PSIsContainer) { if (!$path.PSIsContainer) {
++$Script:total Write-Host "a $rname"
$zentry = $archive.CreateEntry($rname) # preserve unix file permissions mode
# refer https://github.com/PowerShell/Microsoft.PowerShell.Archive/pull/146/files
$uxmode = $null
if ($path.UnixStat) { if ($path.UnixStat) {
# when run on unix, set permissions same with origin file $uxmode = $path.UnixStat.Mode
# refer https://github.com/PowerShell/Microsoft.PowerShell.Archive/pull/146/files }
$zentry.ExternalAttributes = ((0x8000 -bor $path.UnixStat.Mode) -shl 16) else {
$fileext = Split-Path $rname -Extension
if (!$fileext -or $rname.EndsWith('.sh')) {
$filestatus = $(git -C $AX_ROOT ls-files -s $rname)
if ($filestatus) {
$uxmode = [Convert]::ToInt32($filestatus.Split(' ')[0], 8)
}
}
} }
if (!$uxmode) {
# default unix file permissions
$uxmode = [Convert]::ToInt32('100644', 8)
}
if ($prefix) {
$rname = Join-Path $prefix $rname
}
$zentry = $archive.CreateEntry($rname)
$zentry.ExternalAttributes = (($Script:S_IFREG -bor $uxmode) -shl 16)
$zentryWriter = New-Object -TypeName System.IO.BinaryWriter $zentry.Open() $zentryWriter = New-Object -TypeName System.IO.BinaryWriter $zentry.Open()
$zentryWriter.Write([System.IO.File]::ReadAllBytes($path)) $zentryWriter.Write([System.IO.File]::ReadAllBytes($path))
$zentryWriter.Flush() $zentryWriter.Flush()
$zentryWriter.Close() $zentryWriter.Close()
} else {
++$Script:total
}
else {
$sub_paths = Get-ChildItem $path $sub_paths = Get-ChildItem $path
foreach($sub_path in $sub_paths) { foreach ($sub_path in $sub_paths) {
&$_zip_add $archive $sub_path $compressionLevel $prefix &$_zip_add $archive $sub_path $compressionLevel $prefix
} }
} }
} }
else { else {
Write-Host "x` $path" Write-Host "x $rname"
} }
} }
else { else {
Write-Host "x $path, LinkType=$($Path.LinkType)" Write-Host "x $rname, LinkType=$($Path.LinkType)"
} }
} }
# write entries with relative paths as names # write entries with relative paths as names
foreach ($path in $Paths) { foreach ($path in $Paths) {
if($path.GetType() -eq [string]) { if ($path.GetType() -eq [string]) {
$path = Get-Item $path $path = Get-Item $path
} }
&$_zip_add $archive $path $compressionLevelValue $Prefix &$_zip_add $archive $path $compressionLevelValue $Prefix
@ -156,7 +291,7 @@ function Compress-ArchiveEx() {
# release zip file # release zip file
$archive.Dispose() $archive.Dispose()
if($RelativeBasePath) { if ($RelativeBasePath) {
Pop-Location Pop-Location
} }
@ -172,10 +307,10 @@ Write-Host "Create package $pkg_file_path done, ${total} files found, MD5: $md5_
Pop-Location Pop-Location
if($env:GITHUB_ACTIONS -eq 'true') { if ($env:GITHUB_ACTIONS -eq 'true') {
$release_note = Join-Path $AX_ROOT "release_note_draft.txt" $release_note = Join-Path $AX_ROOT "release_note_draft.txt"
[System.IO.File]::WriteAllText($release_note, "## MD5 Hash of the release artifacts`n - ``${pkg_file_name}``: $md5_digest") [System.IO.File]::WriteAllText($release_note, "## MD5 Hash of the release artifacts`n - ``${pkg_file_name}``: $md5_digest")
echo "release_tag=v$version" >> ${env:GITHUB_OUTPUT} echo "release_tag=v$version" >> ${env:GITHUB_OUTPUT}
echo "release_pkg=$pkg_file_name" >> ${env:GITHUB_OUTPUT} echo "release_pkg=$pkg_file_name" >> ${env:GITHUB_OUTPUT}
echo "release_note=$release_note" >> ${env:GITHUB_OUTPUT} echo "release_note=$release_note" >> ${env:GITHUB_OUTPUT}
} }