From 0d0786e2224bf9ed8a7bad4f75ae932f2b3a616a Mon Sep 17 00:00:00 2001 From: MarcoPad Dev Date: Fri, 17 Jul 2026 20:44:47 -0700 Subject: [PATCH] ci: provision Python via nuget (idempotent, no registry side effects) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The per-user MSI installer is stateful across runs on a persistent VM: once a version is registered, a later /quiet install no-ops and never lands at the new TargetDir, so python.exe went missing. Switch to a standalone CPython from nuget cached under LOCALAPPDATA — no registry/PATH changes, idempotent, reused across runs. A pre-existing Python 3.11 on PATH is still honoured. Co-Authored-By: Claude Opus 4.8 (1M context) --- .gitea/workflows/build-windows.yml | 40 +++++++++++++++--------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/.gitea/workflows/build-windows.yml b/.gitea/workflows/build-windows.yml index 2ec2589..c80d0ef 100644 --- a/.gitea/workflows/build-windows.yml +++ b/.gitea/workflows/build-windows.yml @@ -45,16 +45,17 @@ jobs: run: | $ErrorActionPreference = 'Stop' [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 - $python = $null - # 1) Existing "py -3.11" launcher - try { - $exe = & py -3.11 -c "import sys; print(sys.executable)" 2>$null - if ($LASTEXITCODE -eq 0 -and $exe) { $python = $exe.Trim() } - } catch {} + # Persistent, side-effect-free Python for this builder. We use a + # standalone CPython from nuget (no registry/PATH changes, idempotent) + # cached under LOCALAPPDATA so subsequent runs reuse it. A pre-existing + # Python 3.11 on PATH is honoured if present. + $pyVersion = "3.11.9" + $root = Join-Path $env:LOCALAPPDATA "MacroPadBuild" + $python = Join-Path $root "python.$pyVersion\tools\python.exe" - # 2) A python on PATH that is 3.11.x - if (-not $python) { + if (-not (Test-Path $python)) { + # Honour an existing 3.11 on PATH (e.g. if the VM is pre-provisioned). try { $v = & python --version 2>&1 if ($LASTEXITCODE -eq 0 -and "$v" -match '3\.11') { @@ -63,21 +64,20 @@ jobs: } catch {} } - # 3) Install per-user, silent (no elevation, cannot prompt) - if (-not $python) { - Write-Host "Python 3.11 not found - installing per-user..." - $tmp = if ($env:RUNNER_TEMP) { $env:RUNNER_TEMP } else { $env:TEMP } - $installer = Join-Path $tmp "python-3.11.9-amd64.exe" - Invoke-WebRequest -UseBasicParsing -Uri "https://www.python.org/ftp/python/3.11.9/python-3.11.9-amd64.exe" -OutFile $installer - $dir = Join-Path $tmp "Python311" - $proc = Start-Process -FilePath $installer -Wait -PassThru -NoNewWindow -ArgumentList @( - "/quiet","InstallAllUsers=0","PrependPath=0","Include_launcher=0","Include_test=0","TargetDir=$dir" - ) - if ($proc.ExitCode -ne 0) { throw "Python installer exited with $($proc.ExitCode)" } - $python = Join-Path $dir "python.exe" + if (-not (Test-Path $python)) { + Write-Host "Provisioning standalone Python $pyVersion via nuget..." + New-Item -ItemType Directory -Force -Path $root | Out-Null + $nuget = Join-Path $root "nuget.exe" + if (-not (Test-Path $nuget)) { + Invoke-WebRequest -UseBasicParsing -Uri "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" -OutFile $nuget + } + & $nuget install python -Version $pyVersion -OutputDirectory $root -Source "https://api.nuget.org/v3/index.json" -NonInteractive + if ($LASTEXITCODE -ne 0) { throw "nuget install python exited with $LASTEXITCODE" } + $python = Join-Path $root "python.$pyVersion\tools\python.exe" } if (-not (Test-Path $python)) { throw "Python not found at '$python'" } + & $python -m ensurepip --upgrade 2>$null | Out-Null & $python --version # Write to GITHUB_ENV without a BOM (ascii) so the value parses cleanly. Add-Content -Path $env:GITHUB_ENV -Value "PYTHON=$python" -Encoding ascii