fix: convert preflight here-string from expandable to literal for file-based execution

The preflight script used @"..."@ (expandable here-string) with backtick-escaped
variables, which produced invalid PowerShell when written to a .ps1 file. Switch
to @'...'@ (literal here-string) with normal PowerShell syntax. Format-specific
checks (PDF/EPUB) are appended conditionally using GitHub Actions expressions.
This commit is contained in:
Vijay Janapa Reddi
2026-03-06 15:16:16 -05:00
parent 4a58fce6ea
commit e3c647e1c3

View File

@@ -459,80 +459,87 @@ jobs:
shell: pwsh
run: |
Write-Host "🧪 Running Windows toolchain preflight checks..."
$preflightScript = @"
$scriptContent = @'
$ErrorActionPreference = 'Stop'
$PSNativeCommandUseErrorActionPreference = $true
`$ErrorActionPreference = 'Stop'
`$PSNativeCommandUseErrorActionPreference = `$true
function Invoke-Check {
param(
[string]`$Name,
[scriptblock]`$Action
)
Write-Host \"▶ preflight: `$Name\"
try {
& `$Action
if (-not `$?) { throw 'Command returned non-zero status' }
Write-Host \"✅ preflight: `$Name\"
} catch {
`$errorMessage = `$_.Exception.Message
Write-Error (\"❌ preflight failed: `$Name -- {0}\" -f `$errorMessage)
throw
}
function Invoke-Check {
param(
[string]$Name,
[scriptblock]$Action
)
Write-Host ">> preflight: $Name"
try {
& $Action
if (-not $?) { throw 'Command returned non-zero status' }
Write-Host "OK preflight: $Name"
} catch {
$errorMessage = $_.Exception.Message
Write-Error ("FAIL preflight: $Name -- {0}" -f $errorMessage)
throw
}
}
Invoke-Check 'quarto on PATH' { `$resolved = Get-Command quarto -ErrorAction Stop; Write-Host (\" quarto -> {0}\" -f `$resolved.Source) }
Invoke-Check 'quarto version' { quarto --version | Select-Object -First 1 }
Invoke-Check 'pandoc available' {
`$pandocCmd = Get-Command pandoc -ErrorAction SilentlyContinue
if (`$pandocCmd) {
Write-Host (\" pandoc -> {0}\" -f `$pandocCmd.Source)
} else {
quarto pandoc --version | Select-Object -First 1 | Out-Null
Write-Host \" pandoc -> bundled via quarto\"
}
Invoke-Check 'quarto on PATH' { $resolved = Get-Command quarto -ErrorAction Stop; Write-Host (" quarto -> {0}" -f $resolved.Source) }
Invoke-Check 'quarto version' { quarto --version | Select-Object -First 1 }
Invoke-Check 'pandoc available' {
$pandocCmd = Get-Command pandoc -ErrorAction SilentlyContinue
if ($pandocCmd) {
Write-Host (" pandoc -> {0}" -f $pandocCmd.Source)
} else {
quarto pandoc --version | Select-Object -First 1 | Out-Null
Write-Host " pandoc -> bundled via quarto"
}
Invoke-Check 'pandoc version' {
`$pandocCmd = Get-Command pandoc -ErrorAction SilentlyContinue
if (`$pandocCmd) {
pandoc --version | Select-Object -First 1
} else {
quarto pandoc --version | Select-Object -First 1
}
}
Invoke-Check 'pandoc version' {
$pandocCmd = Get-Command pandoc -ErrorAction SilentlyContinue
if ($pandocCmd) {
pandoc --version | Select-Object -First 1
} else {
quarto pandoc --version | Select-Object -First 1
}
Invoke-Check 'python on PATH' { `$resolved = Get-Command python -ErrorAction Stop; Write-Host (\" python -> {0}\" -f `$resolved.Source) }
Invoke-Check 'python version' { python --version }
Invoke-Check 'python3 on PATH' { `$resolved = Get-Command python3 -ErrorAction Stop; Write-Host (\" python3 -> {0}\" -f `$resolved.Source) }
Invoke-Check 'python3 version' { python3 --version }
Invoke-Check 'mlsysim import' { python -c 'import mlsysim,sys; print(\"mlsysim:\", mlsysim.__file__); print(\"python:\", sys.executable)' }
Invoke-Check 'Rscript on PATH' { `$resolved = Get-Command Rscript -ErrorAction Stop; Write-Host (\" Rscript -> {0}\" -f `$resolved.Source) }
Invoke-Check 'Rscript version' { Rscript --version | Select-Object -First 1 }
Invoke-Check 'inkscape on PATH' { `$resolved = Get-Command inkscape -ErrorAction Stop; Write-Host (\" inkscape -> {0}\" -f `$resolved.Source) }
Invoke-Check 'inkscape version' { inkscape --version | Select-Object -First 1 }
}
Invoke-Check 'python on PATH' { $resolved = Get-Command python -ErrorAction Stop; Write-Host (" python -> {0}" -f $resolved.Source) }
Invoke-Check 'python version' { python --version }
Invoke-Check 'python3 on PATH' { $resolved = Get-Command python3 -ErrorAction Stop; Write-Host (" python3 -> {0}" -f $resolved.Source) }
Invoke-Check 'python3 version' { python3 --version }
Invoke-Check 'mlsysim import' { python -c "import mlsysim,sys; print('mlsysim:', mlsysim.__file__); print('python:', sys.executable)" }
Invoke-Check 'Rscript on PATH' { $resolved = Get-Command Rscript -ErrorAction Stop; Write-Host (" Rscript -> {0}" -f $resolved.Source) }
Invoke-Check 'Rscript version' { Rscript --version | Select-Object -First 1 }
Invoke-Check 'inkscape on PATH' { $resolved = Get-Command inkscape -ErrorAction Stop; Write-Host (" inkscape -> {0}" -f $resolved.Source) }
Invoke-Check 'inkscape version' { inkscape --version | Select-Object -First 1 }
'@
if ('${{ matrix.format_name }}' -eq 'PDF') {
Invoke-Check 'lualatex on PATH' { `$resolved = Get-Command lualatex -ErrorAction Stop; Write-Host (\" lualatex -> {0}\" -f `$resolved.Source) }
Invoke-Check 'lualatex version' { lualatex --version | Select-Object -First 1 }
Invoke-Check 'ghostscript on PATH' {
`$gsCmd = Get-Command gs -ErrorAction SilentlyContinue
if (-not `$gsCmd) { `$gsCmd = Get-Command gswin64c -ErrorAction SilentlyContinue }
if (-not `$gsCmd) { throw 'Ghostscript not found (expected gs or gswin64c)' }
Write-Host (\" ghostscript -> {0}\" -f `$gsCmd.Source)
}
Invoke-Check 'ghostscript version' {
`$gsCmd = Get-Command gs -ErrorAction SilentlyContinue
if (-not `$gsCmd) { `$gsCmd = Get-Command gswin64c -ErrorAction SilentlyContinue }
& `$gsCmd.Source --version
}
}
# Add format-specific checks (GitHub Actions expands matrix vars before PowerShell sees this)
$formatChecks = ""
if ('${{ matrix.format_name }}' -eq 'PDF') {
$formatChecks = @'
if ('${{ matrix.format_name }}' -eq 'EPUB') {
Invoke-Check 'Pillow import' { python -c 'import PIL; print(\"Pillow:\", PIL.__version__)' }
}
"@
Invoke-Check 'lualatex on PATH' { $resolved = Get-Command lualatex -ErrorAction Stop; Write-Host (" lualatex -> {0}" -f $resolved.Source) }
Invoke-Check 'lualatex version' { lualatex --version | Select-Object -First 1 }
Invoke-Check 'ghostscript on PATH' {
$gsCmd = Get-Command gs -ErrorAction SilentlyContinue
if (-not $gsCmd) { $gsCmd = Get-Command gswin64c -ErrorAction SilentlyContinue }
if (-not $gsCmd) { throw 'Ghostscript not found (expected gs or gswin64c)' }
Write-Host (" ghostscript -> {0}" -f $gsCmd.Source)
}
Invoke-Check 'ghostscript version' {
$gsCmd = Get-Command gs -ErrorAction SilentlyContinue
if (-not $gsCmd) { $gsCmd = Get-Command gswin64c -ErrorAction SilentlyContinue }
& $gsCmd.Source --version
}
'@
}
if ('${{ matrix.format_name }}' -eq 'EPUB') {
$formatChecks = @'
Invoke-Check 'Pillow import' { python -c "import PIL; print('Pillow:', PIL.__version__)" }
'@
}
$fullScript = $scriptContent + $formatChecks
$scriptPath = Join-Path $PWD.Path 'preflight-script.ps1'
Set-Content -Path $scriptPath -Value $preflightScript -Encoding UTF8
Set-Content -Path $scriptPath -Value $fullScript -Encoding UTF8
docker run --rm `
-e PYTHONPATH=C:\workspace `