mirror of
https://github.com/hansjone/netx.git
synced 2026-10-15 03:40:51 +08:00
Make local Windows release builds work without GitHub.
- Prefer Python 3.12 (py -3.12 / Python312) even when another version is first on PATH, matching the CI pin. - Skip npm ci when node_modules already matches package-lock.json: npm ci wipes node_modules first and a running Vite dev server leaves it half-deleted. - pip --no-warn-script-location: its PATH check realpath()s every entry and aborts on a broken reparse point. - README: local release / Forgejo / offline steps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
1b2b8cef2b
commit
a82e546918
2 changed files with 38 additions and 5 deletions
|
|
@ -50,6 +50,14 @@ ISCC.exe packaging\installer\netx.iss
|
||||||
Override version in the `.iss` or edit `#define MyAppVersion`.
|
Override version in the `.iss` or edit `#define MyAppVersion`.
|
||||||
Optional local zip only: `build_release.ps1 -CreateZip` (not for release upload).
|
Optional local zip only: `build_release.ps1 -CreateZip` (not for release upload).
|
||||||
|
|
||||||
|
### Local release without GitHub
|
||||||
|
|
||||||
|
GitHub Actions (`.github/workflows/release-windows.yml`, on `v*` tags) runs the same scripts. To release without it:
|
||||||
|
|
||||||
|
1. Install Python **3.12** (same as CI; side by side with other versions is fine, PATH not needed — the build picks it via `py -3.12` or `%LOCALAPPDATA%\Programs\Python\Python312`) and Inno Setup 6.
|
||||||
|
2. `powershell -ExecutionPolicy Bypass -File .\packaging\publish_release.ps1 -Version x.y.z -SkipGitHub` → `packaging\release\NetX-Setup-x.y.z.exe` + `.sha256`. PostgreSQL and WinSW come from `packaging\cache` (offline once cached). `npm ci` is skipped when `web\node_modules` already matches `package-lock.json`, so a running Vite dev server does not break the build.
|
||||||
|
3. Publish to Forgejo with `publish_forgejo_release.ps1`, or copy the Setup to offline machines; clients can update from Forgejo only via `NETX_UPDATE_SOURCES=forgejo`.
|
||||||
|
|
||||||
## End-user install
|
## End-user install
|
||||||
|
|
||||||
### Setup.exe
|
### Setup.exe
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,17 @@ if (-not $SkipWebBuild) {
|
||||||
Write-Host "==> npm build"
|
Write-Host "==> npm build"
|
||||||
Push-Location $webRoot
|
Push-Location $webRoot
|
||||||
try {
|
try {
|
||||||
& npm.cmd ci
|
# npm ci wipes node_modules first; on a dev box a running Vite locks native
|
||||||
if ($LASTEXITCODE -ne 0) { throw "npm_install_failed" }
|
# .node files and leaves it half-deleted. Skip when installed deps match the lockfile.
|
||||||
|
$installedLock = Join-Path $webRoot "node_modules\.package-lock.json"
|
||||||
|
$lock = Join-Path $webRoot "package-lock.json"
|
||||||
|
if ((Test-Path $installedLock) -and
|
||||||
|
(Get-Item $installedLock).LastWriteTimeUtc -ge (Get-Item $lock).LastWriteTimeUtc) {
|
||||||
|
Write-Host "==> node_modules up to date with package-lock.json - skip npm ci"
|
||||||
|
} else {
|
||||||
|
& npm.cmd ci
|
||||||
|
if ($LASTEXITCODE -ne 0) { throw "npm_install_failed" }
|
||||||
|
}
|
||||||
# Release packaging skips tsc (dev CI still uses `npm run build`).
|
# Release packaging skips tsc (dev CI still uses `npm run build`).
|
||||||
& npm.cmd run build:release
|
& npm.cmd run build:release
|
||||||
if ($LASTEXITCODE -ne 0) { throw "web_build_failed" }
|
if ($LASTEXITCODE -ne 0) { throw "web_build_failed" }
|
||||||
|
|
@ -175,7 +184,21 @@ foreach ($cmdName in @("NetX-FirstRun.cmd", "NetX-Start.cmd", "NetX-Tray.cmd", "
|
||||||
|
|
||||||
if ($CreateVenv) {
|
if ($CreateVenv) {
|
||||||
Write-Host "==> Creating portable python/runtime + .venv (must not reference build-machine paths)"
|
Write-Host "==> Creating portable python/runtime + .venv (must not reference build-machine paths)"
|
||||||
$pyPath = Get-NetxSystemPython
|
# Releases pin 3.12 (same as CI); prefer it even when another version is first on PATH.
|
||||||
|
$pyPath = $null
|
||||||
|
$pyLauncher = Get-Command "py" -ErrorAction SilentlyContinue
|
||||||
|
if ($pyLauncher -and $pyLauncher.Source -notmatch '\\WindowsApps\\') {
|
||||||
|
try {
|
||||||
|
$resolved = (& $pyLauncher.Source -3.12 -c "import sys; print(sys.executable)" 2>$null | Out-String).Trim()
|
||||||
|
if ($resolved -and (Test-Path -LiteralPath $resolved)) { $pyPath = $resolved }
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
if (-not $pyPath) {
|
||||||
|
foreach ($p in @("$env:LOCALAPPDATA\Programs\Python\Python312\python.exe", "$env:ProgramFiles\Python312\python.exe")) {
|
||||||
|
if (Test-Path -LiteralPath $p) { $pyPath = $p; break }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (-not $pyPath) { $pyPath = Get-NetxSystemPython }
|
||||||
if (-not $pyPath) { throw "python_not_found_for_venv: need Python 3.12.x (not WindowsApps stub)" }
|
if (-not $pyPath) { throw "python_not_found_for_venv: need Python 3.12.x (not WindowsApps stub)" }
|
||||||
$pyVersion = (& $pyPath -c "import sys; print('%d.%d' % sys.version_info[:2])" 2>$null | Out-String).Trim()
|
$pyVersion = (& $pyPath -c "import sys; print('%d.%d' % sys.version_info[:2])" 2>$null | Out-String).Trim()
|
||||||
if ($pyVersion -ne '3.12') { throw "python_version_mismatch: Windows releases require Python 3.12.x for reproducible runtimes; found $pyVersion at $pyPath" }
|
if ($pyVersion -ne '3.12') { throw "python_version_mismatch: Windows releases require Python 3.12.x for reproducible runtimes; found $pyVersion at $pyPath" }
|
||||||
|
|
@ -213,8 +236,10 @@ if ($CreateVenv) {
|
||||||
& $venvPy -c "from pathlib import Path; import glob; print(Path.cwd()); print(glob.__file__)"
|
& $venvPy -c "from pathlib import Path; import glob; print(Path.cwd()); print(glob.__file__)"
|
||||||
if ($LASTEXITCODE -ne 0) { throw "python_stdlib_smoke_failed: pathlib/glob import mismatch" }
|
if ($LASTEXITCODE -ne 0) { throw "python_stdlib_smoke_failed: pathlib/glob import mismatch" }
|
||||||
|
|
||||||
& $venvPy -m pip install --upgrade pip
|
# --no-warn-script-location: the PATH check realpath()s every entry and aborts on a
|
||||||
& $venvPy -m pip install -r (Join-Path $stage "requirements.txt")
|
# broken reparse point (e.g. a stale app folder on a detached volume). Irrelevant here.
|
||||||
|
& $venvPy -m pip install --upgrade pip --no-warn-script-location
|
||||||
|
& $venvPy -m pip install -r (Join-Path $stage "requirements.txt") --no-warn-script-location
|
||||||
if ($LASTEXITCODE -ne 0) { throw "pip_install_failed" }
|
if ($LASTEXITCODE -ne 0) { throw "pip_install_failed" }
|
||||||
|
|
||||||
$null = Repair-NetxShippedVenv -ProgramRoot $stage
|
$null = Repair-NetxShippedVenv -ProgramRoot $stage
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue