Skip to content

HoloPatcher Release #14

HoloPatcher Release

HoloPatcher Release #14

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:
- '*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: |
$singleLineJson = '${{ env.OS_RUNNERS_JSON }}' -replace "`r", "" -replace "`n", ""
echo "os<<EOF" >> $env:GITHUB_OUTPUT
echo $singleLineJson >> $env:GITHUB_OUTPUT
echo "EOF" >> $env:GITHUB_OUTPUT
$singleLineJson = '${{ env.PYTHON_VERSIONS_JSON }}' -replace "`r", "" -replace "`n", ""
echo "python-version<<EOF" >> $env:GITHUB_OUTPUT
echo $singleLineJson >> $env:GITHUB_OUTPUT
echo "EOF" >> $env:GITHUB_OUTPUT
$singleLineJson = '${{ env.ARCHITECTURES_JSON }}' -replace "`r", "" -replace "`n", ""
echo "architecture<<EOF" >> $env:GITHUB_OUTPUT
echo $singleLineJson >> $env:GITHUB_OUTPUT
echo "EOF" >> $env:GITHUB_OUTPUT
$singleLineJson = '${{ env.INTERPRETERS_JSON }}' -replace "`r", "" -replace "`n", ""
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 pypy ${{ matrix.python-version }}
if: ${{ matrix.python_pypy == 'pypy' }}
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
architecture: ${{ matrix.architecture }}
- 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: 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 == 'Windows'
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 HoloPatcher dependencies
if: ${{ success() || failure() }}
env:
MATRIX_ARCH: ${{ matrix.architecture }}
id: holopatcher_deps
run: | # known pyinstaller versions that work with upx compressions, not all are available on all python versions.
try {
$env:LD_LIBRARY_PATH = "/usr/local/lib:$env:LD_LIBRARY_PATH"
. ./install_python_venv.ps1 -noprompt -venv_name .venv_holopatcher_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} -force_python_version ${{ matrix.python-version }}
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
}
$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 "Detailed Error Report:"
Write-Host -ForegroundColor Red "Message: $($_.Exception.Message)"
# Attempt to provide a more detailed location of the error
if ($_.InvocationInfo -and $_.InvocationInfo.MyCommand) {
Write-Host -ForegroundColor Red "Command Name: $($_.InvocationInfo.MyCommand.Name)"
Write-Host -ForegroundColor Red "Script Name: $($_.InvocationInfo.ScriptName)"
Write-Host -ForegroundColor Red "Line Number: $($_.InvocationInfo.ScriptLineNumber)"
Write-Host -ForegroundColor Red "Line: $($_.InvocationInfo.Line)"
} else {
Write-Host -ForegroundColor Red "No invocation information available."
}
# Extract and display the script stack trace if available
if ($_.ScriptStackTrace) {
Write-Host -ForegroundColor Red "Script Stack Trace:"
Write-Host -ForegroundColor Red $_.ScriptStackTrace
} else {
Write-Host -ForegroundColor Red "No script stack trace available."
}
# Log the error to GitHub Actions output or another logging mechanism
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: |
$env:LD_LIBRARY_PATH = "/usr/local/lib:$env:LD_LIBRARY_PATH"
$upxDir = $env:UPX_DIR
Write-Host "Using UPX directory at '$upxDir'"
$output = ""
$env:PYTHONOPTIMIZE = "1"
. ./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 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: Upload HoloPatcher binaries attempt 1
if: ${{ success() || failure() }}
id: upload_attempt_1
uses: actions/upload-artifact@v4
with:
name: HoloPatcher_${{ runner.os }}_${{ matrix.architecture }}
path: ./dist/**
retention-days: 90
continue-on-error: true
- name: Upload HoloPatcher binaries attempt 2
id: upload_attempt_2
if: ${{ (success() || failure()) && steps.upload_attempt_1.outcome == 'failure' }}
uses: actions/upload-artifact@v4
with:
name: HoloPatcher_${{ runner.os }}_${{ matrix.architecture }}
path: ./dist/**
retention-days: 90
continue-on-error: true
- name: Upload HoloPatcher binaries attempt 3
id: upload_attempt_3
if: ${{ (success() || failure()) && steps.upload_attempt_2.outcome == 'failure' }}
uses: actions/upload-artifact@v4
with:
name: HoloPatcher_${{ runner.os }}_${{ matrix.architecture }}
path: ./dist/**
retention-days: 90
continue-on-error: true
- name: Upload HoloPatcher binaries attempt 4
id: upload_attempt_4
if: ${{ (success() || failure()) && steps.upload_attempt_3.outcome == 'failure' }}
uses: actions/upload-artifact@v4
with:
name: HoloPatcher_${{ runner.os }}_${{ matrix.architecture }}
path: ./dist/**
retention-days: 90
continue-on-error: true
- name: Upload HoloPatcher binaries attempt 5
id: upload_attempt_5
if: ${{ (success() || failure()) && steps.upload_attempt_4.outcome == 'failure' }}
uses: actions/upload-artifact@v4
with:
name: HoloPatcher_${{ runner.os }}_${{ 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:
- uses: actions/checkout@v4
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: published_workflow_builds/
pattern: HoloPatcher_*
- name: Compress into archives
run: |
$originalDir = Get-Location
$sourceFolder = Join-Path -Path $originalDir -ChildPath "published_workflow_builds"
Set-Location $sourceFolder
Get-ChildItem -Path "." -Directory | ForEach-Object {
$folderName = $_.Name
$archiveName = "$folderName.zip"
zip -r -9 $archiveName $folderName
}
Set-Location $originalDir
shell: pwsh
- name: Determine Release Tag Ending with 'patcher'
id: get_tag
run: |
if ($env:GITHUB_EVENT_NAME -eq "workflow_dispatch") {
git fetch --depth=1 origin '+refs/tags/*:refs/tags/*'
# Get all tags ending with 'patcher', then pick the most recent one based on how they're listed
$tag = git tag --list '*patcher*' | Select-Object -Last 1
} else {
git fetch --depth=1 origin '+refs/tags/*:refs/tags/*'
# Get all tags ending with 'patcher', then pick the most recent one based on how they're listed
$tag = git tag --list '*patcher*' | Select-Object -Last 1
}
if (-not $tag) {
echo "No matching tag found ending with 'patcher'."
git tag --list
exit 1
}
echo "tag=$tag" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
shell: pwsh
- name: Release
uses: softprops/action-gh-release@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
tag_name: ${{ steps.get_tag.outputs.tag }}
files: "published_workflow_builds/*.zip"
fail_on_unmatched_files: true
target_commitish: ${{ github.event_name == 'workflow_dispatch' && github.ref_name || github.head_ref }}
- name: Determine Release ID for fallback upload.
if: ${{ failure() }}
id: get_release_id
run: |
# Filter tags ending with 'patcher', sort them by date, and pick the most recent one
$uri = "https://api.github.com/repos/${{ github.repository }}/releases/tags/${{ steps.get_tag.outputs.tag }}"
$headers = @{Authorization = "token ${{ secrets.GITHUB_TOKEN }}"}
$response = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers
$releaseId = $response.id
echo "RELEASE_ID=$releaseId" | Out-File -FilePath $env:GITHUB_ENV -Append
shell: pwsh
- name: Upload Archive to Release
if: ${{ failure() }}
run: |
try {
Add-Type -TypeDefinition @"
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
public class GitHubUploader {
public static async Task UploadFileAsync(string filePath, string uploadUrl, string token) {
using (var client = new HttpClient()) {
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
using (var content = new MultipartFormDataContent()) {
var fileContent = new ByteArrayContent(System.IO.File.ReadAllBytes(filePath));
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");
content.Add(fileContent, "file", System.IO.Path.GetFileName(filePath));
var response = await client.PostAsync(uploadUrl, content);
if (!response.IsSuccessStatusCode) {
throw new ApplicationException(await response.Content.ReadAsStringAsync());
}
}
}
}
}
"@
$archivePath = "published_workflow_builds/*.zip"
$releaseId = $env:RELEASE_ID
$token = "${{ secrets.GITHUB_TOKEN }}""
Get-ChildItem -Path $archivePath | ForEach-Object {
$filePath = $_.FullName
$fileName = $_.Name
$uploadUrl = "https://uploads.github.com/repos/$env:GITHUB_REPOSITORY/releases/$releaseId/assets?name=$fileName&label=$fileName"
try {
Write-Host "Attempting to upload $fileName"
[GitHubUploader]::UploadFileAsync($filePath, $uploadUrl, $token).GetAwaiter().GetResult()
Write-Host "Upload successful: $fileName"
} catch {
Write-Host "Failed to upload $fileName : $($_.Exception.Message)"
Write-Host -ForegroundColor Red "Detailed Error Report:"
Write-Host -ForegroundColor Red "Message: $($_.Exception.Message)"
# Attempt to provide a more detailed location of the error
if ($_.InvocationInfo -and $_.InvocationInfo.MyCommand) {
Write-Host -ForegroundColor Red "Command Name: $($_.InvocationInfo.MyCommand.Name)"
Write-Host -ForegroundColor Red "Script Name: $($_.InvocationInfo.ScriptName)"
Write-Host -ForegroundColor Red "Line Number: $($_.InvocationInfo.ScriptLineNumber)"
Write-Host -ForegroundColor Red "Line: $($_.InvocationInfo.Line)"
} else {
Write-Host -ForegroundColor Red "No invocation information available."
}
# Extract and display the script stack trace if available
if ($_.ScriptStackTrace) {
Write-Host -ForegroundColor Red "Script Stack Trace:"
Write-Host -ForegroundColor Red $_.ScriptStackTrace
} else {
Write-Host -ForegroundColor Red "No script stack trace available."
}
}
}
} catch {
Write-Host -ForegroundColor Red "Detailed Error Report:"
Write-Host -ForegroundColor Red "Message: $($_.Exception.Message)"
# Attempt to provide a more detailed location of the error
if ($_.InvocationInfo -and $_.InvocationInfo.MyCommand) {
Write-Host -ForegroundColor Red "Command Name: $($_.InvocationInfo.MyCommand.Name)"
Write-Host -ForegroundColor Red "Script Name: $($_.InvocationInfo.ScriptName)"
Write-Host -ForegroundColor Red "Line Number: $($_.InvocationInfo.ScriptLineNumber)"
Write-Host -ForegroundColor Red "Line: $($_.InvocationInfo.Line)"
} else {
Write-Host -ForegroundColor Red "No invocation information available."
}
# Extract and display the script stack trace if available
if ($_.ScriptStackTrace) {
Write-Host -ForegroundColor Red "Script Stack Trace:"
Write-Host -ForegroundColor Red $_.ScriptStackTrace
} else {
Write-Host -ForegroundColor Red "No script stack trace available."
}
Add-Content -Path $env:GITHUB_OUTPUT -Value "success=false"
exit 1
}
shell: pwsh