mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-24 10:52:21 +00:00
The desktop self-update runs `hermes update` then `hermes desktop --build-only`, and only relaunches if the rebuild returns 0. The first `--build-only` can exit nonzero on a still-settling post-update tree or a network-blocked Electron fetch that the installer's self-heal repaired mid-run — so both updaters (the Tauri setup binary and the in-app POSIX path) bailed before the relaunch step. The update landed but the app never restarted; a manual launch worked because the heal had completed. Retry `--build-only` once in both paths before failing, mirroring the retry-once `hermes update` already does (and the CLI `hermes update`'s own desktop rebuild). A second run builds clean off the healed dist and is a near-no-op when the first actually succeeded (content-hash stamp). - update.rs: retry stage 2; add rebuild_needs_retry() + test - main.cjs: retry via new update-rebuild.cjs helper (behavior-tested)
55 lines
1.9 KiB
JavaScript
55 lines
1.9 KiB
JavaScript
/**
|
|
* Tests for electron/update-rebuild.cjs — the retry-once policy for the desktop
|
|
* `--build-only` rebuild during self-update.
|
|
*
|
|
* Run with: node --test electron/update-rebuild.test.cjs
|
|
* (Wired into npm test:desktop:platforms in package.json.)
|
|
*
|
|
* Why this matters: a first rebuild can return nonzero on a still-settling tree
|
|
* or a self-healed (network-blocked) Electron download. Without a second attempt
|
|
* the updater bails before the relaunch step — the app updates but never restarts
|
|
* (the field report behind this fix). The retry must fire on failure, not on
|
|
* success, and must run at most twice.
|
|
*/
|
|
|
|
const test = require('node:test')
|
|
const assert = require('node:assert/strict')
|
|
|
|
const { shouldRetryRebuild, runRebuildWithRetry } = require('./update-rebuild.cjs')
|
|
|
|
test('shouldRetryRebuild retries only on a non-success exit', () => {
|
|
assert.equal(shouldRetryRebuild(0), false)
|
|
assert.equal(shouldRetryRebuild(1), true)
|
|
assert.equal(shouldRetryRebuild(null), true)
|
|
})
|
|
|
|
test('a clean first rebuild runs once and does not retry', async () => {
|
|
const codes = []
|
|
const result = await runRebuildWithRetry(attempt => {
|
|
codes.push(attempt)
|
|
return Promise.resolve({ code: 0 })
|
|
})
|
|
assert.deepEqual(codes, [0])
|
|
assert.equal(result.code, 0)
|
|
})
|
|
|
|
test('a failed first rebuild retries once and succeeds', async () => {
|
|
const codes = []
|
|
const result = await runRebuildWithRetry(attempt => {
|
|
codes.push(attempt)
|
|
return Promise.resolve({ code: attempt === 0 ? 1 : 0 })
|
|
})
|
|
assert.deepEqual(codes, [0, 1])
|
|
assert.equal(result.code, 0)
|
|
})
|
|
|
|
test('a rebuild that keeps failing runs at most twice and reports the failure', async () => {
|
|
const codes = []
|
|
const result = await runRebuildWithRetry(attempt => {
|
|
codes.push(attempt)
|
|
return Promise.resolve({ code: 1, error: 'rebuild-failed' })
|
|
})
|
|
assert.deepEqual(codes, [0, 1])
|
|
assert.equal(result.code, 1)
|
|
assert.equal(result.error, 'rebuild-failed')
|
|
})
|