mirror of
https://github.com/hansjone/netx.git
synced 2026-10-08 23:33:21 +08:00
Release 0.4.11: Setup-only updates that preserve existing DB config.
Offline Setup and check_update now upgrade in place without the database wizard; zip packages are no longer published. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
7b5dd3eada
commit
a9c9d17550
11 changed files with 250 additions and 164 deletions
3
.github/workflows/release-windows.yml
vendored
3
.github/workflows/release-windows.yml
vendored
|
|
@ -22,7 +22,7 @@ jobs:
|
|||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Build release zip
|
||||
- name: Build release stage
|
||||
shell: pwsh
|
||||
run: |
|
||||
powershell -ExecutionPolicy Bypass -File ./packaging/build_release.ps1 -CreateVenv
|
||||
|
|
@ -43,6 +43,5 @@ jobs:
|
|||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: |
|
||||
packaging/release/NetX-*-win64.zip
|
||||
packaging/release/NetX-Setup-*.exe
|
||||
generate_release_notes: true
|
||||
|
|
|
|||
|
|
@ -158,9 +158,9 @@ API base: `http://127.0.0.1:8890/`
|
|||
|
||||
After `npm run build` in `web/`, the API can also serve the UI at `http://127.0.0.1:8890/` (same origin). See `NETX_UI_DIST_DIR` in `.env.example`.
|
||||
|
||||
### Windows installer / portable package (optional)
|
||||
### Windows installer (optional)
|
||||
|
||||
Fool-proof Windows delivery (bundled or external Postgres, program/data split, manual update) lives under [`packaging/`](packaging/README.md). **Linux installs are unchanged** — keep using your own Postgres and `scripts/start_netx.sh`.
|
||||
Fool-proof Windows delivery via `NetX-Setup-*.exe` (bundled or external Postgres, program/data split, offline upgrade over existing installs) lives under [`packaging/`](packaging/README.md). **Linux installs are unchanged** — keep using your own Postgres and `scripts/start_netx.sh`.
|
||||
|
||||
### 6) MCP(Cursor / oclaw / Claude)
|
||||
|
||||
|
|
|
|||
|
|
@ -14,12 +14,13 @@ This directory builds a Windows deliverable with:
|
|||
|
||||
| Artifact | How |
|
||||
|----------|-----|
|
||||
| `NetX-x.y.z-win64.zip` | `build_release.ps1` |
|
||||
| `NetX-Setup-x.y.z.exe` | Compile `installer/netx.iss` with [Inno Setup](https://jrsoftware.org/isinfo.php) after staging |
|
||||
| `NetX-Setup-x.y.z.exe` | Stage with `build_release.ps1`, then compile `installer/netx.iss` with [Inno Setup](https://jrsoftware.org/isinfo.php) |
|
||||
|
||||
Zip packages are **not** published. Releases ship **Setup.exe only**.
|
||||
|
||||
**Installer:** English + 简体中文 (language dialog). Icons use `packaging/assets/netx.ico`.
|
||||
|
||||
**Offline:** Setup ships portable PostgreSQL, **`python/runtime` + `.venv`** (portable; not tied to the build PC’s user profile), and WinSW. The installer wizard chooses **built-in or external** PostgreSQL and validates external credentials (`psql SELECT 1`) before files are installed — **no GitHub/EDB download on the target PC**. Service install uses bundled WinSW (pass `-AllowDownload` only on a build/dev machine if the binary is missing). Auto-update still needs network later, and is unchecked by default.
|
||||
**Offline:** Setup ships portable PostgreSQL, **`python/runtime` + `.venv`** (portable; not tied to the build PC’s user profile), and WinSW. **First install** shows the Database page (built-in or external PostgreSQL; external credentials validated with `psql SELECT 1`). **Re-running Setup when `%ProgramData%\NetX\.env` already has `NETX_DB_MODE`** skips the DB wizard and updates program files in place — **no GitHub/EDB download on the target PC**. Service install uses bundled WinSW (pass `-AllowDownload` only on a build/dev machine if the binary is missing). Auto-update still needs network later, and is unchecked by default.
|
||||
|
||||
**OS:** Windows 10/11 or Windows Server **2016+** recommended. Packaging scripts are UTF-8 **with BOM** so Chinese UI works on Windows PowerShell 5.x. Bundled Python in current releases is **3.13+**, which does **not** support Windows Server 2012 R2 — use Server 2016+ or a newer desktop OS.
|
||||
|
||||
|
|
@ -32,14 +33,13 @@ cd netx
|
|||
# Optional: download portable Postgres into packaging\postgres\pgsql
|
||||
powershell -ExecutionPolicy Bypass -File .\packaging\download_postgres.ps1
|
||||
|
||||
# Build web + stage + zip (-CreateVenv ships a ready .venv; large)
|
||||
# Build web + stage (-CreateVenv ships a ready .venv; large). No zip by default.
|
||||
powershell -ExecutionPolicy Bypass -File .\packaging\build_release.ps1 -CreateVenv
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
- `packaging/release/netx-win64/` — stage tree
|
||||
- `packaging/release/NetX-<ver>-win64.zip`
|
||||
- `packaging/release/netx-win64/` — stage tree (input to Inno Setup)
|
||||
|
||||
Inno Setup:
|
||||
|
||||
|
|
@ -47,34 +47,26 @@ Inno Setup:
|
|||
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).
|
||||
|
||||
## End-user install
|
||||
|
||||
### Setup.exe
|
||||
|
||||
1. Run `NetX-Setup-x.y.z.exe` (admin).
|
||||
2. On the **Database** page: choose built-in (offline) or external PostgreSQL (host/port/user/password/db; connection must succeed to continue).
|
||||
3. Files → `%ProgramFiles%\NetX\` (program root).
|
||||
4. Data → `%ProgramData%\NetX\` (`.env`, `pgdata`, spool, secrets). Post-install writes `.env` automatically.
|
||||
5. Start menu: **Start NetX** / **Stop NetX** / **Open NetX UI** / **Reconfigure database** (repair only).
|
||||
2. **First install:** Database page — choose built-in (offline) or external PostgreSQL (host/port/user/password/db; connection must succeed to continue).
|
||||
3. **Already installed (upgrade):** if `%ProgramData%\NetX\.env` already has `NETX_DB_MODE`, Setup **skips** the Database page, stops running NetX, replaces program files, and **keeps** data / DB settings. Use Start Menu → **Reconfigure database** only when you need to change DB mode.
|
||||
4. Files → `%ProgramFiles%\NetX\` (program root).
|
||||
5. Data → `%ProgramData%\NetX\` (`.env`, `pgdata`, spool, secrets).
|
||||
6. Start menu: **Start NetX** / **Stop NetX** / **Open NetX UI** / **Reconfigure database**.
|
||||
|
||||
Silent (bundled default): `/SILENT /DbMode=bundled`
|
||||
Silent first install (bundled default): `/SILENT /DbMode=bundled`
|
||||
Silent external: `/SILENT /DbMode=external /DbHost=... /DbPort=5432 /DbUser=... /DbPassword=... /DbName=...`
|
||||
Silent upgrade over existing data: `/VERYSILENT /NORESTART` (auto-detects `.env`; or force `/SkipDbPage=1`)
|
||||
Force DB wizard on an existing install: `/ForceDbPage=1`
|
||||
Optional credential key (reuse encrypted NE passwords from another install): `/CredentialSecretKey=...` — omit to auto-generate.
|
||||
|
||||
### Zip (portable)
|
||||
|
||||
1. Unpack anywhere.
|
||||
2. Marker `.portable` → data root is sibling `NetXData\`.
|
||||
3. Target needs **Python 3.11+** on PATH unless the zip was built with `-CreateVenv`.
|
||||
4. Run:
|
||||
|
||||
```powershell
|
||||
.\packaging\setup_first_run.ps1
|
||||
.\packaging\start_netx_app.ps1
|
||||
```
|
||||
|
||||
## Database modes
|
||||
|
||||
| Mode | Behavior |
|
||||
|
|
@ -87,14 +79,16 @@ Existing Windows deploys that only set `NETX_DATABASE_URL` keep working: never s
|
|||
|
||||
## Manual update
|
||||
|
||||
Preferred: run a newer `NetX-Setup-*.exe` over the same machine (upgrade mode keeps ProgramData).
|
||||
|
||||
Legacy/dev zip (only if you built with `-CreateZip`):
|
||||
|
||||
```powershell
|
||||
.\packaging\update_netx.ps1 -PackagePath .\NetX-0.4.0-win64.zip
|
||||
```
|
||||
|
||||
Stops services, replaces program folders (`netx_api`, `web`, `packaging`, `postgres`, …), **keeps** the data root, restarts. Schema migrations still run via Alembic on API start.
|
||||
|
||||
Or reinstall a newer `NetX-Setup-*.exe` over the same program directory.
|
||||
|
||||
## Check / apply updates
|
||||
|
||||
**Defaults (no `.env` needed):** probe **GitHub** (`hansjone/netx`) and Forgejo mirror (`https://git.avelo.top/hansjone/netx`), then use the **newest reachable** version. Same version → prefer GitHub.
|
||||
|
|
@ -120,15 +114,15 @@ Or reinstall a newer `NetX-Setup-*.exe` over the same program directory.
|
|||
.\packaging\check_update.ps1 -Apply
|
||||
```
|
||||
|
||||
Both sides should publish the same release assets (`NetX-*-win64.zip`). **Code mirror alone is not enough** — Forgejo pull-mirror syncs git/tags only; Release zip/exe must be uploaded separately (or clients can only fall back to GitHub).
|
||||
Both sides should publish the same **Setup.exe**. `check_update.ps1` prefers `NetX-Setup-*.exe` (legacy `win64.zip` still works if present). **Code mirror alone is not enough** — Forgejo pull-mirror syncs git/tags only; Release assets must be uploaded separately (or clients can only fall back to GitHub).
|
||||
|
||||
### Maintainer release checklist (Windows)
|
||||
|
||||
Do this on the **dev PC on the home LAN** after bumping version:
|
||||
|
||||
1. **Build** — `.\packaging\build_release.ps1 -CreateVenv` (and Inno Setup for Setup.exe if needed)
|
||||
2. **GitHub** — `.\packaging\publish_release.ps1 -Version x.y.z` (or `gh release create …`)
|
||||
3. **Forgejo (intranet)** — upload the same assets to QNAP Forgejo; public `git.avelo.top` is only a reverse proxy to the same instance:
|
||||
1. **Build** — `.\packaging\build_release.ps1 -CreateVenv` + Inno Setup → `NetX-Setup-*.exe`
|
||||
2. **GitHub** — `.\packaging\publish_release.ps1 -Version x.y.z` (uploads Setup.exe only)
|
||||
3. **Forgejo (intranet)** — upload the same Setup.exe to QNAP Forgejo; public `git.avelo.top` is only a reverse proxy to the same instance:
|
||||
|
||||
```powershell
|
||||
# One-time: User env var (never commit the token)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ param(
|
|||
[string]$OutDir = "",
|
||||
[switch]$SkipWebBuild = $false,
|
||||
[switch]$SkipPostgresDownload = $false,
|
||||
# Zip is no longer published; stage + Setup.exe only. Opt-in for local/dev testing.
|
||||
[switch]$CreateZip = $false,
|
||||
# Deprecated no-op (zip is off by default). Kept so older scripts that pass -SkipZip still run.
|
||||
[switch]$SkipZip = $false,
|
||||
# Default on: offline Setup must ship .venv so target PCs never pip-install.
|
||||
[switch]$CreateVenv = $true
|
||||
|
|
@ -233,15 +236,18 @@ if ($CreateVenv) {
|
|||
|
||||
Write-Host "==> Stage ready: $stage" -ForegroundColor Green
|
||||
|
||||
if (-not $SkipZip) {
|
||||
if ($SkipZip -and $CreateZip) {
|
||||
Write-Host "[WARN] -SkipZip ignored because -CreateZip was set" -ForegroundColor Yellow
|
||||
}
|
||||
if ($CreateZip) {
|
||||
$zip = Join-Path (Split-Path -Parent $stage) "NetX-$Version-win64.zip"
|
||||
if (Test-Path $zip) { Remove-Item -Force $zip }
|
||||
Compress-Archive -Path $stage -DestinationPath $zip -Force
|
||||
Write-Host "==> Zip: $zip" -ForegroundColor Green
|
||||
Write-Host "==> Zip (optional/dev): $zip" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Ship options:"
|
||||
Write-Host " Zip: user unpacks, runs packaging\setup_first_run.ps1 then start_netx_app.ps1"
|
||||
Write-Host "Ship:"
|
||||
Write-Host " Exe: compile packaging\installer\netx.iss with Inno Setup (needs stage above)"
|
||||
Write-Host " (Zip packages are not published; use -CreateZip only for local testing.)"
|
||||
Write-Host "Python: install 3.11+ on target, or rebuild with -CreateVenv and ship .venv"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
param(
|
||||
param(
|
||||
[string]$ProgramRoot = "",
|
||||
[string]$DataRoot = "",
|
||||
[string]$UpdateUrl = "",
|
||||
|
|
@ -109,16 +109,32 @@ function Convert-ReleaseToManifest {
|
|||
$tag = [string]$Rel.tag_name
|
||||
$ver = $tag.TrimStart('v', 'V')
|
||||
$assets = @($Rel.assets)
|
||||
$zipAsset = $assets | Where-Object { $_.name -match 'win64\.zip$' } | Select-Object -First 1
|
||||
# Prefer Setup.exe (current ship format). Legacy win64.zip still accepted.
|
||||
$setupAsset = $assets | Where-Object { $_.name -match 'Setup-.*\.exe$' } | Select-Object -First 1
|
||||
if (-not $zipAsset) { throw "${SourceName}_release_missing_zip" }
|
||||
|
||||
$zipUrl = Resolve-AssetUrl -Asset $zipAsset -Rel $Rel -SourceName $SourceName -ApiLatestUrl $ApiLatestUrl
|
||||
if (-not $zipUrl) { throw "${SourceName}_zip_url_missing" }
|
||||
$zipAsset = $assets | Where-Object { $_.name -match 'win64\.zip$' } | Select-Object -First 1
|
||||
if (-not $setupAsset -and -not $zipAsset) {
|
||||
throw "${SourceName}_release_missing_setup_or_zip"
|
||||
}
|
||||
|
||||
$setupUrl = ""
|
||||
if ($setupAsset) {
|
||||
$setupUrl = Resolve-AssetUrl -Asset $setupAsset -Rel $Rel -SourceName $SourceName -ApiLatestUrl $ApiLatestUrl
|
||||
if (-not $setupUrl) { throw "${SourceName}_setup_url_missing" }
|
||||
}
|
||||
$zipUrl = ""
|
||||
if ($zipAsset) {
|
||||
$zipUrl = Resolve-AssetUrl -Asset $zipAsset -Rel $Rel -SourceName $SourceName -ApiLatestUrl $ApiLatestUrl
|
||||
}
|
||||
|
||||
if ($setupUrl) {
|
||||
$primaryUrl = $setupUrl
|
||||
$packageKind = "setup"
|
||||
$primarySize = [int64]$(if ($setupAsset.size) { $setupAsset.size } else { 0 })
|
||||
} else {
|
||||
if (-not $zipUrl) { throw "${SourceName}_zip_url_missing" }
|
||||
$primaryUrl = $zipUrl
|
||||
$packageKind = "zip"
|
||||
$primarySize = [int64]$(if ($zipAsset.size) { $zipAsset.size } else { 0 })
|
||||
}
|
||||
|
||||
return [pscustomobject]@{
|
||||
|
|
@ -128,10 +144,11 @@ function Convert-ReleaseToManifest {
|
|||
notes_url = [string]$Rel.html_url
|
||||
source = $SourceName
|
||||
windows = [pscustomobject]@{
|
||||
url = $zipUrl
|
||||
url = $primaryUrl
|
||||
sha256 = ""
|
||||
size = [int64]$(if ($zipAsset.size) { $zipAsset.size } else { 0 })
|
||||
size = $primarySize
|
||||
setup_url = $setupUrl
|
||||
package = $packageKind
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -246,8 +263,26 @@ foreach ($c in $candidates) {
|
|||
|
||||
Write-Host "==> Selected source=$($manifest.source) latest=$($manifest.latest) (from $($candidates.Count) reachable)" -ForegroundColor Green
|
||||
|
||||
# Prefer Setup.exe when a manifest still lists a legacy zip as windows.url but also has setup_url.
|
||||
if ($manifest.windows -and $manifest.windows.setup_url) {
|
||||
$setupCandidate = [string]$manifest.windows.setup_url
|
||||
$urlNow = [string]$manifest.windows.url
|
||||
$pkgNow = if ($manifest.windows.package) { [string]$manifest.windows.package } else { "" }
|
||||
if ($setupCandidate -and ($pkgNow -eq "zip" -or $urlNow -match '\.zip(\?|$)' -or -not $urlNow)) {
|
||||
$manifest.windows | Add-Member -NotePropertyName url -NotePropertyValue $setupCandidate -Force
|
||||
$manifest.windows | Add-Member -NotePropertyName package -NotePropertyValue "setup" -Force
|
||||
}
|
||||
}
|
||||
|
||||
$latest = [string]$manifest.latest
|
||||
$cmp = Compare-SemVer -A $current -B $latest
|
||||
$packageKind = "setup"
|
||||
if ($manifest.windows.package) {
|
||||
$packageKind = [string]$manifest.windows.package
|
||||
} elseif ([string]$manifest.windows.url -match '\.zip(\?|$)') {
|
||||
$packageKind = "zip"
|
||||
}
|
||||
|
||||
$result = [pscustomobject]@{
|
||||
current = $current
|
||||
latest = $latest
|
||||
|
|
@ -255,6 +290,7 @@ $result = [pscustomobject]@{
|
|||
source = $(if ($manifest.source) { [string]$manifest.source } else { "unknown" })
|
||||
download_url = [string]$manifest.windows.url
|
||||
setup_url = $(if ($manifest.windows.setup_url) { [string]$manifest.windows.setup_url } else { "" })
|
||||
package = $packageKind
|
||||
notes_url = $(if ($manifest.notes_url) { [string]$manifest.notes_url } else { "" })
|
||||
sha256 = $(if ($manifest.windows.sha256) { [string]$manifest.windows.sha256 } else { "" })
|
||||
reachable = @($candidates | ForEach-Object { "$($_.source)=$($_.latest)" })
|
||||
|
|
@ -276,8 +312,7 @@ $autoVal = Get-Cfg "NETX_UPDATE_AUTO" ""
|
|||
if ($autoVal -match '^(1|true|yes|on)$') { $autoEnabled = $true }
|
||||
|
||||
if (-not $Apply) {
|
||||
Write-Host " Download (zip): $($result.download_url)"
|
||||
if ($result.setup_url) { Write-Host " Or install: $($result.setup_url)" }
|
||||
Write-Host " Download ($($result.package)): $($result.download_url)"
|
||||
Write-Host " To apply: .\packaging\check_update.ps1 -Apply"
|
||||
if (-not $Quiet) {
|
||||
$result | ConvertTo-Json -Compress | Write-Output
|
||||
|
|
@ -313,16 +348,22 @@ try {
|
|||
if (-not (Test-Path $dlDir)) {
|
||||
New-Item -ItemType Directory -Path $dlDir -Force | Out-Null
|
||||
}
|
||||
$zipName = "NetX-$latest-win64.zip"
|
||||
$zipPath = Join-Path $dlDir $zipName
|
||||
|
||||
$isSetup = ($result.package -eq "setup") -or ($result.download_url -match '\.exe(\?|$)')
|
||||
if ($isSetup) {
|
||||
$pkgName = "NetX-Setup-$latest.exe"
|
||||
} else {
|
||||
$pkgName = "NetX-$latest-win64.zip"
|
||||
}
|
||||
$pkgPath = Join-Path $dlDir $pkgName
|
||||
|
||||
$needDownload = $true
|
||||
if ((Test-Path -LiteralPath $zipPath) -and ((Get-Item -LiteralPath $zipPath).Length -gt 1MB)) {
|
||||
Write-Host "==> Using existing download: $zipPath ($([math]::Round((Get-Item $zipPath).Length/1MB,1)) MB)"
|
||||
if ((Test-Path -LiteralPath $pkgPath) -and ((Get-Item -LiteralPath $pkgPath).Length -gt 1MB)) {
|
||||
Write-Host "==> Using existing download: $pkgPath ($([math]::Round((Get-Item $pkgPath).Length/1MB,1)) MB)"
|
||||
$needDownload = $false
|
||||
}
|
||||
if ($needDownload) {
|
||||
Write-Host "==> Downloading $zipName from $($result.source) ..."
|
||||
Write-Host "==> Downloading $pkgName from $($result.source) ..."
|
||||
# Only attach token for non-GitHub hosts (Forgejo/private). Public GitHub assets need no auth;
|
||||
# a Forgejo token would break anonymous GitHub downloads.
|
||||
$dlHeaders = @{ "User-Agent" = "NetX-UpdateCheck" }
|
||||
|
|
@ -331,10 +372,10 @@ try {
|
|||
if ($UpdateToken -and -not $isGithub) {
|
||||
$dlHeaders["Authorization"] = "token $UpdateToken"
|
||||
}
|
||||
Invoke-WebRequest -Uri $result.download_url -OutFile $zipPath -Headers $dlHeaders -UseBasicParsing
|
||||
Invoke-WebRequest -Uri $result.download_url -OutFile $pkgPath -Headers $dlHeaders -UseBasicParsing
|
||||
}
|
||||
if ($result.sha256 -and $result.sha256 -notmatch 'REPLACE' -and $result.sha256.Trim()) {
|
||||
$hash = (Get-FileHash -Path $zipPath -Algorithm SHA256).Hash.ToLowerInvariant()
|
||||
$hash = (Get-FileHash -Path $pkgPath -Algorithm SHA256).Hash.ToLowerInvariant()
|
||||
$expect = $result.sha256.ToLowerInvariant()
|
||||
if ($hash -ne $expect) {
|
||||
throw "sha256_mismatch: got $hash expected $expect"
|
||||
|
|
@ -342,7 +383,7 @@ try {
|
|||
Write-Host "==> SHA256 OK"
|
||||
}
|
||||
|
||||
# Program Files installs need admin to replace files; elevate once (avoid loop via NETX_UPDATE_ELEVATED).
|
||||
# Program Files installs need admin; elevate once (avoid loop via NETX_UPDATE_ELEVATED).
|
||||
$progWritable = $false
|
||||
try {
|
||||
$probe = Join-Path $prog (".netx_w_" + [guid]::NewGuid().ToString("n"))
|
||||
|
|
@ -361,10 +402,26 @@ try {
|
|||
exit $ep.ExitCode
|
||||
}
|
||||
|
||||
Write-Host "==> Applying update via update_netx.ps1"
|
||||
$env:NETX_UPDATE_ELEVATED = "1"
|
||||
& powershell -ExecutionPolicy Bypass -File (Join-Path $PSScriptRoot "update_netx.ps1") `
|
||||
-PackagePath $zipPath -ProgramRoot $prog -DataRoot $data
|
||||
if ($isSetup) {
|
||||
# Silent Setup over an existing configured install skips the DB wizard
|
||||
# (see installer/netx.iss GSkipDbPage) and preserves ProgramData.
|
||||
Write-Host "==> Applying update via silent Setup.exe"
|
||||
$setupArgs = "/VERYSILENT /NORESTART /SUPPRESSMSGBOXES /DIR=`"$prog`" /SkipDbPage=1"
|
||||
$sp = Start-Process -FilePath $pkgPath -ArgumentList $setupArgs -Wait -PassThru
|
||||
if ($null -eq $sp.ExitCode -or $sp.ExitCode -ne 0) {
|
||||
$code = if ($null -eq $sp.ExitCode) { "null" } else { $sp.ExitCode }
|
||||
throw "setup_update_failed: exit $code"
|
||||
}
|
||||
Write-Host "==> Restarting NetX after Setup"
|
||||
& (Join-Path $PSScriptRoot "start_netx_app.ps1") `
|
||||
-ProgramRoot $prog -DataRoot $data -SkipBrowser
|
||||
if ($LASTEXITCODE -and $LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||
} else {
|
||||
Write-Host "==> Applying legacy zip update via update_netx.ps1"
|
||||
& powershell -ExecutionPolicy Bypass -File (Join-Path $PSScriptRoot "update_netx.ps1") `
|
||||
-PackagePath $pkgPath -ProgramRoot $prog -DataRoot $data
|
||||
}
|
||||
Write-Host "==> Update applied to $latest" -ForegroundColor Green
|
||||
} finally {
|
||||
Remove-Item -Force $lockFile -ErrorAction SilentlyContinue
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
; NetX Windows installer (Inno Setup 6+)
|
||||
; NetX Windows installer (Inno Setup 6+)
|
||||
; Compile after: packaging\build_release.ps1
|
||||
; ISCC.exe packaging\installer\netx.iss
|
||||
; Encoding: UTF-8 with BOM (required for Chinese CustomMessages)
|
||||
|
||||
#define MyAppName "NetX"
|
||||
#ifndef MyAppVersion
|
||||
#define MyAppVersion "0.4.10"
|
||||
#define MyAppVersion "0.4.11"
|
||||
#endif
|
||||
#define MyAppPublisher "NetX"
|
||||
#define MyAppURL "https://github.com/hansjone/netx"
|
||||
|
|
@ -39,7 +39,7 @@ ArchitecturesAllowed=x64compatible
|
|||
ArchitecturesInstallIn64BitMode=x64compatible
|
||||
PrivilegesRequired=admin
|
||||
; Data lives under {commonappdata}\NetX - not overwritten by upgrades.
|
||||
; Do NOT use CloseApplications=yes — it can freeze/beep on the Tasks/Ready
|
||||
; Do NOT use CloseApplications=yes — it can freeze/beep on the Tasks/Ready
|
||||
; pages while scanning locked NetX tray/service processes with no visible dialog.
|
||||
CloseApplications=no
|
||||
ShowLanguageDialog=yes
|
||||
|
|
@ -66,45 +66,47 @@ english.DbUser=User
|
|||
english.DbPassword=Password
|
||||
english.DbName=Database
|
||||
english.CredKey=Credential key
|
||||
english.CredKeyHint=NETX_CREDENTIAL_SECRET_KEY (optional — empty = auto-generate)
|
||||
english.CredKeyHint=NETX_CREDENTIAL_SECRET_KEY (optional — empty = auto-generate)
|
||||
english.DbFieldsRequired=Please fill in host, port, user, password, and database name.
|
||||
english.DbTesting=Testing PostgreSQL connection, please wait…
|
||||
english.DbTesting=Testing PostgreSQL connection, please wait…
|
||||
english.DbTestFailed=Cannot connect to PostgreSQL with these settings.%n%n%1%n%nFix the settings and try again.
|
||||
english.DbTestExtractFailed=Could not extract PostgreSQL client tools for connection test.
|
||||
english.DbSilentExternalMissing=Silent install with external DB requires /DbHost /DbUser /DbPassword /DbName (optional /DbPort).
|
||||
english.DbApplyFailed=Database configuration failed after file install (exit %1).%n%nLog: %2%n%nFix the problem, then use Start Menu → Reconfigure database — or reinstall.
|
||||
english.DbApplyFailed=Database configuration failed after file install (exit %1).%n%nLog: %2%n%nFix the problem, then use Start Menu → Reconfigure database — or reinstall.
|
||||
english.DbApplyExecFailed=Could not start database configuration script.
|
||||
english.DbBundledMissing=Built-in PostgreSQL files are missing from the install folder:%n%1%n%nThe Setup package is incomplete. Re-download NetX-Setup and install again.
|
||||
english.DbEnvMissing=Database configuration did not write %ProgramData%\NetX\.env.
|
||||
english.ReconfigureDb=Reconfigure database
|
||||
chinesesimplified.CreateDesktopIcon=创建桌面快捷方式
|
||||
chinesesimplified.SetupOptions=安装完成后:
|
||||
chinesesimplified.StartTrayNow=立即启动 NetX 托盘
|
||||
chinesesimplified.EnableAutostart=开机时自动启动 NetX 托盘
|
||||
chinesesimplified.EnableAutoUpdate=启用每日静默自动更新(以后需要联网)
|
||||
chinesesimplified.InstallService=安装为 Windows 服务(使用已捆绑的 WinSW,可离线)
|
||||
chinesesimplified.UninstallDeleteData=是否同时删除 NetX 数据(%ProgramData%\NetX)?%n%n是 = 删除数据库、配置和密钥%n否 = 保留数据以便以后重装
|
||||
chinesesimplified.DbPageCaption=数据库
|
||||
chinesesimplified.DbPageDescription=选择内置或外置 PostgreSQL。可选粘贴已有 NETX_CREDENTIAL_SECRET_KEY;留空则自动生成。
|
||||
chinesesimplified.DbBundled=内置 PostgreSQL(便携,可离线)
|
||||
chinesesimplified.DbExternal=外置 PostgreSQL(已有服务器)
|
||||
chinesesimplified.DbHost=主机
|
||||
chinesesimplified.DbPort=端口
|
||||
chinesesimplified.DbUser=用户
|
||||
chinesesimplified.DbPassword=密码
|
||||
chinesesimplified.DbName=数据库名
|
||||
chinesesimplified.CredKey=凭据密钥
|
||||
chinesesimplified.CredKeyHint=NETX_CREDENTIAL_SECRET_KEY(可选,留空=自动生成)
|
||||
chinesesimplified.DbFieldsRequired=请填写主机、端口、用户、密码和数据库名。
|
||||
chinesesimplified.DbTesting=正在测试 PostgreSQL 连接,请稍候…
|
||||
chinesesimplified.DbTestFailed=无法用当前设置连接 PostgreSQL。%n%n%1%n%n请改正后重试。
|
||||
chinesesimplified.DbTestExtractFailed=无法解压 PostgreSQL 客户端以测试连接。
|
||||
chinesesimplified.DbSilentExternalMissing=静默安装外置库需要参数 /DbHost /DbUser /DbPassword /DbName(可选 /DbPort)。
|
||||
chinesesimplified.DbApplyFailed=文件安装后数据库自动配置失败(退出码 %1)。%n%n日志: %2%n%n请处理后使用开始菜单 → 重新配置数据库,或重新安装。
|
||||
chinesesimplified.DbApplyExecFailed=无法启动数据库配置脚本。
|
||||
chinesesimplified.DbBundledMissing=安装目录中缺少内置 PostgreSQL 文件:%n%1%n%n安装包不完整,请重新下载 NetX-Setup 后再装。
|
||||
chinesesimplified.DbEnvMissing=数据库配置未写入 %ProgramData%\NetX\.env。
|
||||
chinesesimplified.ReconfigureDb=重新配置数据库
|
||||
english.UpgradeKeepDb=Existing NetX data found - database settings will be kept (no wizard).
|
||||
chinesesimplified.CreateDesktopIcon=创建桌面快捷方式
|
||||
chinesesimplified.SetupOptions=安装完成后:
|
||||
chinesesimplified.StartTrayNow=立即启动 NetX 托盘
|
||||
chinesesimplified.EnableAutostart=开机时自动启动 NetX 托盘
|
||||
chinesesimplified.EnableAutoUpdate=启用每日静默自动更新(以后需要联网)
|
||||
chinesesimplified.InstallService=安装为 Windows 服务(使用已捆绑的 WinSW,可离线)
|
||||
chinesesimplified.UninstallDeleteData=是否同时删除 NetX 数据(%ProgramData%\NetX)?%n%n是 = 删除数据库、配置和密钥%n否 = 保留数据以便以后重装
|
||||
chinesesimplified.DbPageCaption=数据库
|
||||
chinesesimplified.DbPageDescription=选择内置或外置 PostgreSQL。可选粘贴已有 NETX_CREDENTIAL_SECRET_KEY;留空则自动生成。
|
||||
chinesesimplified.DbBundled=内置 PostgreSQL(便携,可离线)
|
||||
chinesesimplified.DbExternal=外置 PostgreSQL(已有服务器)
|
||||
chinesesimplified.DbHost=主机
|
||||
chinesesimplified.DbPort=端口
|
||||
chinesesimplified.DbUser=用户
|
||||
chinesesimplified.DbPassword=密码
|
||||
chinesesimplified.DbName=数据库名
|
||||
chinesesimplified.CredKey=凭据密钥
|
||||
chinesesimplified.CredKeyHint=NETX_CREDENTIAL_SECRET_KEY(可选,留空=自动生成)
|
||||
chinesesimplified.DbFieldsRequired=请填写主机、端口、用户、密码和数据库名。
|
||||
chinesesimplified.DbTesting=正在测试 PostgreSQL 连接,请稍候…
|
||||
chinesesimplified.DbTestFailed=无法用当前设置连接 PostgreSQL。%n%n%1%n%n请改正后重试。
|
||||
chinesesimplified.DbTestExtractFailed=无法解压 PostgreSQL 客户端以测试连接。
|
||||
chinesesimplified.DbSilentExternalMissing=静默安装外置库需要参数 /DbHost /DbUser /DbPassword /DbName(可选 /DbPort)。
|
||||
chinesesimplified.DbApplyFailed=文件安装后数据库自动配置失败(退出码 %1)。%n%n日志: %2%n%n请处理后使用开始菜单 → 重新配置数据库,或重新安装。
|
||||
chinesesimplified.DbApplyExecFailed=无法启动数据库配置脚本。
|
||||
chinesesimplified.DbBundledMissing=安装目录中缺少内置 PostgreSQL 文件:%n%1%n%n安装包不完整,请重新下载 NetX-Setup 后再装。
|
||||
chinesesimplified.DbEnvMissing=数据库配置未写入 %ProgramData%\NetX\.env。
|
||||
chinesesimplified.ReconfigureDb=重新配置数据库
|
||||
chinesesimplified.UpgradeKeepDb=检测到已有 NetX 数据 - 将保留数据库配置(跳过向导)。
|
||||
|
||||
[Tasks]
|
||||
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: checkedonce
|
||||
|
|
@ -140,7 +142,7 @@ Name: "{commonappdata}\NetX\backups"; Permissions: users-modify
|
|||
; Remove legacy desktop shortcuts from older Setup builds (keep a single NetX icon).
|
||||
Type: files; Name: "{commondesktop}\NetX Start.lnk"
|
||||
Type: files; Name: "{commondesktop}\NetX First-time setup.lnk"
|
||||
Type: files; Name: "{commondesktop}\首次配置(内置或外置数据库).lnk"
|
||||
Type: files; Name: "{commondesktop}\首次配置(内置或外置数据库).lnk"
|
||||
|
||||
[Icons]
|
||||
; Prefer .cmd targets so Server 2012 / classic Start Menu shows normal program entries.
|
||||
|
|
@ -200,6 +202,7 @@ var
|
|||
GDbName: String;
|
||||
GCredKey: String;
|
||||
GSkipDbPage: Boolean;
|
||||
GIsUpgrade: Boolean;
|
||||
GDbConfigured: Boolean;
|
||||
GPgToolsReady: Boolean;
|
||||
GDbConnOk: Boolean;
|
||||
|
|
@ -248,6 +251,37 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function ParamIsTruthy(const ParamName: String): Boolean;
|
||||
var
|
||||
V: String;
|
||||
begin
|
||||
V := LowerCase(Trim(ExpandConstant('{param:' + ParamName + '|}')));
|
||||
Result := (V = '1') or (V = 'true') or (V = 'yes') or (V = 'on');
|
||||
end;
|
||||
|
||||
function DetectExistingConfiguredInstall(): Boolean;
|
||||
begin
|
||||
{ Configured install = ProgramData\.env already has NETX_DB_MODE. }
|
||||
Result := EnvHasDbMode();
|
||||
end;
|
||||
|
||||
procedure StopNetxBeforeFileReplace();
|
||||
var
|
||||
ResultCode: Integer;
|
||||
StopScript: String;
|
||||
Params: String;
|
||||
begin
|
||||
StopScript := ExpandConstant('{app}\packaging\stop_netx_app.ps1');
|
||||
if not FileExists(StopScript) then
|
||||
Exit;
|
||||
Params :=
|
||||
'-NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File "' + StopScript + '"' +
|
||||
' -ProgramRoot "' + ExpandConstant('{app}') + '"' +
|
||||
' -DataRoot "' + ExpandConstant('{commonappdata}\NetX') + '"' +
|
||||
' -KillTray';
|
||||
Exec('powershell.exe', Params, ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, ResultCode);
|
||||
end;
|
||||
|
||||
function NetxShouldStartTray(): Boolean;
|
||||
begin
|
||||
Result := GDbConfigured or
|
||||
|
|
@ -504,10 +538,16 @@ begin
|
|||
GDbConfigured := False;
|
||||
GPgToolsReady := False;
|
||||
GDbConnOk := False;
|
||||
{ Always show DB page so choosing built-in always re-runs auto-configure.
|
||||
Skipping when .env exists caused upgrades/reinstalls to keep a broken or
|
||||
external config and still launch tray → confusing "first-time" prompts. }
|
||||
GSkipDbPage := False;
|
||||
{ Upgrade / reinstall over a configured install: skip DB wizard and keep
|
||||
ProgramData\.env / pgdata. Fresh install still shows the Database page.
|
||||
Force wizard: /ForceDbPage=1 Force skip: /SkipDbPage=1 }
|
||||
GIsUpgrade := DetectExistingConfiguredInstall();
|
||||
if ParamIsTruthy('ForceDbPage') then
|
||||
GSkipDbPage := False
|
||||
else if ParamIsTruthy('SkipDbPage') then
|
||||
GSkipDbPage := True
|
||||
else
|
||||
GSkipDbPage := GIsUpgrade;
|
||||
|
||||
DbPage := CreateCustomPage(wpSelectDir,
|
||||
ExpandConstant('{cm:DbPageCaption}'),
|
||||
|
|
@ -679,7 +719,7 @@ begin
|
|||
end;
|
||||
|
||||
{ Connection test here so bad settings never reach Tasks/Ready.
|
||||
Show busy state — ExtractTemporaryFile + psql can take a few seconds. }
|
||||
Show busy state — ExtractTemporaryFile + psql can take a few seconds. }
|
||||
SetWizardBusy(True, ExpandConstant('{cm:DbTesting}'));
|
||||
try
|
||||
Result := ValidateExternalDbSaved(ErrMsg);
|
||||
|
|
@ -863,7 +903,11 @@ var
|
|||
begin
|
||||
if CurStep = ssPostInstall then
|
||||
begin
|
||||
ApplyDatabaseConfig();
|
||||
{ Upgrade keeps existing .env / pgdata - do not re-run DB wizard. }
|
||||
if not GSkipDbPage then
|
||||
ApplyDatabaseConfig()
|
||||
else
|
||||
GDbConfigured := FileExists(ExpandConstant('{commonappdata}\NetX\.env'));
|
||||
|
||||
UninstallKey :=
|
||||
'Software\Microsoft\Windows\CurrentVersion\Uninstall\{A7E3C2D1-9F40-4B8E-9C1A-NETXWIN64001}_is1';
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
{
|
||||
"channel": "stable",
|
||||
"latest": "0.4.10",
|
||||
"latest": "0.4.11",
|
||||
"min_compatible": "0.3.0",
|
||||
"notes_url": "https://github.com/hansjone/netx/releases/tag/v0.4.10",
|
||||
"notes_url": "https://github.com/hansjone/netx/releases/tag/v0.4.11",
|
||||
"windows": {
|
||||
"url": "https://github.com/hansjone/netx/releases/download/v0.4.10/NetX-0.4.10-win64.zip",
|
||||
"setup_url": "https://github.com/hansjone/netx/releases/download/v0.4.10/NetX-Setup-0.4.10.exe",
|
||||
"url": "https://github.com/hansjone/netx/releases/download/v0.4.11/NetX-Setup-0.4.11.exe",
|
||||
"setup_url": "https://github.com/hansjone/netx/releases/download/v0.4.11/NetX-Setup-0.4.11.exe",
|
||||
"package": "setup",
|
||||
"sha256": "",
|
||||
"size": 0
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
param(
|
||||
param(
|
||||
[string]$Version = "",
|
||||
[string]$ForgejoBase = "http://10.0.0.131:3000",
|
||||
[string]$Owner = "hansjone",
|
||||
[string]$Repo = "netx",
|
||||
[string]$Token = "",
|
||||
[string]$ReleaseDir = "",
|
||||
[switch]$SkipSetup = $false
|
||||
[string]$ReleaseDir = ""
|
||||
)
|
||||
|
||||
# Publish Windows release assets to Forgejo/Gitea (mirror sync does NOT copy GitHub Release files).
|
||||
# Publish Windows Setup.exe to Forgejo/Gitea (mirror sync does NOT copy GitHub Release files).
|
||||
# Requires a Forgejo token with repo write (Settings → Applications → Generate New Token).
|
||||
# Default: home LAN Forgejo. Public git.avelo.top is the same instance (VPS reverse proxy).
|
||||
#
|
||||
|
|
@ -28,7 +27,6 @@ if (-not $Version) {
|
|||
}
|
||||
$tag = "v$Version"
|
||||
$relDir = if ($ReleaseDir) { $ReleaseDir } else { Join-Path $PSScriptRoot "release" }
|
||||
$zip = Join-Path $relDir "NetX-$Version-win64.zip"
|
||||
$setup = Join-Path $relDir "NetX-Setup-$Version.exe"
|
||||
|
||||
if (-not $Token) {
|
||||
|
|
@ -38,8 +36,8 @@ if (-not $Token) {
|
|||
if (-not $Token) {
|
||||
throw "forgejo_token_required: set NETX_FORGEJO_TOKEN or pass -Token"
|
||||
}
|
||||
if (-not (Test-Path $zip)) {
|
||||
throw "missing_zip: $zip (run build_release.ps1 first)"
|
||||
if (-not (Test-Path $setup)) {
|
||||
throw "missing_setup: $setup (run build_release.ps1 + ISCC first)"
|
||||
}
|
||||
|
||||
$apiBase = "$ForgejoBase/api/v1/repos/$Owner/$Repo"
|
||||
|
|
@ -84,10 +82,9 @@ try {
|
|||
}
|
||||
|
||||
$notes = @"
|
||||
NetX $Version Windows install package (published from GitHub release build).
|
||||
NetX $Version Windows installer (published from GitHub release build).
|
||||
|
||||
- NetX-Setup-$Version.exe
|
||||
- NetX-$Version-win64.zip
|
||||
"@
|
||||
|
||||
if ($existing -and $existing.id) {
|
||||
|
|
@ -97,12 +94,12 @@ if ($existing -and $existing.id) {
|
|||
|
||||
Write-Host "==> Creating release $tag"
|
||||
$rel = Invoke-ForgejoJson -Method POST -Url "$apiBase/releases" -Body @{
|
||||
tag_name = $tag
|
||||
target = "main"
|
||||
name = "NetX $Version"
|
||||
body = $notes
|
||||
draft = $false
|
||||
prerelease = $false
|
||||
tag_name = $tag
|
||||
target = "main"
|
||||
name = "NetX $Version"
|
||||
body = $notes
|
||||
draft = $false
|
||||
prerelease = $false
|
||||
}
|
||||
$relId = $rel.id
|
||||
if (-not $relId) { throw "forgejo_create_release_failed" }
|
||||
|
|
@ -123,10 +120,7 @@ function Upload-ForgejoAsset {
|
|||
Write-Host " OK $name" -ForegroundColor Green
|
||||
}
|
||||
|
||||
Upload-ForgejoAsset -Path $zip
|
||||
if (-not $SkipSetup -and (Test-Path $setup)) {
|
||||
Upload-ForgejoAsset -Path $setup
|
||||
}
|
||||
Upload-ForgejoAsset -Path $setup
|
||||
|
||||
$releaseUrl = "$ForgejoBase/$Owner/$Repo/releases/tag/$tag"
|
||||
Write-Host ""
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
param(
|
||||
param(
|
||||
[string]$Version = "",
|
||||
[switch]$SkipBuild = $false,
|
||||
[switch]$SkipInstaller = $false,
|
||||
|
|
@ -16,7 +16,6 @@ if (-not $Version) {
|
|||
}
|
||||
$tag = "v$Version"
|
||||
$releaseDir = Join-Path $PSScriptRoot "release"
|
||||
$zip = Join-Path $releaseDir "NetX-$Version-win64.zip"
|
||||
$setup = Join-Path $releaseDir "NetX-Setup-$Version.exe"
|
||||
|
||||
Write-Host "==> NetX publish $tag"
|
||||
|
|
@ -26,10 +25,6 @@ if (-not $SkipBuild) {
|
|||
-Version $Version -CreateVenv
|
||||
}
|
||||
|
||||
if (-not (Test-Path $zip)) {
|
||||
throw "missing_zip: $zip"
|
||||
}
|
||||
|
||||
if (-not $SkipInstaller) {
|
||||
$isccCmd = Get-Command ISCC.exe -ErrorAction SilentlyContinue
|
||||
$isccCandidates = @(
|
||||
|
|
@ -40,27 +35,23 @@ if (-not $SkipInstaller) {
|
|||
) | Where-Object { $_ -and (Test-Path $_) }
|
||||
$iscc = $isccCandidates | Select-Object -First 1
|
||||
if (-not $iscc) {
|
||||
Write-Host "[WARN] Inno Setup (ISCC) not found. Install: winget install JRSoftware.InnoSetup" -ForegroundColor Yellow
|
||||
Write-Host " Skipping Setup.exe; zip-only release."
|
||||
} else {
|
||||
Write-Host "==> Compiling installer: $iscc"
|
||||
& $iscc "/DMyAppVersion=$Version" (Join-Path $PSScriptRoot "installer\netx.iss")
|
||||
if (-not (Test-Path $setup)) {
|
||||
throw "installer_build_failed: expected $setup"
|
||||
}
|
||||
Write-Host "==> Setup.exe: $setup" -ForegroundColor Green
|
||||
throw "innosetup_not_found: install with winget install JRSoftware.InnoSetup"
|
||||
}
|
||||
Write-Host "==> Compiling installer: $iscc"
|
||||
& $iscc "/DMyAppVersion=$Version" (Join-Path $PSScriptRoot "installer\netx.iss")
|
||||
if (-not (Test-Path $setup)) {
|
||||
throw "installer_build_failed: expected $setup"
|
||||
}
|
||||
Write-Host "==> Setup.exe: $setup" -ForegroundColor Green
|
||||
}
|
||||
|
||||
if (-not (Test-Path $setup)) {
|
||||
throw "missing_setup: $setup"
|
||||
}
|
||||
|
||||
if ($Sign) {
|
||||
$toSign = @()
|
||||
if (Test-Path $setup) { $toSign += $setup }
|
||||
if ($toSign.Count -eq 0) {
|
||||
Write-Host "[WARN] -Sign set but no Setup.exe to sign"
|
||||
} else {
|
||||
Write-Host "==> Signing release artifacts"
|
||||
& powershell -ExecutionPolicy Bypass -File (Join-Path $PSScriptRoot "sign_release.ps1") -Files $toSign
|
||||
}
|
||||
Write-Host "==> Signing release artifacts"
|
||||
& powershell -ExecutionPolicy Bypass -File (Join-Path $PSScriptRoot "sign_release.ps1") -Files @($setup)
|
||||
}
|
||||
|
||||
if ($SkipGitHub) {
|
||||
|
|
@ -81,27 +72,24 @@ $viewCode = $LASTEXITCODE
|
|||
$ErrorActionPreference = $prevEap
|
||||
if ($viewCode -eq 0) {
|
||||
Write-Host "==> Release $tag exists; uploading assets"
|
||||
gh release upload $tag $zip --clobber
|
||||
if (Test-Path $setup) {
|
||||
gh release upload $tag $setup --clobber
|
||||
}
|
||||
gh release upload $tag $setup --clobber
|
||||
} else {
|
||||
$notes = @"
|
||||
## NetX $Version — first Windows installable release
|
||||
## NetX $Version
|
||||
|
||||
### Downloads
|
||||
- **NetX-Setup-$Version.exe** — recommended installer (Program Files + ProgramData)
|
||||
- **NetX-$Version-win64.zip** — portable directory package
|
||||
- **NetX-Setup-$Version.exe** — Windows installer (Program Files + ProgramData)
|
||||
|
||||
### Requirements
|
||||
- Windows 10/11 x64
|
||||
- No separate Python or PostgreSQL install required (bundled in package)
|
||||
- Windows 10/11 x64 (or Windows Server 2016+)
|
||||
- No separate Python or PostgreSQL install required (bundled)
|
||||
|
||||
### Quick start (installer)
|
||||
### Quick start
|
||||
1. Run ``NetX-Setup-$Version.exe`` as administrator.
|
||||
2. Complete first-time setup (choose **bundled** or **external** PostgreSQL).
|
||||
3. Start menu → **Start NetX** → browser opens ``http://127.0.0.1:8890/``
|
||||
4. Default login: ``admin`` / ``admin123`` (change after first login)
|
||||
2. **First install:** choose built-in or external PostgreSQL.
|
||||
3. **Already installed:** Setup detects existing data and updates in place (keeps DB settings).
|
||||
4. Start menu → **Start NetX** → ``http://127.0.0.1:8890/``
|
||||
5. Default login: ``admin`` / ``admin123`` (change after first login)
|
||||
|
||||
### Linux
|
||||
Unchanged — use your own PostgreSQL and ``scripts/start_netx.sh``.
|
||||
|
|
@ -110,8 +98,7 @@ See [packaging/README.md](https://github.com/hansjone/netx/blob/main/packaging/R
|
|||
"@
|
||||
$args = @("release", "create", $tag, "--title", "NetX $Version", "--notes", $notes)
|
||||
if ($Draft) { $args += "--draft" }
|
||||
$args += $zip
|
||||
if (Test-Path $setup) { $args += $setup }
|
||||
$args += $setup
|
||||
& gh @args
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
param(
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$PackagePath,
|
||||
[string]$ProgramRoot = "",
|
||||
|
|
@ -22,10 +22,14 @@ New-Item -ItemType Directory -Path $work -Force | Out-Null
|
|||
|
||||
try {
|
||||
Write-Host "==> Extracting update package"
|
||||
# Preferred end-user path is NetX-Setup-*.exe (check_update / offline installer).
|
||||
# This script remains for legacy/dev .zip packages (build_release.ps1 -CreateZip).
|
||||
if ($PackagePath.ToLowerInvariant().EndsWith(".zip")) {
|
||||
Expand-Archive -Path $PackagePath -DestinationPath $work -Force
|
||||
} elseif ($PackagePath.ToLowerInvariant().EndsWith(".exe")) {
|
||||
throw "unsupported_package: run NetX-Setup-*.exe (upgrade keeps DB), or use check_update.ps1 -Apply"
|
||||
} else {
|
||||
throw "unsupported_package: use a .zip built by build_release.ps1"
|
||||
throw "unsupported_package: use a .zip from build_release.ps1 -CreateZip, or NetX-Setup-*.exe"
|
||||
}
|
||||
|
||||
$src = $work
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||
|
||||
[project]
|
||||
name = "netx-ops"
|
||||
version = "0.4.10"
|
||||
version = "0.4.11"
|
||||
description = "netx operations tool: alarm-centric workflows with REST API and stdio MCP"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue