netx/packaging/README.md
oliver b016037270 Make Windows Setup bilingual, offline-capable, and use NetX branding.
Ship WinSW + icon assets, default first-run without network, EN/ZH installer UI.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-07 10:15:40 +08:00

7.7 KiB

NetX Windows packaging

Linux is unchanged: keep using your own PostgreSQL and NETX_DATABASE_URL with scripts/start_netx.sh. Nothing under this folder is required on Linux.

This directory builds a Windows deliverable with:

  • Optional bundled portable PostgreSQL or external existing Postgres
  • API-hosted UI (web/dist) — no separate Vite process for end users
  • Program / data split so upgrades do not wipe the database
  • Manual update script + check/apply updates (GitHub Releases or custom manifest)
  • Optional system tray + start-at-logon

What users get

Artifact How
NetX-x.y.z-win64.zip build_release.ps1
NetX-Setup-x.y.z.exe Compile installer/netx.iss with Inno Setup after staging

Installer: English + 简体中文 (language dialog). Icons use packaging/assets/netx.ico.

Offline: Setup ships portable PostgreSQL, .venv (when built with -CreateVenv), and WinSW. First-run uses -NonInteractive -DbMode bundled — 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.

Build (developer machine)

Prerequisites: Python 3.11+, Node 20+, PowerShell, network (to download PG binaries once).

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)
powershell -ExecutionPolicy Bypass -File .\packaging\build_release.ps1 -CreateVenv

Output:

  • packaging/release/netx-win64/ — stage tree
  • packaging/release/NetX-<ver>-win64.zip

Inno Setup:

ISCC.exe packaging\installer\netx.iss

Override version in the .iss or edit #define MyAppVersion.

End-user install

Setup.exe

  1. Run NetX-Setup-x.y.z.exe (admin).
  2. Files → %ProgramFiles%\NetX\ (program root).
  3. Data → %ProgramData%\NetX\ (.env, pgdata, spool, secrets).
  4. Optional post-install task runs setup_first_run.ps1 (choose bundled vs external DB).
  5. Start menu: Start NetX / Stop NetX / Open NetX UI.

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:
.\packaging\setup_first_run.ps1
.\packaging\start_netx_app.ps1

Database modes

Mode Behavior
bundled Start portable PG on 127.0.0.1:15432, data in data-root pgdata\
external Do not start PG; use NETX_DATABASE_URL (same as today / Linux)
unset Treated as external

Existing Windows deploys that only set NETX_DATABASE_URL keep working: never set NETX_DB_MODE=bundled unless you want the portable engine.

Manual update

.\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.

# Optional overrides in ProgramData\NetX\.env
# NETX_UPDATE_SOURCES=github,forgejo
# NETX_UPDATE_FORGEJO_URL=https://git.avelo.top/api/v1/repos/hansjone/netx/releases/latest
# NETX_UPDATE_GITHUB_REPO=hansjone/netx
# NETX_UPDATE_URL=https://cdn.example.com/netx/manifest.json
# NETX_UPDATE_TOKEN=******
Variable Role
NETX_UPDATE_FORGEJO_URL Forgejo/Gitea releases/latest API (default: git.avelo.top mirror)
NETX_UPDATE_GITHUB_REPO GitHub owner/repo (default hansjone/netx)
NETX_UPDATE_SOURCES Probe order / tie-break order, e.g. github,forgejo
NETX_UPDATE_URL Optional custom JSON manifest
.\packaging\check_update.ps1
.\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).

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:
# One-time: User env var (never commit the token)
# Forgejo → Settings → Applications → Generate New Token (repo write)
[Environment]::SetEnvironmentVariable("NETX_FORGEJO_TOKEN", "your_token", "User")
# Restart Cursor / open a new terminal so the agent/scripts see it

# Default publishes to LAN Forgejo; public git.avelo.top shows the same Release.
.\packaging\publish_forgejo_release.ps1 -Version 0.4.0

# Only when off the home LAN:
# .\packaging\publish_forgejo_release.ps1 -Version 0.4.0 -ForgejoBase "https://git.avelo.top"
Role URL
Publish default (home LAN) http://10.0.0.131:3000 (-ForgejoBase default)
Clients / remote clone https://git.avelo.top (Caddy → 10.0.0.131:3000)
Update probe (default) GitHub + https://git.avelo.top/.../releases/latest

Verify:

Token: NETX_FORGEJO_TOKEN (or FORGEJO_TOKEN).

Tray & autostart

# System tray: Start / Stop / Open UI / Check updates
.\packaging\netx_tray.ps1 -StartOnLaunch

# Start tray at Windows logon (current user)
.\packaging\install_autostart.ps1
# Remove: .\packaging\install_autostart.ps1 -Remove

Windows Service (admin)

Uses WinSW (downloaded on first install into packaging/cache). service_run.ps1 probes /health and restarts children after consecutive failures.

# Elevated PowerShell
.\packaging\install_service.ps1 -Start
# Uninstall: .\packaging\install_service.ps1 -Uninstall

# Fallback without WinSW binary management: SYSTEM scheduled task at startup
.\packaging\install_service.ps1 -Mode task -Start

Silent auto-update

# Writes NETX_UPDATE_AUTO=true and registers a daily task (default 03:30)
.\packaging\install_update_task.ps1

# Manual silent path (only applies when NETX_UPDATE_AUTO=true)
.\packaging\check_update.ps1 -Apply -Quiet -AutoOnly

Tray also auto-applies on launch when NETX_UPDATE_AUTO=true.

Code signing (optional, publisher machine)

.\packaging\sign_release.ps1 -Files .\packaging\release\NetX-Setup-0.4.0.exe -Thumbprint <cert-sha1>
# or: -PfxPath .\certs\code.pfx -PfxPassword ***

Needs signtool.exe (Windows SDK) and a real code-signing certificate. Without a trusted cert, SmartScreen may still warn.

Layout reminder

Program root (replaceable)     Data root (never wiped by update)
  netx_api\  web\dist\           .env
  postgres\pgsql\                pgdata\     (bundled only)
  packaging\  scripts\           data\auth\  data\runtime\
  version.json                   backups\