Skip to content

v1.7.3 - Emergency Updater Fix

Latest

Choose a tag to compare

@avcode-exe avcode-exe released this 30 Jul 15:45
· 3 commits to main since this release

v1.7.3 β€” Emergency Updater Fix

Release Date: 2026-07-30

🚨 Critical Bug Fixes β€” Updater Broken in v1.7.1/v1.7.2

This is an emergency release that fixes three critical bugs in the auto-update system that prevented users from updating the application. Without this fix, clicking "Restart & Install" after downloading an update would fail.

Bug 1: "Please check update first" (Download Failure)

autoUpdater.downloadUpdate() requires autoUpdater.checkForUpdates() to have been called first to populate internal state. Since the app uses a custom checkForUpdatesDirect() that queries the GitHub Atom feed directly, autoUpdater.checkForUpdates() was never called, and autoUpdater.updateInfoAndProvider was null. Calling autoUpdater.downloadUpdate() would throw:

Error: Please check update first

Fix: Replaced autoUpdater.downloadUpdate() with a manual download implementation using fetch() + Web Streams Reader API. Download progress is tracked via reader.read() loop and reported to the renderer via sendStatus('downloading', { percent }).

Bug 2: 404 Not Found on Download URL

The latest.yml from GitHub releases referenced the asset as Tower-Defense-Setup-1.7.2.exe (hyphens), but the actual GitHub release asset name was Tower.Defense.Setup-1.7.2.exe (dots). This mismatch caused a 404 when attempting to download the installer.

Example from logs:

  • GitHub API asset names: ["latest.yml","Tower.Defense.Setup.1.7.2.exe","Tower.Defense.Setup.1.7.2.exe.blockmap"]
  • latest.yml references: Tower-Defense-Setup-1.7.2.exe (hyphens β€” ❌ 404)

Fix: Added fixAssetNamesInInfo() function that queries the GitHub API (https://api.github.com/repos/avcode-exe/Tower-Defense/releases/tags/vX.Y.Z) at download time to discover the actual asset name. The function replaces the hyphenated name in the update info with the correct dotted name and constructs the full download URL.

Bug 3: "No update filepath provided, can't quit and install" (Install Failure)

autoUpdater.quitAndInstall() failed because the download was performed manually (not via autoUpdater.downloadUpdate()), so autoUpdater had no knowledge of the downloaded file path. The error was:

Error: No update filepath provided, can't quit and install

Fix: Rewrote the restart-to-update IPC handler to:

  1. Check if _downloadedFilePath is set (from the manual download)
  2. Launch the NSIS installer directly via spawn() with { detached: true, shell: true, stdio: 'ignore' } and no /S silent flag β€” so the user can see the installer UI and interact with it
  3. Wait 500ms for the installer to start, then call app.quit() to allow the installer to close the app process for file replacement
  4. Fall back to autoUpdater.quitAndInstall() if _downloadedFilePath is not set (old electron-updater path)

πŸ› οΈ Other Improvements

  • Comprehensive logging: Every step of the update flow (check β†’ download β†’ install) is now logged to both the main process console and relayed to the renderer's DevTools (F12) console via a dedicated update-debug-log IPC channel. Logs appear as [update-main] in the renderer console.
  • Installer visibility: The NSIS installer now runs with a visible UI (no /S silent flag), so users can see installation progress and interact with the standard install dialogs.

πŸ“¦ Download

πŸ§ͺ Testing

  • 1,938 tests passed across 50 test files
  • ESLint: 0 errors, 0 warnings
  • Prettier: All files pass format check

πŸ”§ How to Update

  1. If you are on v1.7.1 or v1.7.2: The update will be automatically detected on startup (if "Check on startup" is enabled in Settings β†’ Update). Click Download, then click Restart & Install. The NSIS installer will appear β€” follow the prompts to complete the installation.
  2. Alternatively, download the installer manually from the links above and run it.

⚠️ Manual Installation Required for v1.7.1/v1.7.2 Users

If you are on v1.7.1 or v1.7.2 and the auto-update does not work (due to the bugs fixed in this release), please download the installer manually and run it to update to v1.7.3. After this update, the auto-update system will work correctly for future releases.


Full Changelog

What's Changed

electron-main.js (major changes):

  • Added import { spawn } from 'child_process' at module top level
  • Added _downloadedFilePath module-level variable to track manually downloaded installer path
  • Rewrote downloadUpdateSafely() as async with manual fetch() + Web Streams Reader download (replacing autoUpdater.downloadUpdate())
  • Added fixAssetNamesInInfo() function to query GitHub API and resolve the actual asset name with dots
  • Rewrote restart-to-update IPC handler to launch the installer directly via spawn() with visible UI and 500ms delay before app.quit()
  • Added comprehensive logUpdate() calls in all IPC handlers, checkForUpdatesDirect(), sendStatus(), shouldAnnounceToUser(), and all autoUpdater.on() event listeners
  • Added UPDATE_DEBUG flag and logUpdate() helper function

src/main.js:

  • Added onUpdateDebugLog relay listener that receives 'update-debug-log' IPC events from electron-main.js and logs them as [update-main] in the renderer DevTools console

preload.cjs:

  • Added onUpdateDebugLog function that exposes the 'update-debug-log' IPC channel to the renderer via contextBridge

src/updateManager.js:

  • Added console.log('[update] renderer: ...') calls in check(), _onStatus(), and download() for all phases: checking, available, downloading, downloaded, error

src/game.js:

  • Version string updated to v1.7.3

src/gamePersistence.js:

  • CURRENT_VERSION updated to '1.7.3'

CHANGELOG.md:

  • Added [1.7.3] entry documenting all three bug fixes and the version bump

PLAN.md:

  • Updated "Current State" version to v1.7.3
  • Updated version table with v1.7.3 emergency entry
  • Shifted future plans: v1.7.3 Audio & Visual β†’ v1.7.4, v1.7.4 Performance β†’ v1.7.5
  • Updated dependency ranges and release counts

Tests (6 files updated):

  • tests/electronMain.test.js: Added child_process mock, updated to async for downloadUpdateSafely, added onUpdateDebugLog to mock electron, updated all version references to 1.7.3
  • tests/helpers.js: Updated game.appVersion and getVersion mock to 1.7.3
  • tests/main.test.js: Updated getAnnouncedVersion, getVersion mock, text content assertions, and describe labels to 1.7.3
  • tests/persistence.test.js: Updated save metadata version, cmp assertions to 1.7.3
  • tests/preload.test.js: Updated mockInvoke mock and expectations to 1.7.3
  • tests/electronMain.test.js: Updated resolveDownloadTag and parseUpdateInfo mocks to 1.7.3

package.json / package-lock.json:

  • Version bumped to 1.7.3