Saltar al contenido principal

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:

releases.json
{
"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.

RELEASES
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.

main.js
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 install update-electron-app

Y entonces, llame a updater desde su archivo principal de ejecución:

main.js
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.

Compruebe su entorno de ejecución!

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.

main.js
const { app, autoUpdater, dialog } = require('electron')

Next, construct the URL of the update server feed and tell autoUpdater about it:

main.js
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:

main.js
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:

main.js
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:

main.js
autoUpdater.on('error', (message) => {
console.error('There was a problem updating the application')
console.error(message)
})
Administrando actualizaciones manualmente

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.

main.js
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.

https://your-deployment-url.com/update/win32/1.2.3/RELEASES
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.

https://your-deployment-url.com/update/darwin/0.31.0
{
"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.