Installer et packager des électrons (partie 2)

Retour !

Lors de ma dernière tentative, j’étais resté sur ma faim car je n’arrivais pas à builder le setup Windows sous Linux. De plus, je n’avais pas géré les mises à jour qui sont normalement une fonctionnalité de base d’Electron… Donc retour !

Remonter le fil !

LaunchFox

En me baladant sur les internets, j’étais tombé sur ce site LaunchFox. Sans creuser d’avantages, je m’étais noté de regarder car le projet toolkit + la possibilité de publication me tentait bien. Bon après quelques lectures du site, je me suis rendu compte que ce n’était pas encore en production … Par contre, cela m’a permis de regarder electron-toolkit.

Electron-toolkit

Il s’agit d’une application Electron dont le but semble d’aider dans la partie build ce qui est une bonne idée. Malheureusement après quelques tests, je me suis rendu compte que l’application était limitée pour le moment :

  • Pas de logs en cas d’erreur,
  • Conserve bien les paramètres dans le package.json mais ne s’en ressert pas …
    • Par contre, la documentation indique que le projet utilise electron-builder qui semble être un concurrent de electron-packager et que j’avais déjà croisé au moment de ma première tentative.

      Je n’avais pas creusé car je trouvais la documentation pas claire et complexe comparée à electron-packager …

      AutoUpdate

      Documentation officielle

      Après cette première piste, je suis revenu à l’auto-update en partant de la documentation officielle. Pour le coup, la documentation est assez clair. Plusieurs solutions sont proposées mais elles ont toutes un point commun (sauf erreur de ma part) : il faut un serveur applicatif ou un compte GitHub.

      Dans mon cas, la deuxième n’est pas envisageable et la deuxième m’embête un peu … et c’est là que suis tombé sur ce projet electron-simple-updater. La promesse : il suffit d’un fichier placé sur un espace pour que les mises à jour fonctionnent. Et cela m’arrangerait bien.

      Et devinez avec qui il est en relation : electron-builder ! Bref, faut que j’y passe !

      Electron-Builder

      Installation

      Comme d’habitude : npm install electron-builder --save-dev

      Configuration

      Après quelques tâtonnements, je suis parvenu à cette configuration :

      
          "build": {
              "appId": "[APP_ID]"
              , "copyright": "Moi@2018
              , "productName": "productName"
              , "asar": true
              ,"appImage": {
                  "systemIntegration": "doNotAsk"
              },
              "files": [
                  "!publisher.json",
                  "!README.md",
                  "!updates.json",
                  "!release-builds/**/*"
              ],
              "linux": {
                  "category": "Utils"
              },
              "win": {
                  "target": "squirrel"
              },
              "squirrelWindows": {
                  "iconUrl": "[URL]"
              }
      

      En fait, en prenant le temps, la documentation plus les projets exemples permettent de s’en sortir.

      Build

      La commande est simple "dist":"./node_modules/.bin/electron-builder -lw" . Par défaut, il ne réalise l’action que pour la plateforme utilisée. Il faut penser à ajouter -w (windows) ou -m (mac) si on est sous linux. Dans mon cas, cela donne -lw (linux + windows).

      Alors forcément, c’est là que les ennuis commencent … Enfin pour Windows car Linux, aucun souci ! Et finalement, je suis retombé sur le même problème que la dernière fois: il manque des dépendances …

      PAF dans la gueule !

      J’ai continué à lire la documentation et je suis tombé sur cette page : ici. Et là: PAF dans la gueule ! DOCKER !!! Mais oui bien sûr. Je l’utilise tous les jours et en plus ici, ils fournissent des images.

      Souci de timezone

      Avec la commande fournie, j’ai quand même un souci : Could not find file "/etc/localtime". Il s’agit d’un bug connu de mono (nécessaire pour le build pour Windows) mais qui n’est pas corrigé dans la version de l’image fournie. Pas grave, il suffit de changer la commande en ajoutant un paramètre :

      
      docker run --rm -ti  --env-file <(env | grep -iE 'DEBUG|NODE_|ELECTRON_|YARN_|NPM_|CI|CIRCLE|TRAVIS_TAG|TRAVIS|TRAVIS_REPO_|TRAVIS_BUILD_|TRAVIS_BRANCH|TRAVIS_PULL_REQUEST_|APPVEYOR_|CSC_|GH_|GITHUB_|BT_|AWS_|STRIP|BUILD_')  --env ELECTRON_CACHE="/root/.cache/electron"  --env ELECTRON_BUILDER_CACHE="/root/.cache/electron-builder"  -v ${PWD}:/project  -v ${PWD##*/}-node-modules:/project/node_modules  -v ~/.cache/electron:/root/.cache/electron  -v ~/.cache/electron-builder:/root/.cache/electron-builder -v /etc/localtime:/etc/localtime electronuserland/builder:wine-mono /bin/bash -c "npm run dist"
      

      Le build fonctionne mais …

      Mais pas l’installer : « This a dummy update.exe […] ». Qwant n’étant pas si mal que cela, j’ai trouvé UNE information mais c’était la bonne. Il fallait nettoyer le répertoire nodes_modules : et pour le coup ça marche !

      Electron-simple-updater

      Alors en fait

      Je vais commencer par un autre package : electron-simple-publisher. Ce package doit permettre de publier et mettre à jour le fichier de release qui est utilisé par electron-simple-updated.

      Vous reprendrez bien du NPM

      npm install --save-dev electron-simple-publisher

      Configuration

      Ayant un FTP sous la main, je vais l’utiliser. J’ai crée (comme demandé), un fichier publisher.json reprennant l’exemple ici.

      La commande

      node_modules/.bin/publish all

      Le all est présent car défaut, il ne publie que celui de la plateforme en cours (c’est un peu une manie).

      Modification

      On fait comme il demande :

      
      // [...]
      const updater = require('electron-simple-updater
      // [...]
      // Gestion de la mise à jour
      updater.init();
      

      Le chemin vers le fichier update.json (qui gère les versions) est directement dans le package.json.

      Test !

      Et bien çà marche !

      Le test :

      • Installation de la version 1.0.1 manuellement sur un poste Windows,
      • Génération et publication de la version 1.0.2,
      • Relance de l’application –> constat que la version 1.0.2 est bien là
      • Relance de l’application –> c’est la version 1.0.2.

      Suite ?

      Il faut que je trouve un moyen d’éviter les relances …

      Bilan

      Je builde et publie depuis Linux une application Electron qui tourne sous Windows ! Bref, ça marche !

      D’ailleurs pour une fois, j’ai presque pas eu de soucis entre la documentation et l’action. Cela explique peut-être le résultat 🙂

Installer et packager des électrons !

Introduction

Après une nouvelle période d’absence (été, projets), je reprends les jours R&D pour la rentrée ! Premier sujet de cette nouvelle: générer un installeur windows pour une application Electron.

Premiers pas

Electron Installer

Après une rapide recherche, je suis tombé sur plusieurs articles qui pointaient vers le même projet : electron-winstaller donc je pense que je vais regarder par là. Première chose : le projet utilise Squirrel. Mais c’est quoi donc Squirrel ?

Squirrel

Le titre du projet est assez évocateur : « Squirrel, It’s like ClickOne but Works » … Le but est de créer des installeur pour windows (IOs aussi). Le projet et sa documentation cible très clairement les applications .Net et utilise le système de package associé « NuGet ». Le système propose des mécanismes de mises à jour en arrière plan ce qui peut-être pratique !

J’essaye !

Package

Le projet utilisé pour test est une reprise et j’avais oublié qu’il n’avait pas de package … donc il faut commencer par remettre en place la possibilité de packager car c’est un prérequis

  • Installation du packager: npm install -g electron-packager,
  • Version Linux : electron-packager . teamweather --platform=linux --arch=x64 --out=release-builds --prune=true --overwrite
  • Version Windows : electron-packager . teamweather --platform=win32 --arch=x64 --out=release-builds --prune=true --overwrite

Le package ne pose aucun souci … pas une erreur rien. C’est louche mais ca marche

Installer

Script

La documentation décrit le code qu’il faut utiliser. Personnellement, j’ai suivi le conseil d’un des articles et j’ai externalisé le code dans une commande. Voici le code (qui est très proche de celui présent dans les articles …) :


// Dépendandes
const createWindowsInstaller = require('electron-winstaller').createWindowsInstaller
const path = require('path')

// Appel de la fonction
getInstallerConfig()
  .then(createWindowsInstaller)
  .catch((error) => {
    console.error(error.message || error)
    process.exit(1)
  })

  // La fonction de build
function getInstallerConfig () {
  // un petit log
  console.log('creating windows installer')
  // Point de départ
  const rootPath = path.join('./')
  // Sortie
  const outPath = path.join(rootPath, 'release-builds')

  // Action !!!
  return Promise.resolve({
    appDirectory: path.join(outPath, 'teamweather-win32-x64/'), // Là où est la version packagé
    authors: 'TeamWeather Team', // L'auteur
    noMsi: true,
    outputDirectory: path.join(outPath, 'windows-installer'), // Là où sera déposé le package
    exe: 'teamweather.exe', // l'exec
    setupExe: 'TeamWeatherAppInstaller.exe' // le nom du setup
  })
}

Pour builder, il suffit alors de lancer la commande : node installers/windows/createinstaller.js

Build

Alors ... comment dire que j'ai galéré. En même temps, c'est ma faute : j'étais sous Linux pour un installer Windows. J'ai essayé d'installer des éléments manquants (Mono) mais c'était jamais la bonne version ou je prennais le risque de casser ma distrib. Totale, je suis passer sous Windows et 5 minutes c'était réglé ... :

npm install --save-dev electron-winstaller
node installers/windows/createinstaller.js

Voilà !

Actions avant / après

Comme indiqué dans la documentation, il est possible de réaliser des commandes en mode "installation/désinstallation". Par exemple, après l'installation, enregistrer une clé de registre. Je n'ai pas eu le temps de pousser cette partie en raison des soucis de build mais le principe est assez simple

.

Suite à une action "setup", l'executable principale est appelée avec un paramètre du type '--squirrel-install'. Il faut donc détecter le paramètre et réaliser les actions que l'on souhaite en fonction du paramètre. Voici deux exemples :


case '--squirrel-install':
case '--squirrel-updated':
                // Ajout d'un raccourci
                spawnUpdate(['--createShortcut', exeName]);
                setTimeout(app.quit, 1000);
                return true;
case '--squirrel-uninstall':
                // Suppression du raccourci
                spawnUpdate(['--removeShortcut', exeName]);
                setTimeout(app.quit, 1000);
                return true;

Un point important : il faut que les traitements soient rapides ! En effet, Squirrel car couper l'application au bout d'une seconde ... Pas le temps de traîner !

Bilan

J'ai bien un installer mais j'ai pu regarder les mises à jour ... J'aurais pas du insister à vouloir builder un package windows sous linux ... Ce sera pour un autre demain.

Liens

Quelques liens :