Skip to content

Add release packaging and Pear install site#3

Closed
willwashburn wants to merge 3 commits into
mainfrom
codex/release-autoupdate
Closed

Add release packaging and Pear install site#3
willwashburn wants to merge 3 commits into
mainfrom
codex/release-autoupdate

Conversation

@willwashburn

Copy link
Copy Markdown
Member

Summary

  • add electron-builder packaging config and GitHub Release publisher workflow
  • add electron-updater launch/manual update checks and packaged broker binary resolution
  • add SST static install site at pear.agentrelay.com with macOS/Linux and Windows bootstrap scripts
  • add SST production/preview deploy workflows and release runbook

Verification

  • npm run build
  • sh -n site/install.sh
  • git diff --check
  • CSC_IDENTITY_AUTO_DISCOVERY=false npm run dist -- --dir
  • npx sst install
  • npx sst diff --stage pr-smoke --print-logs (config evaluated; stopped at missing CLOUDFLARE_API_TOKEN locally)

@coderabbitai

coderabbitai Bot commented May 20, 2026

Copy link
Copy Markdown

Review Change Stack

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: 9020ab52-ca99-40e5-a27e-b45276c33e49

📥 Commits

Reviewing files that changed from the base of the PR and between 75222af and 4ff3358.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (4)
  • .gitignore
  • package.json
  • src/main/broker.ts
  • src/main/index.ts
✅ Files skipped from review due to trivial changes (1)
  • .gitignore

📝 Walkthrough

Walkthrough

Adds CI and release workflows, production and preview SST deploy pipelines with AWS account assertion, an installer landing site with platform installers, electron-builder packaging and release config, and an Electron auto-update module wired into the app.

Changes

Pear Distribution & Deployment System

Layer / File(s) Summary
AWS Account Validation & Deployment Workflows
.github/scripts/assert-aws-account.sh, .github/workflows/deploy-site.yml, .github/workflows/preview-site.yml
AWS account ID is validated before deployments via a reusable assertion script. Production deploys run on main pushes to site/config files; PR preview workflow deploys/removes ephemeral SST stages and posts/updates a PR comment with the preview URL.
CI & Release Build System
.github/workflows/ci.yml, .github/workflows/release.yml, package.json, .gitignore
Adds CI to typecheck/build on PRs and a release workflow that builds/publishes installers across macOS (universal), Windows (x64 NSIS), and Linux (AppImage/Deb). package.json adds release/dist scripts, electron-updater dependency, and electron-builder configuration; .gitignore ignores SST/tsbuildinfo.
Electron Auto-Update System
src/main/updater.ts, src/main/index.ts, src/main/broker.ts
New updater module provides checkForUpdates and configureAutoUpdates, schedules periodic checks, prompts users to restart on update, and integrates a manual menu item. Broker binary resolution now handles packaged app bundle paths.
Installer Download & Installation Site
sst.config.ts, site/index.html, site/install.sh, site/install.ps1
SST provisions a static site hosting an install landing page with platform-specific install scripts. Shell installer handles macOS (universal .app) and Linux (AppImage); PowerShell installer handles Windows x64 .exe.
Release Runbook Documentation
docs/release.md
Adds operational release documentation covering packaging, signing secrets, install commands, tagging, and produced artifacts.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 Workflows stitched and scripts in hand,
Pear ships out across the land,
AWS nods the gate,
Auto-updates wait,
Installers hum — deliveries planned! 🍐


Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login.

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

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

View 5 additional findings in Devin Review.

Open in Devin Review

Comment thread src/main/updater.ts
Comment on lines +78 to +94
updater.on('update-downloaded', async (info) => {
console.log(`[updater] Update downloaded: ${info.version}`)
if (mainWindow.isDestroyed()) return

const result = await dialog.showMessageBox(mainWindow, {
type: 'info',
buttons: ['Restart', 'Later'],
defaultId: 0,
cancelId: 1,
message: 'A Pear update is ready to install.',
detail: 'Restart Pear to apply the downloaded update.'
})

if (result.response === 0) {
updater.quitAndInstall()
}
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Stale BrowserWindow reference in updater causes silent update prompt failure on macOS re-activate

configureAutoUpdates at src/main/index.ts:138 captures the initial mainWindow BrowserWindow instance by value into the update-downloaded event handler closure (src/main/updater.ts:78-93). On macOS, when the user closes all windows (the app stays alive per src/main/index.ts:147) and later clicks the dock icon, createWindow() is called at src/main/index.ts:141 creating a new BrowserWindow—but the updater still holds a reference to the old, destroyed window. When an update is downloaded, the mainWindow.isDestroyed() check at line 80 returns true and the handler silently returns, so the user is never prompted to restart and install the update.

Prompt for agents
The configureAutoUpdates function captures the BrowserWindow instance passed at setup time. On macOS, when the user closes the window (app stays alive) and re-opens via dock click, a new BrowserWindow is created but the updater still references the old destroyed one.

Approach 1: Instead of capturing a specific BrowserWindow, resolve the focused/active window at the time the event fires using BrowserWindow.getFocusedWindow() or BrowserWindow.getAllWindows()[0].

Approach 2: Have configureAutoUpdates accept a getter function () => BrowserWindow | null instead of a direct reference, and have the caller pass a function that returns the current mainWindow module variable.

The fix should be applied in src/main/updater.ts in the update-downloaded handler (line 78-94), and potentially the function signature of configureAutoUpdates (line 49). The caller in src/main/index.ts:138 would need to be updated accordingly.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6761d67557

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/main/updater.ts
Comment on lines +80 to +81
if (mainWindow.isDestroyed()) return

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Show update prompt on the current window

configureAutoUpdates captures the first BrowserWindow instance and then never rebinds it (updaterConfigured short-circuits future calls). On macOS, window-all-closed does not quit the app (src/main/index.ts), so if the user closes and reopens the window later, update-downloaded can fire while the captured window is destroyed and return early, which suppresses the restart prompt even though an update is ready.

Useful? React with 👍 / 👎.

@willwashburn

Copy link
Copy Markdown
Member Author

@copilot resolve the merge conflicts in this pull request

Co-authored-by: willwashburn <957608+willwashburn@users.noreply.github.com>

Copilot AI commented May 21, 2026

Copy link
Copy Markdown

@copilot resolve the merge conflicts in this pull request

Resolved and pushed in 4ff3358. I merged main into this branch, resolved the conflicts in package.json and src/main/index.ts, and verified the merged branch with npm ci, npm run build, and git diff --check.

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.

2 participants