Actualización de aplicaciones
Hay varias maneras de proporcionar actualizaciones automáticas a tu aplicación de Electron. The easiest and officially supported one is taking advantage of the built-in Squirrel framework and Electron's autoUpdater module.
Using cloud object storage (serverless)
For a simple serverless update flow, Electron's autoUpdater module can check if updates are available by pointing to a static storage URL containing latest release metadata.
When a new release is available, this metadata needs to be published to cloud storage alongside the release itself. The metadata format is different for macOS and Windows.
Publishing release metadata
With Electron Forge, you can set up static file storage updates by publishing metadata artifacts from the ZIP Maker (macOS) with macUpdateManifestBaseUrl
and the Squirrel.Windows Maker (Windows) with remoteReleases
.
See Forge's Auto updating from S3 guide for an end-to-end example.
Manual publishing
On macOS, Squirrel.Mac can receive updates by reading a releases.json
file with the following JSON format:
{
"currentRelease": "1.2.3",
"releases": [
{
"version": "1.2.1",
"updateTo": {
"version": "1.2.1",
"pub_date": "2023-09-18T12:29:53+01:00",
"notes": "Theses are some release notes innit",
"name": "1.2.1",
"url": "https://mycompany.example.com/myapp/releases/myrelease"
}
},
{
"version": "1.2.3",
"updateTo": {
"version": "1.2.3",
"pub_date": "2024-09-18T12:29:53+01:00",
"notes": "Theses are some more release notes innit",
"name": "1.2.3",
"url": "https://mycompany.example.com/myapp/releases/myrelease3"
}
}
]
}
On Windows, Squirrel.Windows can receive updates by reading from the RELEASES file generated during the build process. This file details the .nupkg
delta package to update to.
B0892F3C7AC91D72A6271FF36905FEF8FE993520 electron-fiddle-0.36.3-full.nupkg 103298365
These files should live in the same directory as your release, under a folder structure that is aware of your app's platform and architecture.
Por ejemplo:
my-app-updates/
├─ darwin/
│ ├─ x64/
│ │ ├─ my-app-1.0.0-darwin-x64.zip
│ │ ├─ my-app-1.1.0-darwin-x64.zip
│ │ ├─ RELEASES.json
│ ├─ arm64/
│ │ ├─ my-app-1.0.0-darwin-arm64.zip
│ │ ├─ my-app-1.1.0-darwin-arm64.zip
│ │ ├─ RELEASES.json
├─ win32/
│ ├─ x64/
│ │ ├─ my-app-1.0.0-win32-x64.exe
│ │ ├─ my-app-1.0.0-win32-x64.nupkg
│ │ ├─ my-app-1.1.0-win32-x64.exe
│ │ ├─ my-app-1.1.0-win32-x64.nupkg
│ │ ├─ RELEASES
Reading release metadata
The easiest way to consume metadata is by installing update-electron-app, a drop-in Node.js module that sets up autoUpdater and prompts the user with a native dialog.
For static storage updates, point the updateSource.baseUrl
parameter to the directory containing your release metadata files.
const { updateElectronApp, UpdateSourceType } = require('update-electron-app')
updateElectronApp({
updateSource: {
type: UpdateSourceType.StaticStorage,
baseUrl: `https://my-bucket.s3.amazonaws.com/my-app-updates/${process.platform}/${process.arch}`
}
})
Usando update.electronjs.org
El equipo de Electron mantiene update.electronjs.org, un webservice gratis y open-source que las aplicaciones Electron puede usar para auto-actualizarse. El servicio está diseñado para aplicaciones de Electron que cumplen con los siguientes criterios:
- Aplicaciones que se ejecuten en macOS o Windows
- La Aplicación tiene un repositorio público en GitHub
- Todas las compilaciones se publicarán en GitHub Releases
- Builds are code-signed (macOS only)
La forma más fácil de usar este servicio es instalando update-electron-app, un módulo de Node.js preconfigurado para usarse con update.electronjs.org.
Instale el módulo usando su gestor de paquetes Node.js de su elección:
- npm
- Yarn
npm install update-electron-app
yarn add update-electron-app
Y entonces, llame a updater desde su archivo principal de ejecución:
require('update-electron-app')()
De manera predeterminada, este módulo verificará si existen actualizaciones en el inicio de la aplicación y luego cada diez minutos. Cuando se encuentra una actualización, esta se descargará automáticamente en segundo plano. Cuando se completa la descarga, se muestra un cuadro de diálogo que le permite al usuario reiniciar su aplicación.
Si necesita personalizar su configuración, puedes pasar opciones a update-electron-app o usa el servicio de actualización directamente.
Usando otros servicios de actualización
Si está desarrollando una aplicación privada de Electrón, o si no está publicando lanzamientos en GitHub, tal vez pueda considerar poseer su propio servidor de actualizaciones.
Paso 1: Desplegando un servidor de actualizaciones
Dependiendo de sus necesidades, puede escoger una de esta:
- Hazel – Servidor de actualizaciones para aplicaciones privadas o de código abierto que pueden ser desplegadas de forma gratuita mediante Vercel. Es tomado de los Lanzamientos de GitHub y aprovecha al maximo el poder de las CDN's de GitHub.
- Nuts – También usa los Lanzamientos de GitHub, pero almacena la aplicación, actualiza en el Disco Duro y también soporta repositorios privados.
- electron-release-server – proporciona un panel para administrar los lanzamientos y no es necesarios que los lanzamientos se originen desde GitHub.
- Nucleus – Un servidor de actualizaciones completo para aplicaciones de Electrón y es mantenido gracias a Atlassian. Soporta múltiples aplicaciones y canales, y utiliza un almacén de archivos estáticos para minimizar el coste del servidor.
Una vez que hayas desplegado tu servidor de actualizaciones, puedes instrumentar tu código de aplicación para recibir y aplicar las actualizaciones con el módulo autoUpdater de Electron.
Paso 2: Recibiendo actualizaciones en tu aplicación
Primero, importe los módulos requeridos en su código principal. El siguiente código podría variar para diferentes software para servidores, pero funciona como se describe cuando se utiliza Hazel.
Por favor, asegúrese de que el código de abajo sólo se ejecutará en su aplicación empaquetada, y no en desarrollo. You can use the app.isPackaged API to check the environment.
const { app, autoUpdater, dialog } = require('electron')
Next, construct the URL of the update server feed and tell autoUpdater about it:
const server = 'https://your-deployment-url.com'
const url = `${server}/update/${process.platform}/${app.getVersion()}`
autoUpdater.setFeedURL({ url })
Como este paso final, compruebe si hay actualizaciones. El siguiente ejemplo comprobará cada minuto:
setInterval(() => {
autoUpdater.checkForUpdates()
}, 60000)
Once your application is packaged, it will receive an update for each new GitHub Release that you publish.
Paso 3: Notificar a los usuarios cuando haya actualizaciones disponibles
Ahora que ha configurado el mecanismo de actualización básico para su aplicación, debe asegurarse de que el usuario reciba una notificación cuando haya una actualización. This can be achieved using the autoUpdater API events:
autoUpdater.on('update-downloaded', (event, releaseNotes, releaseName) => {
const dialogOpts = {
type: 'info',
buttons: ['Restart', 'Later'],
title: 'Application Update',
message: process.platform === 'win32' ? releaseNotes : releaseName,
detail:
'Una nueva versión ha sido descargada. Restart the application to apply the updates.'
}
dialog.showMessageBox(dialogOpts).then((returnValue) => {
if (returnValue.response === 0) autoUpdater.quitAndInstall()
})
})
Also make sure that errors are being handled. Aquí hay un ejemplo para registrarlos en stderr
:
autoUpdater.on('error', (message) => {
console.error('There was a problem updating the application')
console.error(message)
})
Debido a que las peticiones realizadas por autoUpdate no están bajo su control directo, puede encontrar situaciones que son difíciles de manejar (como si el servidor de actualizaciones cuenta con sistema de autenticación). El campo de la url
soporta el protocolo file://
, lo que significa que con un poco de esfuerzo, puede evitar el aspecto del proceso de comunicación con el servidor cargando su actualización desde un directorio local. Aquí hay un ejemplo de cómo podría funcionar esto.
Update server specification
For advanced deployment needs, you can also roll out your own Squirrel-compatible update server. For example, you may want to have percentage-based rollouts, distribute your app through separate release channels, or put your update server behind an authentication check.
Squirrel.Windows and Squirrel.Mac clients require different response formats, but you can use a single server for both platforms by sending requests to different endpoints depending on the value of process.platform
.
const { app, autoUpdater } = require('electron')
const server = 'https://your-deployment-url.com'
// e.g. for Windows and app version 1.2.3
// https://your-deployment-url.com/update/win32/1.2.3
const url = `${server}/update/${process.platform}/${app.getVersion()}`
autoUpdater.setFeedURL({ url })
Windows
A Squirrel.Windows client expects the update server to return the RELEASES
artifact of the latest available build at the /RELEASES
subpath of your endpoint.
For example, if your feed URL is https://your-deployment-url.com/update/win32/1.2.3
, then the https://your-deployment-url.com/update/win32/1.2.3/RELEASES
endpoint should return the contents of the RELEASES
artifact of the version you want to serve.
B0892F3C7AC91D72A6271FF36905FEF8FE993520 https://your-static.storage/your-app-1.2.3-full.nupkg 103298365
Squirrel.Windows does the comparison check to see if the current app should update to the version returned in RELEASES
, so you should return a response even when no update is available.
macOS
When an update is available, the Squirrel.Mac client expects a JSON response at the feed URL's endpoint. This object has a mandatory url
property that maps to a ZIP archive of the app update. All other properties in the object are optional.
{
"url": "https://your-static.storage/your-app-1.2.3-darwin.zip",
"name": "1.2.3",
"notes": "Theses are some release notes innit",
"pub_date": "2024-09-18T12:29:53+01:00"
}
If no update is available, the server should return a 204 No Content
HTTP response.