11# .github/workflows/windows-build.yml
2- # GitHub Actions workflow to build a standalone Windows executable and create a release.
3- # This version correctly downloads and prepares a full, portable Python runtime.
2+ # This workflow correctly downloads a full, portable Python runtime, prepares it,
3+ # and bundles it with the Nuitka-compiled application for a fully standalone release.
4+ # It includes exhaustive verification steps to prevent incorrect builds.
45
56name : Build and Release Windows App
67
@@ -27,60 +28,74 @@ jobs:
2728 with :
2829 python-version : ' 3.11'
2930
30- - name : Cache Pip and Nuitka
31- uses : actions/cache@v4
32- with :
33- path : |
34- ~\.cache\pip
35- ~\AppData\Local\Nuitka\Nuitka\Cache
36- key : ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
37- restore-keys : |
38- ${{ runner.os }}-pip-
39-
40- - name : Install dependencies
41- run : pip install -r requirements.txt
42-
43- - name : Download zstd.exe decompressor
44- shell : pwsh
45- run : |
46- Invoke-WebRequest -Uri "https://github.com/facebook/zstd/releases/download/v1.5.5/zstd-v1.5.5-win64.zip" -OutFile "zstd.zip"
47- Expand-Archive -Path "zstd.zip" -DestinationPath "zstd"
48- $env:PATH += ";${PWD}/zstd"
49-
50- - name : Download Python standalone runtime
31+ - name : Prepare Portable Python Runtime
5132 shell : pwsh
5233 run : |
34+ # 1. Download the correct 'install_only' standalone Python distribution.
5335 $pythonVersion = "3.11.13"
5436 $releaseTag = "20250808"
55- $fileName = "cpython-$($pythonVersion)+$($releaseTag)-x86_64-pc-windows-msvc-pgo-full .tar.zst "
37+ $fileName = "cpython-$($pythonVersion)+$($releaseTag)-x86_64-pc-windows-msvc-install_only .tar.gz "
5638 $url = "https://github.com/astral-sh/python-build-standalone/releases/download/$releaseTag/$fileName"
39+
40+ Write-Host "Downloading Python runtime from $url"
41+ Invoke-WebRequest -Uri $url -OutFile "python-standalone.tar.gz"
5742
58- Invoke-WebRequest -Uri $url -OutFile "python-standalone.tar.zst"
59-
60- - name : Decompress Python runtime
61- shell : pwsh
62- run : |
63- # The zstd executable is in a nested directory after extraction.
64- # Use the correct path to the executable.
65- .\zstd\zstd-v1.5.5-win64\zstd.exe -d python-standalone.tar.zst -o python-standalone.tar
66- tar -xf python-standalone.tar
67-
68- - name : Move to python_runtime folder
69- shell : pwsh
70- run : |
43+ # 2. Decompress the archive.
44+ Write-Host "Decompressing Python runtime..."
45+ tar -xzf python-standalone.tar.gz
46+
47+ # 3. Move the contents to the 'python_runtime' directory.
7148 New-Item -ItemType Directory -Force -Path python_runtime
72- Move-Item -Path "python\install\ *" -Destination "python_runtime"
49+ Move-Item -Path "python\*" -Destination "python_runtime"
7350 Remove-Item "python" -Recurse -Force
51+
52+ # 4. Download the official pip bootstrap script.
53+ Write-Host "Downloading get-pip.py..."
54+ Invoke-WebRequest -Uri "https://bootstrap.pypa.io/get-pip.py" -OutFile "python_runtime\get-pip.py"
55+
56+ # 5. Run the bootstrap script to install pip.
57+ Write-Host "Installing pip into the portable runtime..."
58+ .\python_runtime\python.exe .\python_runtime\get-pip.py
59+
60+ # 6. Clean up.
61+ Remove-Item "python_runtime\get-pip.py"
62+ Write-Host "Python runtime prepared."
7463
75- - name : Verify python_runtime
64+ - name : Insane Sanity Check of Python Runtime
7665 shell : pwsh
7766 run : |
78- if (-not (Test-Path "python_runtime\python.exe")) { exit 1 }
79-
80- - name : Upgrade pip in portable runtime
81- shell : pwsh
82- run : |
83- .\python_runtime\python.exe -m pip install --upgrade pip
67+ Write-Host "--- RUNNING EXTREME VERIFICATION ---"
68+ $runtimePath = "python_runtime"
69+
70+ # Check 1: python.exe must exist.
71+ $pythonExePath = Join-Path $runtimePath "python.exe"
72+ if (-not (Test-Path $pythonExePath)) {
73+ Write-Host "CRITICAL FAILURE: '$($pythonExePath)' does not exist. The wrong package was downloaded or extracted."
74+ exit 1
75+ }
76+ Write-Host "[PASS] python.exe found."
77+
78+ # Check 2: pip.exe must exist.
79+ $pipExePath = Join-Path $runtimePath "Scripts\pip.exe"
80+ if (-not (Test-Path $pipExePath)) {
81+ Write-Host "CRITICAL FAILURE: '$($pipExePath)' does not exist. Pip bootstrapping failed."
82+ exit 1
83+ }
84+ Write-Host "[PASS] pip.exe found."
85+
86+ # Check 3: There must NOT be any .pdb files.
87+ $pdbFiles = Get-ChildItem -Path $runtimePath -Recurse -Filter "*.pdb"
88+ if ($pdbFiles) {
89+ Write-Host "CRITICAL FAILURE: Found .pdb files in the runtime directory. This indicates the wrong package type (a debug or dev package) was downloaded."
90+ $pdbFiles | ForEach-Object { Write-Host " - $($_.FullName)" }
91+ exit 1
92+ }
93+ Write-Host "[PASS] No .pdb files found."
94+
95+ Write-Host "--- VERIFICATION SUCCEEDED ---"
96+
97+ - name : Install dependencies for Nuitka build
98+ run : pip install -r requirements.txt
8499
85100 - name : Build app with Nuitka
86101 run : |
0 commit comments