mirror of
https://github.com/The-Low-Code-Foundation/OpenNoodl.git
synced 2026-01-11 23:02:56 +01:00
359 lines
11 KiB
Markdown
359 lines
11 KiB
Markdown
# Task 7.3: Configure Auto-Update Publishing
|
|
|
|
## Overview
|
|
|
|
Connect the existing auto-update infrastructure to GitHub Releases so users receive update notifications without manual downloads.
|
|
|
|
## What Already Exists
|
|
|
|
The codebase already has:
|
|
1. **electron-updater** - Installed and configured in `autoupdater.js`
|
|
2. **Update UI** - TitleBar shows "Update Available" state
|
|
3. **Confirmation Dialog** - Asks user to restart
|
|
4. **IPC Handlers** - Communication between main and renderer
|
|
|
|
What's missing: **The publish URL configuration**.
|
|
|
|
## How Auto-Update Works
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────┐
|
|
│ Auto-Update Flow │
|
|
├─────────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ 1. App Starts │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ 2. Check GitHub Releases for latest-{platform}.yml │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ 3. Compare versions (semver) │
|
|
│ │ │
|
|
│ ├─── Same version ──► Do nothing, check again in 60s │
|
|
│ │ │
|
|
│ └─── New version ──► Download in background │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ 4. Download complete ──► Show "Update Available" in TitleBar │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ 5. User clicks ──► Show confirmation dialog │
|
|
│ │ │
|
|
│ ├─── "Later" ──► Dismiss │
|
|
│ │ │
|
|
│ └─── "Restart" ──► quitAndInstall() │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ 6. App restarts with new version │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## Implementation
|
|
|
|
### Step 1: Add Publish Configuration
|
|
|
|
**`packages/noodl-editor/package.json`**
|
|
|
|
```json
|
|
{
|
|
"build": {
|
|
"publish": {
|
|
"provider": "github",
|
|
"owner": "the-low-code-foundation",
|
|
"repo": "opennoodl",
|
|
"releaseType": "release"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**Configuration Options:**
|
|
|
|
| Setting | Value | Description |
|
|
|---------|-------|-------------|
|
|
| `provider` | `"github"` | Use GitHub Releases |
|
|
| `owner` | `"the-low-code-foundation"` | GitHub org/user |
|
|
| `repo` | `"opennoodl"` | Repository name |
|
|
| `releaseType` | `"release"` | Only stable releases (not drafts/prereleases) |
|
|
|
|
### Step 2: Update autoupdater.js
|
|
|
|
**`packages/noodl-editor/src/main/src/autoupdater.js`**
|
|
|
|
```javascript
|
|
const { app, ipcMain } = require('electron');
|
|
const { autoUpdater } = require('electron-updater');
|
|
const log = require('electron-log');
|
|
|
|
// Configure logging
|
|
autoUpdater.logger = log;
|
|
autoUpdater.logger.transports.file.level = 'info';
|
|
|
|
// Disable auto-download so user can choose
|
|
autoUpdater.autoDownload = false;
|
|
|
|
function setupAutoUpdate(window) {
|
|
// Skip in dev mode
|
|
if (process.env.devMode === 'true' || process.env.autoUpdate === 'no') {
|
|
log.info('Auto-update disabled in dev mode');
|
|
return;
|
|
}
|
|
|
|
// Linux: Only AppImage supports auto-update
|
|
if (process.platform === 'linux' && !process.env.APPIMAGE) {
|
|
log.info('Auto-update only available for AppImage on Linux');
|
|
return;
|
|
}
|
|
|
|
// Check for updates on startup
|
|
checkForUpdates();
|
|
|
|
// Check periodically (every 60 seconds)
|
|
setInterval(checkForUpdates, 60 * 1000);
|
|
|
|
function checkForUpdates() {
|
|
log.info('Checking for updates...');
|
|
autoUpdater.checkForUpdates().catch((err) => {
|
|
log.error('Update check failed:', err);
|
|
});
|
|
}
|
|
|
|
// Update available - ask user if they want to download
|
|
autoUpdater.on('update-available', (info) => {
|
|
log.info('Update available:', info.version);
|
|
|
|
// Start download automatically (runs in background)
|
|
autoUpdater.downloadUpdate().catch((err) => {
|
|
log.error('Download failed:', err);
|
|
});
|
|
});
|
|
|
|
// No update available
|
|
autoUpdater.on('update-not-available', (info) => {
|
|
log.info('No update available. Current version:', app.getVersion());
|
|
});
|
|
|
|
// Download progress
|
|
autoUpdater.on('download-progress', (progress) => {
|
|
log.info(`Download progress: ${progress.percent.toFixed(1)}%`);
|
|
|
|
// Optionally send to renderer for progress UI
|
|
if (window && !window.isDestroyed()) {
|
|
window.webContents.send('updateDownloadProgress', progress);
|
|
}
|
|
});
|
|
|
|
// Download complete - notify user
|
|
autoUpdater.on('update-downloaded', (info) => {
|
|
log.info('Update downloaded:', info.version);
|
|
|
|
if (window && !window.isDestroyed()) {
|
|
window.webContents.send('showAutoUpdatePopup', {
|
|
version: info.version,
|
|
releaseNotes: info.releaseNotes
|
|
});
|
|
}
|
|
});
|
|
|
|
// Handle user response
|
|
ipcMain.on('autoUpdatePopupClosed', (event, restartNow) => {
|
|
if (restartNow) {
|
|
log.info('User requested restart for update');
|
|
autoUpdater.quitAndInstall(false, true);
|
|
} else {
|
|
log.info('User deferred update');
|
|
}
|
|
});
|
|
|
|
// Error handling
|
|
autoUpdater.on('error', (error) => {
|
|
log.error('Auto-updater error:', error);
|
|
|
|
// Don't spam logs - wait before retrying
|
|
setTimeout(checkForUpdates, 5 * 60 * 1000); // Retry in 5 minutes
|
|
});
|
|
}
|
|
|
|
module.exports = {
|
|
setupAutoUpdate
|
|
};
|
|
```
|
|
|
|
### Step 3: Enhance Update Dialog (Optional)
|
|
|
|
**`packages/noodl-editor/src/editor/src/views/windows/BaseWindow/BaseWindow.tsx`**
|
|
|
|
```typescript
|
|
const [AutoUpdateDialog, autoUpdateConfirmation] = useConfirmationDialog({
|
|
title: 'Update Available',
|
|
message: `Version ${updateInfo?.version || 'new'} is ready to install.
|
|
|
|
Release notes:
|
|
${updateInfo?.releaseNotes || 'Bug fixes and improvements.'}
|
|
|
|
Restart now to update?`,
|
|
confirmButtonLabel: 'Restart Now',
|
|
cancelButtonLabel: 'Later'
|
|
});
|
|
```
|
|
|
|
### Step 4: Update Manifests
|
|
|
|
When you build with `--publish always`, electron-builder creates:
|
|
|
|
**`latest.yml`** (Windows)
|
|
```yaml
|
|
version: 1.2.0
|
|
files:
|
|
- url: Nodegex-Setup-1.2.0.exe
|
|
sha512: abc123...
|
|
size: 85000000
|
|
path: Nodegex-Setup-1.2.0.exe
|
|
sha512: abc123...
|
|
releaseDate: '2024-01-15T10:30:00.000Z'
|
|
```
|
|
|
|
**`latest-mac.yml`** (macOS)
|
|
```yaml
|
|
version: 1.2.0
|
|
files:
|
|
- url: Nodegex-1.2.0-arm64.dmg
|
|
sha512: def456...
|
|
size: 150000000
|
|
- url: Nodegex-1.2.0-x64.dmg
|
|
sha512: ghi789...
|
|
size: 155000000
|
|
path: Nodegex-1.2.0-arm64.dmg
|
|
sha512: def456...
|
|
releaseDate: '2024-01-15T10:30:00.000Z'
|
|
```
|
|
|
|
**`latest-linux.yml`** (Linux)
|
|
```yaml
|
|
version: 1.2.0
|
|
files:
|
|
- url: Nodegex-1.2.0-x64.AppImage
|
|
sha512: jkl012...
|
|
size: 120000000
|
|
path: Nodegex-1.2.0-x64.AppImage
|
|
sha512: jkl012...
|
|
releaseDate: '2024-01-15T10:30:00.000Z'
|
|
```
|
|
|
|
### Step 5: Test Locally
|
|
|
|
**Create a test release:**
|
|
|
|
```bash
|
|
# Build with publish (but don't actually publish)
|
|
cd packages/noodl-editor
|
|
npx electron-builder --mac --publish never
|
|
|
|
# Check generated files
|
|
ls dist/
|
|
# Should include: latest-mac.yml
|
|
```
|
|
|
|
**Test update detection:**
|
|
|
|
```bash
|
|
# 1. Install an older version
|
|
# 2. Create a GitHub Release with newer version
|
|
# 3. Launch old version
|
|
# 4. Watch logs for update detection:
|
|
tail -f ~/Library/Logs/Nodegex/main.log
|
|
```
|
|
|
|
### Step 6: Configure Release Channels (Optional)
|
|
|
|
For beta/alpha testing:
|
|
|
|
```javascript
|
|
// In autoupdater.js
|
|
autoUpdater.channel = 'latest'; // Default
|
|
|
|
// Or allow user to opt into beta:
|
|
autoUpdater.channel = userPreferences.updateChannel || 'latest';
|
|
// Channels: 'latest' (stable), 'beta', 'alpha'
|
|
```
|
|
|
|
electron-builder creates separate manifests:
|
|
- `latest.yml` - Stable releases
|
|
- `beta.yml` - Beta releases
|
|
- `alpha.yml` - Alpha releases
|
|
|
|
## Files to Modify
|
|
|
|
| File | Changes |
|
|
|------|---------|
|
|
| `packages/noodl-editor/package.json` | Add publish configuration |
|
|
| `packages/noodl-editor/src/main/src/autoupdater.js` | Enhance with logging, progress |
|
|
| `packages/noodl-editor/src/editor/src/views/windows/BaseWindow/BaseWindow.tsx` | Optional: Better update dialog |
|
|
|
|
## Testing Checklist
|
|
|
|
### Local Testing
|
|
- [ ] Build produces `latest-*.yml` files
|
|
- [ ] App connects to GitHub Releases API
|
|
- [ ] Update detection works (with test release)
|
|
- [ ] Download progress shown (optional)
|
|
- [ ] "Restart" installs update
|
|
- [ ] "Later" dismisses dialog
|
|
- [ ] App restarts with new version
|
|
|
|
### Platform Testing
|
|
- [ ] macOS Intel: Download correct arch
|
|
- [ ] macOS ARM: Download correct arch
|
|
- [ ] Windows: NSIS installer works
|
|
- [ ] Linux AppImage: Update replaces file
|
|
|
|
### Edge Cases
|
|
- [ ] Offline: Graceful failure, retry later
|
|
- [ ] Partial download: Resume or restart
|
|
- [ ] Corrupted download: SHA512 check fails, retry
|
|
- [ ] Downgrade prevention: Don't install older version
|
|
|
|
## Troubleshooting
|
|
|
|
### Update not detected
|
|
|
|
Check logs:
|
|
```bash
|
|
# macOS
|
|
cat ~/Library/Logs/Nodegex/main.log
|
|
|
|
# Windows
|
|
type %USERPROFILE%\AppData\Roaming\Nodegex\logs\main.log
|
|
|
|
# Linux
|
|
cat ~/.config/Nodegex/logs/main.log
|
|
```
|
|
|
|
### Wrong architecture downloaded
|
|
|
|
Verify `latest-mac.yml` has both arch entries and correct `sha512` values.
|
|
|
|
### "Cannot find latest.yml"
|
|
|
|
Either:
|
|
1. Build wasn't published to GitHub Releases
|
|
2. Release is still in draft mode
|
|
3. Network/proxy issues
|
|
|
|
### Update downloads but doesn't install
|
|
|
|
Check:
|
|
1. SHA512 mismatch (corrupted download)
|
|
2. Disk space
|
|
3. Permissions (can write to app directory)
|
|
|
|
## Success Criteria
|
|
|
|
1. ✅ App checks for updates on startup
|
|
2. ✅ Update notification appears for new releases
|
|
3. ✅ Background download doesn't interrupt work
|
|
4. ✅ Restart installs update seamlessly
|
|
5. ✅ User data preserved after update
|
|
6. ✅ Works on all three platforms
|