Repository navigation
fix(launcher): capture startup crashes to launcher.log + dump in CI #3
Workflow file for this run
This file contains hidden or 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
| # ============================================================================= | |
| # Build panelagent.exe on tag push and attach it to a GitHub Release. | |
| # ============================================================================= | |
| # Trigger: push a tag matching v* (e.g. v1.0.0). The workflow builds the | |
| # static frontend, bundles it with the Python backend via PyInstaller on a | |
| # Windows runner, and uploads panelagent.exe to a Release for that tag. | |
| # ============================================================================= | |
| name: Build Windows exe | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| workflow_dispatch: # allow manual runs from the Actions tab | |
| permissions: | |
| contents: write # required to create the release and upload the asset | |
| jobs: | |
| build: | |
| runs-on: windows-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.13" | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "npm" | |
| cache-dependency-path: frontend/package-lock.json | |
| - name: Install backend deps + PyInstaller | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -r backend/requirements.txt | |
| pip install pyinstaller | |
| - name: Build static frontend | |
| env: | |
| NEXT_PUBLIC_API_URL: "http://127.0.0.1:8000" | |
| run: | | |
| cd frontend | |
| npm install | |
| npm run build | |
| if (-Not (Test-Path "out/index.html")) { throw "next build did not produce out/index.html" } | |
| shell: pwsh | |
| - name: Build exe | |
| run: | | |
| python -m PyInstaller panelagent.spec --noconfirm --clean | |
| if (-Not (Test-Path "dist/panelagent.exe")) { throw "PyInstaller did not produce dist/panelagent.exe" } | |
| shell: pwsh | |
| - name: Smoke test (start exe + poll health endpoint + dump log + kill) | |
| continue-on-error: true # don't block the release upload if the CI env can't reach localhost | |
| run: | | |
| Write-Host "Launching dist\panelagent.exe..." | |
| $p = Start-Process -FilePath "dist\panelagent.exe" -PassThru | |
| # PyInstaller one-file cold start: unpack bundle + import pandas/scipy | |
| # can take 30-60s on first run. Poll up to 120s. | |
| $ok = $false | |
| for ($i = 0; $i -lt 24; $i++) { | |
| Start-Sleep -Seconds 5 | |
| try { | |
| $resp = Invoke-WebRequest -Uri "http://127.0.0.1:8000/api/v1/health" -UseBasicParsing -TimeoutSec 5 | |
| if ($resp.StatusCode -eq 200) { | |
| Write-Host "Health check OK after $($i*5)s: $($resp.Content)" | |
| $ok = $true | |
| break | |
| } | |
| } catch { | |
| Write-Host "Waiting... ($($_.Exception.Message.Split([Environment]::NewLine)[0]))" | |
| } | |
| } | |
| Stop-Process -Id $p.Id -Force -ErrorAction SilentlyContinue | |
| Start-Sleep -Seconds 2 | |
| # If it failed, dump the launcher log so the cause is visible in CI. | |
| $logPath = "$env:USERPROFILE\.panelagent\launcher.log" | |
| Write-Host "Launcher log: $logPath" | |
| if (Test-Path $logPath) { | |
| Write-Host "===== launcher.log =====" | |
| Get-Content $logPath | ForEach-Object { Write-Host $_ } | |
| Write-Host "===== end launcher.log =====" | |
| } else { | |
| Write-Host "No launcher.log found (exe may have crashed before logging was set up)." | |
| } | |
| if (-not $ok) { | |
| Write-Host "::warning::Smoke test could not reach health endpoint within 120s. See launcher.log above. The exe will still be uploaded." | |
| } | |
| shell: pwsh | |
| - name: Get version from tag | |
| if: startsWith(github.ref, 'refs/tags/') | |
| id: version | |
| run: echo "tag=${GITHUB_REF#refs/tags/}" >> $env:GITHUB_OUTPUT | |
| shell: pwsh | |
| - name: Create / update Release and upload asset | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ steps.version.outputs.tag || github.ref_name }} | |
| name: PanelAgent ${{ steps.version.outputs.tag || 'dev' }} | |
| files: dist/panelagent.exe | |
| generate_release_notes: true | |
| fail_on_unmatched_files: true |