ensure archived before release step. #2
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: HoloPatcher Release | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref }} | |
cancel-in-progress: true | |
env: | |
OS_RUNNERS_JSON: '["windows-2019", "ubuntu-20.04", "macos-12"]' | |
PYTHON_VERSIONS_JSON: '["3.8"]' | |
ARCHITECTURES_JSON: '["x86", "x64"]' | |
INTERPRETERS_JSON: '["python"]' | |
UPX_VERSION: '4.2.2' | |
on: | |
push: | |
tags: | |
- 'v*.**-patcher' | |
workflow_dispatch: | |
permissions: | |
contents: write | |
jobs: | |
setup: | |
runs-on: ubuntu-latest | |
outputs: | |
os: ${{ steps.set_env.outputs.os }} | |
python-version: ${{ steps.set_env.outputs.python-version }} | |
architecture: ${{ steps.set_env.outputs.architecture }} | |
python-pypy: ${{ steps.set_env.outputs.python-pypy }} | |
#qt_version: ${#{ steps.set_env.outputs.qt_version }} | |
steps: | |
- name: Set environment variables | |
id: set_env | |
run: | | |
# Use a single line of JSON to avoid issues | |
$singleLineJson = '${{ env.OS_RUNNERS_JSON }}' -replace "`r", "" | |
$singleLineJson = $singleLineJson -replace "`n", "" | |
Write-Host $singleLineJson | |
echo "os<<EOF" >> $env:GITHUB_OUTPUT | |
echo $singleLineJson >> $env:GITHUB_OUTPUT | |
echo "EOF" >> $env:GITHUB_OUTPUT | |
$singleLineJson = '${{ env.PYTHON_VERSIONS_JSON }}' -replace "`r", "" | |
$singleLineJson = $singleLineJson -replace "`n", "" | |
Write-Host $singleLineJson | |
echo "python-version<<EOF" >> $env:GITHUB_OUTPUT | |
echo $singleLineJson >> $env:GITHUB_OUTPUT | |
echo "EOF" >> $env:GITHUB_OUTPUT | |
$singleLineJson = '${{ env.ARCHITECTURES_JSON }}' -replace "`r", "" | |
$singleLineJson = $singleLineJson -replace "`n", "" | |
Write-Host $singleLineJson | |
echo "architecture<<EOF" >> $env:GITHUB_OUTPUT | |
echo $singleLineJson >> $env:GITHUB_OUTPUT | |
echo "EOF" >> $env:GITHUB_OUTPUT | |
$singleLineJson = '${{ env.INTERPRETERS_JSON }}' -replace "`r", "" | |
$singleLineJson = $singleLineJson -replace "`n", "" | |
Write-Host $singleLineJson | |
echo "python-pypy<<EOF" >> $env:GITHUB_OUTPUT | |
echo $singleLineJson >> $env:GITHUB_OUTPUT | |
echo "EOF" >> $env:GITHUB_OUTPUT | |
shell: pwsh | |
build: | |
needs: setup | |
runs-on: ${{ matrix.os }} | |
strategy: | |
fail-fast: false # Disable automatic cancellation of other jobs | |
matrix: | |
os: ${{ fromJson(needs.setup.outputs.os) }} | |
python-version: ${{ fromJson(needs.setup.outputs.python-version) }} | |
architecture: ${{ fromJson(needs.setup.outputs.architecture) }} | |
python_pypy: ${{ fromJson(needs.setup.outputs.python-pypy) }} | |
#qt_version: ['pyqt5', 'pyqt6', 'pyside2', 'pyside6'] | |
include: | |
- arch: x86 | |
vc_redist2015: "https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x86.exe" | |
vc_redist-latest: "https://aka.ms/vs/17/release/vc_redist.x86.exe" | |
vc_redist2019: "https://aka.ms/vs/17/release/vc_redist.x86.exe" | |
- arch: x64 | |
vc_redist2015: "https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x64.exe" | |
vc_redist-latest: "https://aka.ms/vs/17/release/vc_redist.x64.exe" | |
vc_redist2019: "https://aka.ms/vs/17/release/vc_redist.x64.exe" | |
exclude: | |
# unix x86 is definitely not supported. | |
- os: ubuntu-20.04 | |
architecture: x86 | |
- os: macos-12 | |
architecture: x86 | |
# latest PyPy version as of 17/03/2024 is 3.10. | |
- python_pypy: 'pypy' | |
python-version: '3.11' | |
- python_pypy: 'pypy' | |
python-version: '3.12' | |
# PyQt5 doesn't seem to be compatible with PyPy | |
#- python_pypy: "pypy" | |
# qt_version: 'pyqt5' | |
#- python_pypy: "pypy" | |
# qt_version: 'pyside2' | |
#- python_pypy: "pypy" | |
# qt_version: 'pyqt6' | |
#- python_pypy: "pypy" | |
# python-version: '3.10' | |
# os: 'windows-2019' | |
outputs: | |
matrix-os: ${{ toJson(matrix.os) }} | |
matrix-python-version: ${{ toJson(matrix.python-version) }} | |
steps: | |
- name: Determine Python version string | |
id: set-python-version | |
run: | | |
if ( "${{ matrix.python_pypy }}" -eq "pypy" ) { | |
Add-Content -Path $env:GITHUB_ENV -Value "PYTHON_VERSION=pypy-${{ matrix.python-version }}" | |
} else { | |
Add-Content -Path $env:GITHUB_ENV -Value "PYTHON_VERSION=${{ matrix.python-version }}" | |
} | |
shell: pwsh | |
- uses: actions/checkout@v4 | |
- name: Test Powershell installer | |
if: ${{ runner.os != 'Windows' }} | |
id: setup-powershell | |
run: | | |
bash ./install_powershell.sh | |
shell: bash | |
- name: Set up ${{ matrix.python_pypy }} ${{ matrix.python-version }} | |
if: ${{ runner.os != 'macOS' && (runner.os != 'Linux' || matrix.python_pypy == 'pypy') }} | |
uses: actions/setup-python@v5 | |
with: | |
python-version: ${{ env.PYTHON_VERSION }} | |
architecture: ${{ matrix.architecture }} | |
- name: Set up python 3.12 mac (stops brew erroring on linking) | |
if: ${{ runner.os == 'macOS' && matrix.python-version != '3.12' }} | |
run: | | |
brew install [email protected] --quiet || true | |
shell: bash | |
- name: Set up ${{ matrix.python_pypy }} ${{ matrix.python-version }} macOS | |
if: ${{ runner.os == 'macOS' }} | |
run: | # warning: `brew link --overwrite python@ver` is unsafe on any non-virtualized macos. | |
echo "NONINTERACTIVE DEFAULT: $NONINTERACTIVE" | |
export NONINTERACTIVE=1 | |
echo "NONINTERACTIVE NEW: $NONINTERACTIVE" | |
brew analytics on | |
brew update | |
brew install ${{ matrix.python_pypy }}@${{ matrix.python-version }} || brew link --overwrite ${{ matrix.python_pypy }}@${{ matrix.python-version }} | |
- name: Set up ${{ matrix.python_pypy }} ${{ matrix.python-version }} ${{ runner.os }} # macos too? | |
if: ${{ runner.os == 'Linux' && matrix.python_pypy == 'python' }} | |
run: | | |
if ("${{ runner.os }}" -eq "Linux") { | |
sudo apt-get update | |
sudo apt-get install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev libbz2-dev tk-dev -y | |
} elseif ("${{ runner.os }}" -eq "macOS") { | |
# Ensure Xcode Command Line Tools are installed? | |
# xcode-select --install 2>$null | Out-Null | |
} | |
$pyVersion = switch ("${{ matrix.python-version }}") { | |
"3.7" { "3.7.17" } | |
"3.8" { "3.8.18" } | |
"3.9" { "3.9.18" } | |
"3.10" { "3.10.13" } | |
"3.11" { "3.11.8" } | |
"3.12" { "3.12.2" } | |
} | |
Write-Output "Downloading ${{ matrix.python_pypy }} '$pyVersion'..." | |
Invoke-WebRequest -Uri https://www.python.org/ftp/python/$pyVersion/Python-$pyVersion.tgz -OutFile Python-$pyVersion.tgz | |
tar -xvf Python-$pyVersion.tgz | |
$current_working_dir = (Get-Location).Path | |
Set-Location -LiteralPath "Python-$pyVersion" -ErrorAction Stop | |
$env:LDFLAGS="" | |
sudo ./configure --enable-optimizations --with-ensurepip=install --enable-shared --disable-new-dtags | |
sudo make -j $(nproc) | |
sudo make altinstall | |
Set-Location -LiteralPath $current_working_dir | |
shell: pwsh | |
- name: Reset APT sources to default | |
if: ${{ runner.os == 'Linux' }} | |
run: | | |
echo "Resetting APT sources to default Ubuntu repositories" | |
sudo rm /etc/apt/sources.list | |
echo "deb http://archive.ubuntu.com/ubuntu $(lsb_release -cs) main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list | |
echo "deb http://archive.ubuntu.com/ubuntu $(lsb_release -cs)-updates main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list | |
echo "deb http://archive.ubuntu.com/ubuntu $(lsb_release -cs)-backports main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list | |
echo "deb http://security.ubuntu.com/ubuntu $(lsb_release -cs)-security main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list | |
sudo apt-get update -y | |
shell: bash | |
- name: Setup python venvs | |
run: | # create the venv early to work around an issue with the matrix runners' concurrency | |
$pythonExeName = "${{ matrix.python_pypy }}" | |
if ("${{ runner.os }}" -ne "Windows") | |
{ | |
$pythonExeName = "${{ matrix.python_pypy }}${{ matrix.python-version }}" | |
# LD_LIBRARY_PATH must be updated. However this won't be permanent, just long enough to create the venv. | |
$env:LD_LIBRARY_PATH = "/usr/local/lib:$env:LD_LIBRARY_PATH" | |
} | |
& $pythonExeName -m venv .venv_holopatcher_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
& $pythonExeName -m venv .venv_toolset_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
& $pythonExeName -m venv .venv_guiduplicator_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
& $pythonExeName -m venv .venv_kotordiff_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
& $pythonExeName -m venv .venv_batchpatcher_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
shell: pwsh | |
- name: Set UPX download URL | |
# upx docs express that crashes are happening on ventura and above with upx, don't use on mac. | |
if: runner.os != 'macOS' | |
id: upx_setup | |
run: | | |
$build = "no" | |
$archiveName = "" | |
if ("${{ runner.os }}" -eq "Windows") { | |
if ("${{ matrix.architecture }}" -eq "x86") { | |
$archiveName = "upx-${{ env.UPX_VERSION }}-win32.zip" | |
} else { | |
$archiveName = "upx-${{ env.UPX_VERSION }}-win64.zip" | |
} | |
} elseif ("${{ runner.os }}" -eq "Linux") { | |
$archiveName = "upx-${{ env.UPX_VERSION }}-amd64_linux.tar.xz" | |
} elseif ("${{ runner.os }}" -eq "macOS") { | |
$build = "yes" | |
$archiveName = "upx-${{ env.UPX_VERSION }}-src.tar.xz" | |
} | |
$url = "https://github.com/upx/upx/releases/download/v${{ env.UPX_VERSION }}/$archiveName" | |
# Write to the GITHUB_OUTPUT environment file | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "build=$build" | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "url=$url" | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "archiveName=$archiveName" | |
shell: pwsh | |
- name: Download and prepare UPX | |
if: runner.os != 'macOS' | |
run: | | |
$ext = "${{ runner.os }}" -eq "Windows" ? "zip" : "tar.xz" | |
$url = "${{ steps.upx_setup.outputs.url }}" | |
$archiveName = "${{ steps.upx_setup.outputs.archiveName }}" | |
$outputPath = "upx-dir" | |
# Use Invoke-WebRequest or curl depending on the OS | |
if ("${{ runner.os }}" -eq "Windows") { | |
Invoke-WebRequest -Uri $url -OutFile $archiveName | |
} elseif ("${{ runner.os }}" -eq "Linux") { | |
curl -L $url -o $archiveName | |
} | |
New-Item -ItemType Directory -Force -Path "upx-dir" -ErrorAction SilentlyContinue | |
if ("${{ runner.os }}" -ne "macOS") { | |
if ($ext -eq "zip") { | |
$fileNameWithoutExtension = [System.IO.Path]::GetFileNameWithoutExtension($archiveName) | |
Expand-Archive -Path $archiveName -DestinationPath "temp_folder_upx" | |
# Ensure upx-dir exists; create it if it doesn't | |
if (-not (Test-Path -Path "upx-dir")) { | |
New-Item -ItemType Directory -Path "upx-dir" | |
} | |
Get-ChildItem -Path "temp_folder_upx/$fileNameWithoutExtension" -Recurse | Move-Item -Destination "upx-dir" | |
Remove-Item "temp_folder_upx" -Recurse -Force -ErrorAction SilentlyContinue | |
} else { | |
tar -xvf $archiveName --strip-components=1 -C "upx-dir" | |
} | |
Remove-Item $archiveName # Clean up downloaded archive | |
} | |
shell: pwsh | |
- name: Set UPX directory path | |
if: runner.os != 'macOS' | |
id: upx_dir | |
run: | | |
$upx_dir = "./upx-dir" | |
$upx_dir = $([System.IO.Path]::GetFullPath('./upx-dir')) | |
Dir -Recurse $upx_dir | Get-Childitem | |
echo "UPX_DIR=$upx_dir" | Out-File -FilePath $env:GITHUB_ENV -Append | |
Write-Output "UPX_DIR set to '$upx_dir'" | |
shell: pwsh | |
- name: Install Visual Studio 2015 C++ Redistributable | |
if: runner.os == 'Windows' | |
run: | | |
$url = "${{ matrix.vc_redist2015 }}" | |
$output = "vc_redist.exe" | |
Invoke-WebRequest -Uri $url -OutFile $output | |
Start-Process $output -ArgumentList '/install', '/quiet', '/norestart' -Wait | |
Remove-Item -Path $output | |
#choco install vcredist2015 -y | |
shell: pwsh | |
- name: Install Visual Studio 2019 C++ Redistributable | |
if: runner.os == 'Windows' | |
run: | | |
$url = "${{ matrix.vc_redist2019 }}" | |
$output = "vc_redist.exe" | |
Invoke-WebRequest -Uri $url -OutFile $output | |
Start-Process $output -ArgumentList '/install', '/quiet', '/norestart' -Wait | |
Remove-Item -Path $output | |
#choco install vcredist2019 -y | |
shell: pwsh | |
- name: Install Visual Studio latest C++ Redistributable | |
if: runner.os == 'Windows' | |
run: | | |
$url = "${{ matrix.vc_redist-latest }}" | |
$output = "vc_redist.exe" | |
Invoke-WebRequest -Uri $url -OutFile $output | |
Start-Process $output -ArgumentList '/install', '/quiet', '/norestart' -Wait | |
Remove-Item -Path $output | |
shell: pwsh | |
- name: Install Holocron Toolset dependencies | |
if: ${{ success() || failure() }} | |
id: toolset_deps | |
run: | # known pyinstaller versions that work with upx compressions, not all are available on all python versions. | |
try { | |
. ./install_python_venv.ps1 -noprompt -venv_name .venv_toolset_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
Write-Host "Python executable path: $pythonExePath" | |
& $pythonExePath -m pip install --upgrade pip | |
if ("${{ runner.os }}" -eq "Windows") { | |
if ("${{ matrix.python-version }}" -eq "3.12") { | |
pip install pyinstaller --prefer-binary -U | |
} elseif ("${{ matrix.python-version }}" -eq "3.11") { | |
pip install "pyinstaller==5.13.2" --prefer-binary | |
} else { | |
pip install "pyinstaller==5.4" --prefer-binary | |
} | |
} else { | |
pip install pyinstaller -U --prefer-binary | |
} | |
#$env:QT_API = if (-not [string]::IsNullOrEmpty($env:QT_API)) { $env:QT_API } else { "{{ matrix.qt_version }}" } | |
$output = "" | |
$errorLines = @() | |
. ./compile/deps_toolset.ps1 -noprompt -venv_name .venv_toolset_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} 2>&1 | ForEach-Object { | |
Write-Output $_.ToString() | |
$output += $_.ToString() + "`n" | |
if($_ -match 'ERROR:') { | |
$errorLines += $_.ToString() | |
} | |
} | |
if ($errorLines.Count -gt 0) { | |
$errorLines | ForEach-Object { Write-Error $_ } | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=false" | |
exit 1 | |
} else { | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=true" | |
} | |
} catch { | |
Write-Host -ForegroundColor Red "$($_.InvocationInfo.PositionMessage)`n$($_.Exception.Message)" | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=false" | |
exit 1 | |
} | |
shell: pwsh | |
- name: HolocronToolset - Adjust RPATH for shared libraries in the virtual environment | |
if: ${{ (success() || failure()) && runner.os == 'Disabled_Linux' && steps.toolset_deps.outputs.success == 'true' }} | |
run: | | |
. ./install_python_venv.ps1 -noprompt -venv_name .venv_toolset_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
# Ensure patchelf is installed | |
sudo apt-get update && sudo apt-get install -y patchelf | |
# Find the virtual environment's site-packages directory | |
$venvPath = $env:VIRTUAL_ENV | |
Write-Host "Virtual environment path: $venvPath" | |
# Dynamically find the Python version directory inside the venv | |
$pythonLibPath = Get-ChildItem -Path "$venvPath/lib" | Where-Object { $_.PSIsContainer } | Select-Object -First 1 | |
$sitePackagesPath = Join-Path -Path $pythonLibPath.FullName -ChildPath "site-packages" | |
Write-Host "Site-packages path: $sitePackagesPath" | |
# Use patchelf to adjust RPATH for all shared libraries in the virtual environment | |
Get-ChildItem -Path $sitePackagesPath -Filter *.so -Recurse | ForEach-Object { | |
$libPath = $_.FullName | |
Write-Host "Patching $libPath" | |
sudo patchelf --set-rpath '$ORIGIN' $libPath | |
} | |
shell: pwsh | |
- name: Compile Holocron Toolset | |
if: ${{ (success() || failure()) && steps.toolset_deps.outputs.success == 'true' }} | |
run: | | |
$upxDir = $env:UPX_DIR | |
Write-Host "Using UPX directory at '$upxDir'" | |
$output = "" | |
. ./compile/compile_toolset.ps1 -noprompt -venv_name .venv_toolset_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} -upx_dir $upxDir 2>&1 | ForEach-Object { | |
Write-Output $_.ToString() | |
$output += $_.ToString() + "`n" | |
if($_ -match 'ERROR:') { | |
$errorLines += $_.ToString() | |
} | |
} | |
$warningCount = 0 | |
$output -split "`n" | ForEach-Object { | |
if ($_ -match 'WARNING: Library not found: could not resolve' -or | |
$_ -match 'WARNING: Cannot find ' -or | |
$_ -match 'WARNING: lib not found:' -or | |
$_ -match 'WARNING: Tcl modules directory' -or | |
$_ -match 'WARNING: Failed to upx strip') { | |
$warningCount++ | |
} | |
} | |
if ($errorLines.Count -gt 0) { | |
$errorLines | ForEach-Object { Write-Error $_ } | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=false" | |
exit 1 | |
} elseif ($warningCount -ge 3) { | |
Write-Output "Many 'library not found' warnings raised, pyinstaller was probably unsuccessful." | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=false" | |
exit 1 | |
} else { | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=true" | |
} | |
shell: pwsh | |
- name: HolocronToolset - Create Static Binary | |
if: ${{ (success() || failure()) && runner.os == 'Disabled_Linux' && steps.toolset_deps.outputs.success == 'true' }} | |
run: | | |
. ./install_python_venv.ps1 -noprompt -venv_name .venv_toolset_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
& $pythonExePath -m pip install staticx | |
staticx ./dist/HolocronToolset ./dist/HolocronToolset-static | |
# Rename the static binary for clarity and consistency | |
Write-Output "./dist/HolocronToolset-static --> ./dist/HolocronToolset" | |
Move-Item -LiteralPath ./dist/HolocronToolset-static -Destination ./dist/HolocronToolset -Force | |
shell: pwsh | |
- name: Install HoloPatcher dependencies | |
if: ${{ success() || failure() }} | |
id: holopatcher_deps | |
run: | # known pyinstaller versions that work with upx compressions, not all are available on all python versions. | |
try { | |
. ./install_python_venv.ps1 -noprompt -venv_name .venv_holopatcher_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
& $pythonExePath -m pip install --upgrade pip | |
if ("${{ runner.os }}" -eq "Windows") { | |
if ("${{ matrix.python-version }}" -eq "3.12") { | |
pip install "pyinstaller==5.13.2" --prefer-binary | |
} elseif ("${{ matrix.python-version }}" -eq "3.11") { | |
pip install "pyinstaller==5.13.2" --prefer-binary | |
} else { | |
pip install "pyinstaller==5.4" --prefer-binary | |
} | |
} else { | |
pip install pyinstaller -U --prefer-binary | |
} | |
$output = "" | |
$errorLines = @() | |
. ./compile/deps_holopatcher.ps1 -noprompt -venv_name .venv_holopatcher_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} 2>&1 | ForEach-Object { | |
Write-Output $_.ToString() | |
$output += $_.ToString() + "`n" | |
if($_ -match 'ERROR:') { | |
$errorLines += $_.ToString() | |
} | |
} | |
if ($errorLines.Count -gt 0) { | |
$errorLines | ForEach-Object { Write-Error $_ } | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=false" | |
exit 1 | |
} else { | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=true" | |
} | |
} catch { | |
Write-Host -ForegroundColor Red "$($_.InvocationInfo.PositionMessage)`n$($_.Exception.Message)" | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=false" | |
exit 1 | |
} | |
shell: pwsh | |
- name: HoloPatcher - Adjust RPATH for shared libraries in the virtual environment | |
if: ${{ (success() || failure()) && runner.os == 'Disabled_Linux' && steps.holopatcher_deps.outputs.success == 'true' }} | |
run: | | |
. ./install_python_venv.ps1 -noprompt -venv_name .venv_holopatcher_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
# Ensure patchelf is installed | |
sudo apt-get update && sudo apt-get install -y patchelf | |
# Find the virtual environment's site-packages directory | |
$venvPath = $env:VIRTUAL_ENV | |
Write-Host "Virtual environment path: $venvPath" | |
# Dynamically find the Python version directory inside the venv | |
$pythonLibPath = Get-ChildItem -Path "$venvPath/lib" | Where-Object { $_.PSIsContainer } | Select-Object -First 1 | |
$sitePackagesPath = Join-Path -Path $pythonLibPath.FullName -ChildPath "site-packages" | |
Write-Host "Site-packages path: $sitePackagesPath" | |
# Use patchelf to adjust RPATH for all shared libraries in the virtual environment | |
Get-ChildItem -Path $sitePackagesPath -Filter *.so -Recurse | ForEach-Object { | |
$libPath = $_.FullName | |
Write-Host "Patching $libPath" | |
sudo patchelf --set-rpath '$ORIGIN' $libPath | |
} | |
shell: pwsh | |
- name: Compile HoloPatcher | |
if: ${{ (success() || failure()) && steps.holopatcher_deps.outputs.success == 'true' }} | |
run: | | |
$upxDir = $env:UPX_DIR | |
Write-Host "Using UPX directory at '$upxDir'" | |
$output = "" | |
. ./compile/compile_holopatcher.ps1 -noprompt -venv_name .venv_holopatcher_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} -upx_dir $upxDir 2>&1 | ForEach-Object { | |
Write-Output $_.ToString() | |
$output += $_.ToString() + "`n" | |
if($_ -match 'ERROR:') { | |
$errorLines += $_.ToString() | |
} | |
} | |
$warningCount = 0 | |
$output -split "`n" | ForEach-Object { | |
if ($_ -match 'WARNING: Library not found: could not resolve' -or | |
$_ -match 'WARNING: Cannot find ' -or | |
$_ -match 'WARNING: lib not found:' -or | |
$_ -match 'WARNING: Tcl modules directory' -or | |
$_ -match 'WARNING: Failed to upx strip') { | |
$warningCount++ | |
} | |
} | |
if ($errorLines.Count -gt 0) { | |
$errorLines | ForEach-Object { Write-Error $_ } | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=false" | |
exit 1 | |
} elseif ($warningCount -ge 3) { | |
Write-Output "Many 'library not found' warnings raised, pyinstaller was probably unsuccessful." | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=false" | |
exit 1 | |
} else { | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=true" | |
} | |
shell: pwsh | |
- name: HoloPatcher - Create Static Binary | |
if: ${{ (success() || failure()) && runner.os == 'Disabled_Linux' && steps.holopatcher_deps.outputs.success == 'true' }} | |
run: | | |
. ./install_python_venv.ps1 -noprompt -venv_name .venv_holopatcher_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
& $pythonExePath -m pip install staticx | |
staticx ./dist/HoloPatcher ./dist/HoloPatcher-static | |
# Rename the static binary for clarity and consistency | |
Write-Output "./dist/HoloPatcher-static --> ./dist/HoloPatcher" | |
Move-Item -LiteralPath ./dist/HoloPatcher-static -Destination ./dist/HoloPatcher -Force | |
shell: pwsh | |
- name: Install BatchPatcher dependencies | |
if: ${{ success() || failure() }} | |
id: batchpatcher_deps | |
run: | # known pyinstaller versions that work with upx compressions, not all are available on all python versions. | |
try { | |
. ./install_python_venv.ps1 -noprompt -venv_name .venv_batchpatcher_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
& $pythonExePath -m pip install --upgrade pip | |
if ("${{ runner.os }}" -eq "Windows") { | |
if ("${{ matrix.python-version }}" -eq "3.12") { | |
pip install pyinstaller --prefer-binary -U | |
} elseif ("${{ matrix.python-version }}" -eq "3.11") { | |
pip install "pyinstaller==5.13.2" --prefer-binary | |
} else { | |
pip install "pyinstaller==5.4" --prefer-binary | |
} | |
} else { | |
pip install pyinstaller -U --prefer-binary | |
} | |
$output = "" | |
$errorLines = @() | |
. ./compile/deps_batchpatcher.ps1 -noprompt -venv_name .venv_batchpatcher_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} 2>&1 | ForEach-Object { | |
Write-Output $_.ToString() | |
$output += $_.ToString() + "`n" | |
if($_ -match 'ERROR:') { | |
$errorLines += $_.ToString() | |
} | |
} | |
if ($errorLines.Count -gt 0) { | |
$errorLines | ForEach-Object { Write-Error $_ } | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=false" | |
exit 1 | |
} else { | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=true" | |
} | |
} catch { | |
Write-Host -ForegroundColor Red "$($_.InvocationInfo.PositionMessage)`n$($_.Exception.Message)" | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=false" | |
exit 1 | |
} | |
shell: pwsh | |
- name: BatchPatcher - Adjust RPATH for shared libraries in the virtual environment | |
if: ${{ (success() || failure()) && runner.os == 'Disabled_Linux' && steps.batchpatcher_deps.outputs.success == 'true' }} | |
run: | | |
. ./install_python_venv.ps1 -noprompt -venv_name .venv_batchpatcher_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
# Ensure patchelf is installed | |
sudo apt-get update && sudo apt-get install -y patchelf | |
# Find the virtual environment's site-packages directory | |
$venvPath = $env:VIRTUAL_ENV | |
Write-Host "Virtual environment path: $venvPath" | |
# Dynamically find the Python version directory inside the venv | |
$pythonLibPath = Get-ChildItem -Path "$venvPath/lib" | Where-Object { $_.PSIsContainer } | Select-Object -First 1 | |
$sitePackagesPath = Join-Path -Path $pythonLibPath.FullName -ChildPath "site-packages" | |
Write-Host "Site-packages path: $sitePackagesPath" | |
# Use patchelf to adjust RPATH for all shared libraries in the virtual environment | |
Get-ChildItem -Path $sitePackagesPath -Filter *.so -Recurse | ForEach-Object { | |
$libPath = $_.FullName | |
Write-Host "Patching $libPath" | |
sudo patchelf --set-rpath '$ORIGIN' $libPath | |
} | |
shell: pwsh | |
- name: Compile BatchPatcher | |
if: ${{ (success() || failure()) && steps.batchpatcher_deps.outputs.success == 'true' }} | |
run: | | |
$upxDir = $env:UPX_DIR | |
Write-Host "Using UPX directory at '$upxDir'" | |
$output = "" | |
. ./compile/compile_batchpatcher.ps1 -noprompt -venv_name .venv_batchpatcher_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} -upx_dir $upxDir 2>&1 | ForEach-Object { | |
Write-Output $_.ToString() | |
$output += $_.ToString() + "`n" | |
if($_ -match 'ERROR:') { | |
$errorLines += $_.ToString() | |
} | |
} | |
$warningCount = 0 | |
$output -split "`n" | ForEach-Object { | |
if ($_ -match 'WARNING: Library not found: could not resolve' -or | |
$_ -match 'WARNING: Cannot find ' -or | |
$_ -match 'WARNING: lib not found:' -or | |
$_ -match 'WARNING: Tcl modules directory' -or | |
$_ -match 'WARNING: Failed to upx strip') { | |
$warningCount++ | |
} | |
} | |
if ($errorLines.Count -gt 0) { | |
$errorLines | ForEach-Object { Write-Error $_ } | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=false" | |
exit 1 | |
} elseif ($warningCount -ge 3) { | |
Write-Output "Many 'library not found' warnings raised, pyinstaller was probably unsuccessful." | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=false" | |
exit 1 | |
} else { | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=true" | |
} | |
shell: pwsh | |
- name: BatchPatcher - Create Static Binary | |
if: ${{ (success() || failure()) && runner.os == 'Disabled_Linux' && steps.batchpatcher_deps.outputs.success == 'true' }} | |
run: | | |
. ./install_python_venv.ps1 -noprompt -venv_name .venv_batchpatcher_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
& $pythonExePath -m pip install staticx | |
staticx ./dist/K_BatchPatcher ./dist/K_BatchPatcher-static | |
# Rename the static binary for clarity and consistency | |
Write-Output "./dist/K_BatchPatcher-static --> ./dist/K_BatchPatcher" | |
Move-Item -LiteralPath ./dist/K_BatchPatcher-static -Destination ./dist/K_BatchPatcher -Force | |
shell: pwsh | |
- name: Compile KotorDiff | |
if: ${{ success() || failure() }} | |
run: | | |
$upxDir = $env:UPX_DIR | |
Write-Host "Using UPX directory at '$upxDir'" | |
. ./install_python_venv.ps1 -noprompt -venv_name .venv_kotordiff_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
& $pythonExePath -m pip install --upgrade pip | |
if ("${{ runner.os }}" -eq "Windows") { | |
if ("${{ matrix.python-version }}" -eq "3.12") { | |
pip install "pyinstaller==5.13.2" --prefer-binary | |
} elseif ("${{ matrix.python-version }}" -eq "3.11") { | |
pip install "pyinstaller==5.13.2" --prefer-binary | |
} else { | |
pip install "pyinstaller==5.4" --prefer-binary | |
} | |
} else { | |
pip install pyinstaller -U --prefer-binary | |
} | |
pip install -r Tools/KotorDiff/requirements.txt --prefer-binary | |
$output = "" | |
. ./compile/compile_kotordiff.ps1 -noprompt -venv_name .venv_kotordiff_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} -upx_dir $upxDir 2>&1 | ForEach-Object { | |
Write-Output $_.ToString() | |
$output += $_.ToString() + "`n" | |
if($_ -match 'ERROR:') { | |
$errorLines += $_.ToString() | |
} | |
} | |
$warningCount = 0 | |
$output -split "`n" | ForEach-Object { | |
if ($_ -match 'WARNING: Library not found: could not resolve' -or | |
$_ -match 'WARNING: Cannot find ' -or | |
$_ -match 'WARNING: lib not found:' -or | |
$_ -match 'WARNING: Tcl modules directory' -or | |
$_ -match 'WARNING: Failed to upx strip') { | |
$warningCount++ | |
} | |
} | |
if ($errorLines.Count -gt 0) { | |
$errorLines | ForEach-Object { Write-Error $_ } | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=false" | |
exit 1 | |
} elseif ($warningCount -ge 3) { | |
Write-Output "Many 'library not found' warnings raised, pyinstaller was probably unsuccessful." | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=false" | |
exit 1 | |
} else { | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=true" | |
} | |
shell: pwsh | |
- name: KotorDiff - Create Static Binary | |
if: ${{ (success() || failure()) && runner.os == 'Linux' }} | |
run: | | |
. ./install_python_venv.ps1 -noprompt -venv_name .venv_kotordiff_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
& $pythonExePath -m pip install staticx | |
staticx ./dist/KotorDiff ./dist/KotorDiff-static | |
# Rename the static binary for clarity and consistency | |
Write-Output "./dist/KotorDiff-static --> ./dist/KotorDiff" | |
Move-Item -LiteralPath ./dist/KotorDiff-static -Destination ./dist/KotorDiff -Force | |
shell: pwsh | |
- name: Compile GUIDuplicator | |
if: ${{ success() || failure() }} | |
run: | | |
$upxDir = $env:UPX_DIR | |
Write-Host "Using UPX directory at '$upxDir'" | |
. ./install_python_venv.ps1 -noprompt -venv_name .venv_guiduplicator_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
& $pythonExePath -m pip install --upgrade pip | |
if ("${{ runner.os }}" -eq "Windows") { | |
if ("${{ matrix.python-version }}" -eq "3.12") { | |
pip install "pyinstaller==5.13.2" --prefer-binary | |
} elseif ("${{ matrix.python-version }}" -eq "3.11") { | |
pip install "pyinstaller==5.13.2" --prefer-binary | |
} else { | |
pip install "pyinstaller==5.4" --prefer-binary | |
} | |
} else { | |
pip install pyinstaller -U --prefer-binary | |
} | |
pip install -r Tools/GuiDuplicator/requirements.txt --prefer-binary | |
$output = "" | |
. ./compile/compile_gui_duplicator.ps1 -noprompt -venv_name .venv_guiduplicator_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} -upx_dir $upxDir 2>&1 | ForEach-Object { | |
Write-Output $_.ToString() | |
if($_ -match 'ERROR:') { | |
$errorLines += $_.ToString() | |
} | |
} | |
$warningCount = 0 | |
$output -split "`n" | ForEach-Object { | |
if ($_ -match 'WARNING: Library not found: could not resolve' -or | |
$_ -match 'WARNING: Cannot find ' -or | |
$_ -match 'WARNING: lib not found:' -or | |
$_ -match 'WARNING: Tcl modules directory' -or | |
$_ -match 'WARNING: Failed to upx strip') { | |
$warningCount++ | |
} | |
} | |
if ($errorLines.Count -gt 0) { | |
$errorLines | ForEach-Object { Write-Error $_ } | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=false" | |
exit 1 | |
} elseif ($warningCount -ge 3) { | |
Write-Output "Many 'library not found' warnings raised, pyinstaller was probably unsuccessful." | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=false" | |
exit 1 | |
} else { | |
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=true" | |
} | |
shell: pwsh | |
- name: GUIDuplicator - Create Static Binary | |
if: ${{ (success() || failure()) && runner.os == 'Linux' }} | |
run: | | |
. ./install_python_venv.ps1 -noprompt -venv_name .venv_guiduplicator_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
& $pythonExePath -m pip install staticx | |
staticx ./dist/GuiDuplicator ./dist/GuiDuplicator-static | |
# Rename the static binary for clarity and consistency | |
Write-Output "./dist/GuiDuplicator-static --> ./dist/GuiDuplicator" | |
Move-Item -LiteralPath ./dist/GuiDuplicator-static -Destination ./dist/GuiDuplicator -Force | |
shell: pwsh | |
- name: Upload compiled binaries attempt 1 | |
if: ${{ success() || failure() }} | |
id: upload_attempt_1 | |
uses: actions/upload-artifact@v4 | |
with: | |
name: publish_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
path: ./dist/** | |
retention-days: 90 | |
continue-on-error: true | |
- name: Upload compiled binaries attempt 2 | |
id: upload_attempt_2 | |
if: ${{ (success() || failure()) && steps.upload_attempt_1.outcome == 'failure' }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: publish_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
path: ./dist/** | |
retention-days: 90 | |
continue-on-error: true | |
- name: Upload compiled binaries attempt 3 | |
id: upload_attempt_3 | |
if: ${{ (success() || failure()) && steps.upload_attempt_2.outcome == 'failure' }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: publish_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
path: ./dist/** | |
retention-days: 90 | |
continue-on-error: true | |
- name: Upload compiled binaries attempt 4 | |
id: upload_attempt_4 | |
if: ${{ (success() || failure()) && steps.upload_attempt_3.outcome == 'failure' }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: publish_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
path: ./dist/** | |
retention-days: 90 | |
continue-on-error: true | |
- name: Upload compiled binaries attempt 5 | |
id: upload_attempt_5 | |
if: ${{ (success() || failure()) && steps.upload_attempt_4.outcome == 'failure' }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: publish_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
path: ./dist/** | |
retention-days: 90 | |
package: | |
needs: build # do not start this job until all 'build' jobs complete | |
if: ${{ success() || failure() }} | |
runs-on: ubuntu-latest | |
steps: | |
- name: Download all artifacts | |
uses: actions/download-artifact@v4 | |
with: | |
path: published_workflow_builds/ | |
pattern: publish_* | |
- name: Extract tag name | |
id: get_tag | |
run: echo "::set-output name=tag::${GITHUB_REF#refs/tags/}" | |
shell: bash | |
- name: Compress into archives | |
run: | | |
$sourceFolder = Join-Path -Path (Get-Location) -ChildPath "published_workflow_builds" | |
Set-Location $sourceFolder | |
Get-ChildItem -Path "." -Directory | ForEach-Object { | |
$folderName = $_.Name | |
$archiveName = "$folderName.zip" | |
zip -r -9 $archiveName $folderName | |
} | |
shell: pwsh | |
- uses: ncipollo/[email protected] | |
with: | |
tag: ${{ steps.get_tag.outputs.tag }} | |
prerelease: true | |
draft: true | |
artifacts: "published_workflow_builds/*.zip" | |
allowUpdates: true | |
token: ${{ secrets.GITHUB_TOKEN }} |