Skip to content

feat: add mock update server#1180

Merged
juliusmarminge merged 10 commits intopingdotgg:mainfrom
nmggithub:mock-update-server
Mar 28, 2026
Merged

feat: add mock update server#1180
juliusmarminge merged 10 commits intopingdotgg:mainfrom
nmggithub:mock-update-server

Conversation

@nmggithub
Copy link
Copy Markdown
Contributor

@nmggithub nmggithub commented Mar 18, 2026

What Changed

cc @juliusmarminge

This adds a simple mock update server to our setup. There are several ways to use it, docs can be added if desired.

Here are the basics:

  1. bun run start:mock-update-server starts the mock update server. By default, it serves on localhost:3000 and out of ./release-mock at the project root. Both are configurable.
  2. build-desktop-artifact.ts has two more options: (a) wether or not to build with mock updates, and (b) if so, which port to use. These options control two things: (c) wether or not to output to ./release-mock over ./release (the default) and (d) the manifest URL built into the built Electron app.
  3. The same two options above are configurable at runtime on any Electron build.

When used normally, this functionality should work fine. However, users should be aware of the manifest URL's they cause to be built into the app and/or use runtime options to ensure they spin up the mock update server on the right port. Additionally, app artifacts must be signed for a full end-to-end update test to work.

This also includes a minor fix to our update state machine by adding an "in flight" status.

Why

This will help us when testing the update mechanisms.

Adding the "in flight" status also makes our state machine more correct.

UI Changes

N/A

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Note

Add mock update server for local desktop auto-update testing

  • Adds scripts/mock-update-server.ts, a Bun-based static file server that serves update artifacts from release-mock/ on a configurable localhost port.
  • Adds --mock-updates and --mock-update-server-port flags to scripts/build-desktop-artifact.ts, directing build output to release-mock/ and configuring the generic update provider to point at the local server.
  • When T3CODE_DESKTOP_MOCK_UPDATES is set, the app's autoUpdater feed URL is pointed at the local mock server instead of GitHub.
  • Tracks install-in-flight state (updateInstallInFlight) in apps/desktop/src/main.ts so that errors during quitAndInstall are surfaced as install failures rather than generic updater errors.
  • Fixes shouldToastDesktopUpdateActionResult in apps/web/src/components/desktopUpdate.logic.ts to only show a toast when there is an actionable error, not on every accepted-but-incomplete result.

Macroscope summarized 907c8d9.


Note

Medium Risk
Touches desktop auto-update install/error handling and build-time publish configuration; misconfiguration could break update flows or point builds at the wrong feed URL.

Overview
Adds a Bun-based local mock update server (scripts/mock-update-server.ts) plus a start:mock-update-server script, and ignores the new release-mock/ artifact directory.

Extends the desktop artifact build pipeline (build-desktop-artifact.ts) with --mock-updates / --mock-update-server-port (and env equivalents) to output to release-mock/ and embed a local generic publish/feed URL for update testing.

Updates the Electron updater runtime to optionally use the mock feed (T3CODE_DESKTOP_MOCK_UPDATES), improves install flow tracking via updateInstallInFlight (treating quitAndInstall() as async and handling install-time updater errors), and tightens web UI toast logic to only notify when an actionable update error message exists.

Written by Cursor Bugbot for commit 907c8d9. This will update automatically on new commits. Configure here.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 18, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3771f9ef-f5d8-4370-962a-d6c51e42c1e6

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added size:M 30-99 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. labels Mar 18, 2026
@nmggithub nmggithub force-pushed the mock-update-server branch from 214bf71 to 7f0c421 Compare March 18, 2026 01:16
@github-actions github-actions bot added size:L 100-499 changed lines (additions + deletions). and removed size:M 30-99 changed lines (additions + deletions). labels Mar 18, 2026
Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

provider: "generic",
url: `http://localhost:${mockUpdateServerPort ?? 3000}`,
},
];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mock updates config ignored when GitHub config exists

Medium Severity

At build time, the else if means mockUpdates is silently ignored whenever resolveGitHubPublishConfig() returns a config (e.g. when GITHUB_REPOSITORY is set). At runtime in configureAutoUpdater, mock updates correctly override GitHub by running after the GitHub setFeedURL call. This inconsistency means a build with --mock-updates can produce an app-update.yml pointing to GitHub instead of localhost, contradicting the PR's stated intent that the flag controls "the manifest URL built into the built Electron app."

Additional Locations (1)
Fix in Cursor Fix in Web

Copy link
Copy Markdown
Contributor Author

@nmggithub nmggithub Mar 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existence of a GitHub publish config and a mock update path are mutually exclusive. This is desired behavior. This conflict would only happen if someone were to pass --mock-updates and supply a GITHUB_REPOSITORY value, which is not a sane, normal, or expected use of the packaging script.


function isWithinRoot(filePath: string): boolean {
try {
return !relative(realpathSync(root), realpathSync(filePath)).startsWith(".");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Path containment check incorrectly blocks dotfiles

Low Severity

The isWithinRoot check uses startsWith(".") on the relative() result, which rejects both .. parent-traversal paths and legitimate dotfiles at the root level (e.g., .gitkeep). A file like root/.something produces a relative path of ".something" which starts with "." and gets rejected. The check needs startsWith("..") instead to only block directory traversal while allowing dotfiles.

Fix in Cursor Fix in Web

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The update server does not make use of dotfiles. This should be fine.

provider: "generic",
url: `http://localhost:${process.env.T3CODE_DESKTOP_MOCK_UPDATE_SERVER_PORT ?? 3000}`,
});
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Truthy env check enables mock updates with "false"

Medium Severity

The runtime check process.env.T3CODE_DESKTOP_MOCK_UPDATES is a truthy check, so setting it to "false" or "0" still enables mock updates, redirecting the auto-updater to a localhost server that likely isn't running. This silently breaks update checks. The codebase already uses strict comparison for similar env vars (e.g., T3CODE_DISABLE_AUTO_UPDATE === "1"), and the build-time counterpart uses Config.boolean which correctly parses "false" as false.

Fix in Cursor Fix in Web

Copy link
Copy Markdown
Contributor Author

@nmggithub nmggithub Mar 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is expected behavior. Mock updates are opt-in, so passing T3CODE_DESKTOP_MOCK_UPDATES=false is not a sane, normal, or expected use of the packaging script.

@juliusmarminge juliusmarminge merged commit f4617e7 into pingdotgg:main Mar 28, 2026
10 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants