Skip to content

feat: support in-page upgrade for git-clone deployments - #2319

Open
kosmo888 wants to merge 2 commits into
EKKOLearnAI:mainfrom
kosmo888:feat/web-ui-git-clone-upgrade
Open

feat: support in-page upgrade for git-clone deployments#2319
kosmo888 wants to merge 2 commits into
EKKOLearnAI:mainfrom
kosmo888:feat/web-ui-git-clone-upgrade

Conversation

@kosmo888

@kosmo888 kosmo888 commented Aug 1, 2026

Copy link
Copy Markdown

Problem

The Web UI "Update" button only works for npm global install deployments (npm install -g hermes-web-ui@latest). Users running from a git clone with systemd cannot upgrade from the page:

  1. The update check compares the local version against the npm registry, which may lag behind the git repo
  2. handleUpdate runs npm install -g hermes-web-ui@latest — this installs to /usr/lib/node_modules/, but the systemd service runs from the git clone directory (dist/server/index.js). The running server never picks up the change.
  3. The restart mechanism (hermes-web-ui restart) targets the npm-installed CLI, not the git-clone process

Result: clicking "Update" in the sidebar appears to succeed, but the running server is never actually updated. The user has no way to upgrade from the page.

Fix

health.ts

  • Detect git-clone deployment by checking for a .git directory relative to the server module location
  • Check for updates via git (git fetch origin main && git show origin/main:package.json) instead of the npm registry when in a git-clone deployment
  • Expose is_git_clone: boolean in the health response so the frontend can show appropriate messaging

update.ts

  • Add runGitUpdateInstall(): stashes local changes, runs git pull origin main, npm install --include=dev, npm run build
  • Add spawnGitRestart(): detects systemd service via cgroup inspection and uses systemctl restart, falling back to the existing spawn-restart mechanism
  • Modify handleUpdate: checks isGitCloneDeployment() first and routes to the git upgrade path; falls back to the original npm global install path for non-git deployments

system.ts (client)

  • Add is_git_clone?: boolean to HealthResponse interface

How it works (git-clone deployment)

User clicks "Update" in sidebar
  → POST /api/hermes/update
  → handleUpdate detects .git directory → isGitCloneDeployment() = true
  → runGitUpdateInstall():
      1. git stash (if local changes exist)
      2. git fetch origin main
      3. git pull origin main
      4. npm install --include=dev
      5. npm run build
  → spawnGitRestart():
      - detect systemd service from /proc/self/cgroup
      - systemctl restart hermes-webui (or hermes-web-ui)
      - fallback: spawn-restart if not under systemd

Test Plan

  • isGitCloneDeployment() returns true when .git exists, false in Docker and npm installs
  • Health endpoint returns is_git_clone: true for git-clone deploys
  • Update check via git fetch correctly detects newer versions on origin/main
  • handleUpdate on git-clone deploy runs git pull + npm install + npm run build
  • After build, server restarts via systemctl restart when under systemd
  • After restart, health endpoint reports the new version
  • Non-git-clone deploys (npm global) still use the original npm install -g path
  • Docker deploys still show the "use docker pull" message

The old upgrade.sh killed the server process and started a new one
with nohup. When the Web UI is managed by systemd with Restart=always,
killing the process causes systemd to immediately restart the old
version while the new nohup process fights for the same port.

Fix:
- Detect systemd service name and use systemctl restart instead
- Keep a non-systemd fallback (kill + nohup) for bare-metal deploys
- Stash local changes before git pull to avoid merge failures
- Add automatic rollback on build/start failure
- Derive WEBUI_DIR from script location instead of hardcoding
The Web UI update button only worked for npm global install deployments
(npm install -g hermes-web-ui@latest). Users running from a git clone
with systemd could not upgrade from the page — clicking update either
silently updated the wrong npm package or did nothing useful.

Changes:
- health.ts: detect git-clone deployment by checking for .git directory,
  check for updates via git fetch + git show origin/main:package.json
  instead of npm registry. Expose is_git_clone in health response.
- update.ts: add git-clone upgrade path in handleUpdate that runs
  git stash, git pull, npm install, npm run build, then restarts via
  systemctl (when running under systemd) or falls back to spawn-restart.
- system.ts: add is_git_clone field to HealthResponse type.

The npm global install path is preserved as fallback for non-git deploys.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant