create release workflow for gui converter #1
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: GuiConverter 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: | |
- '*guiconverter*' | |
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' | |
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 -LiteralPath "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 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 GuiConverter dependencies | |
if: ${{ success() || failure() }} | |
env: | |
MATRIX_ARCH: ${{ matrix.architecture }} | |
id: guiconverter_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_guiconverter_${{ 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 | |
} | |
pip install comtypes | |
} else { | |
pip install pyinstaller -U --prefer-binary | |
} | |
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: GuiConverter - Adjust RPATH for shared libraries in the virtual environment | |
if: ${{ (success() || failure()) && runner.os == 'Disabled_Linux' && steps.guiconverter_deps.outputs.success == 'true' }} | |
run: | | |
. ./install_python_venv.ps1 -noprompt -venv_name .venv_guiconverter_${{ 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 -LiteralPath "$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 -LiteralPath $sitePackagesPath -Filter *.so -Recurse | ForEach-Object { | |
$libPath = $_.FullName | |
Write-Host "Patching $libPath" | |
sudo patchelf --set-rpath '$ORIGIN' $libPath | |
} | |
shell: pwsh | |
- name: Compile GuiConverter | |
if: ${{ (success() || failure()) && steps.guiconverter_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_guiconverter.ps1 -noprompt -venv_name .venv_guiconverter_${{ 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: GuiConverter - Create Static Binary | |
if: ${{ (success() || failure()) && runner.os == 'Disabled_Linux' && steps.guiconverter_deps.outputs.success == 'true' }} | |
run: | | |
. ./install_python_venv.ps1 -noprompt -venv_name .venv_guiconverter_${{ matrix.os }}_${{ matrix.python_pypy }}_${{ matrix.python-version }}_${{ matrix.architecture }} | |
& $pythonExePath -m pip install staticx | |
staticx ./dist/GuiConverter ./dist/GuiConverter-static | |
# Rename the static binary for clarity and consistency | |
Write-Output "./dist/GuiConverter-static --> ./dist/GuiConverter" | |
Move-Item -LiteralPath ./dist/GuiConverter-static -Destination ./dist/GuiConverter -Force | |
shell: pwsh | |
- name: Upload GuiConverter binaries attempt 1 | |
if: ${{ success() || failure() }} | |
id: upload_attempt_1 | |
uses: actions/upload-artifact@v4 | |
with: | |
name: GuiConverter_${{ runner.os }}_${{ matrix.architecture }} | |
path: ./dist/** | |
retention-days: 90 | |
continue-on-error: true | |
- name: Upload GuiConverter binaries attempt 2 | |
id: upload_attempt_2 | |
if: ${{ (success() || failure()) && steps.upload_attempt_1.outcome == 'failure' }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: GuiConverter_${{ runner.os }}_${{ matrix.architecture }} | |
path: ./dist/** | |
retention-days: 90 | |
continue-on-error: true | |
- name: Upload GuiConverter binaries attempt 3 | |
id: upload_attempt_3 | |
if: ${{ (success() || failure()) && steps.upload_attempt_2.outcome == 'failure' }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: GuiConverter_${{ runner.os }}_${{ matrix.architecture }} | |
path: ./dist/** | |
retention-days: 90 | |
continue-on-error: true | |
- name: Upload GuiConverter binaries attempt 4 | |
id: upload_attempt_4 | |
if: ${{ (success() || failure()) && steps.upload_attempt_3.outcome == 'failure' }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: GuiConverter_${{ runner.os }}_${{ matrix.architecture }} | |
path: ./dist/** | |
retention-days: 90 | |
continue-on-error: true | |
- name: Upload GuiConverter binaries attempt 5 | |
id: upload_attempt_5 | |
if: ${{ (success() || failure()) && steps.upload_attempt_4.outcome == 'failure' }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: GuiConverter_${{ 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: GuiConverter_* | |
- name: Compress into archives | |
run: | | |
$originalDir = Get-Location | |
$sourceFolder = Join-Path -Path $originalDir -ChildPath "published_workflow_builds" | |
Set-Location $sourceFolder | |
Get-ChildItem -LiteralPath "." -Directory | ForEach-Object { | |
$folderName = $_.Name | |
$archiveName = "$folderName.zip" | |
zip -r -9 $archiveName $folderName | |
} | |
Set-Location $originalDir | |
shell: pwsh | |
- name: Determine Release Tag Ending with 'guiconverter' | |
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 'guiconverter', then pick the most recent one based on how they're listed | |
$tag = git tag --list '*guiconverter*' | Select-Object -Last 1 | |
} else { | |
git fetch --depth=1 origin '+refs/tags/*:refs/tags/*' | |
# Get all tags ending with 'guiconverter', then pick the most recent one based on how they're listed | |
$tag = git tag --list '*guiconverter*' | Select-Object -Last 1 | |
} | |
if (-not $tag) { | |
echo "No matching tag found ending with 'guiconverter'." | |
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 'guiconverter', 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 -LiteralPath $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 |