Skip to content

Distributing tC: Package Build Publish

Christopher Klapp edited this page Jul 14, 2017 · 18 revisions

Overview

Distributing an Electron Application such as translationCore via tools, configuration and continuous integration services.

What this covers

This covers what it takes to go from running npm start to being able to download and install the application. This documentation is for tC developers to better understand the process involved.

While these can be complicated steps, a single tool partnered with Continuous Integration services can make this much easier to deal with than using separate tools and scripts.

Steps

  • Package (via electron-forge)
  • Build/Make (via electron-forge)
  • Publish/Release (via continuous integration services)
  • Tag/Version (via script)

Tools

  • electron-forge

Electron-Forge

https://electronforge.io/

Electron-Forge is used bootstrap templated electron apps including react ready ones to help you get started creating an app, including many best practices such as babel, web-pack, es-linters like air-bnb. What it really offers us is abstracting the complicated Packaging and Building processes so that we don't have to.

Electron-Forge Installation

Before you can use the app, you have to make sure Electron-Forge is installed. There is an alias to make sure we are all using the same version of Electron-Forge, and it installs it globally so you can run the CLI.

  • Delete node_modules to be safe and ensure we clean it up.
  • Install Electron-Forge: npm run install-electron-forge
  • Install fresh npm dependencies: npm install

Electron-Forge Configuration

I've prepared a sample electron app using electron-forge that you can browse to see how simple the configuration can be with no scripts. The configuration is basic and can be expanded to cover details such as mac/windows specific icons.

The first section, make_targets, tells the current OS the desired build target. Windows uses Squirrel that generates nice .exe installers. Darwin/OSX/Mac uses a DMG image for installation and compressed images. For Linux we will use DEB packages since that's Ubuntu uses and its the most common Desktop flavor of Linux.

Electron-Forge Scripts

Update package.json scripts for package and make. Due to an issue on Linux where current relative path isn't the default, pass the current relative path to avoid it raising an error that path is undefined.

OS and Architecture

Electron-forge only builds for the OS and Architecture it is run on. While that seems limited at first, we choose to run on continuous integration servers that provide the desired OS builds.

Electron-Forge Packaging

It's as easy as npm run package which via package.json scripts is an alias for electron-forge package. This runs webpack and takes care of es6/babel type stuff behind the scenes so we don't have to, including copying them to a path that is non-destructive and won't be committed to our codebase since our .gitignore file ignores the out folder.

Babel

Electron-Forge is configured to allow babel to happen in production just like it does in development mode with npm start. Keep in mind this means all babel plugins and presets are required to be in dependencies and not dev-dependencies in the package.json.

Node-gyp

When packaging on your local Windows machine, Node-gyp requires python to be installed and may cause issues when packaging.

  • Documented fix: https://github.com/electron-userland/electron-forge/issues/172
  • Right click on PowerShell and run as Admin.
  • Run: npm install --global --production windows-build-tools
  • Run: npm install --global node-gyp
  • Run: setx PYTHON "%USERPROFILE%\.windows-build-tools\python27\python.exe"
  • Ensure to install and use Electron-Forge via PowerShell and not Bash as it thinks the environment is Linux.
  • Ensure to use npm@^5.1.0 as v5 up until that release had a bug in Windows not skipping other OS dependencies.
  • NPM bugfix: https://github.com/npm/npm/pull/17552

Electron-Forge Building/Making

It's as easy as npm run make which via package.json scripts is an alias for electron-forge make. This runs electron-build behind the scenes with many default configurations and scripts for each OS that abstracts the complications. We can configure this via special sections for each OS.

Windows Make via Squirrel Setting

After taking the functioning package from Windows, Electron-Forge Makes an installable executable via Squirrel. Squirrel has a path character limitation of 260 characters. The issue is with the nested dependencies of node_modules folder and it gets pretty deep. This breaks the build and the most common way to address this is by using Asar=true setting in the package step. This makes a virtual file system that works around the limit. Unless we change many of our file references, our App isn't setup to use the virtual file system. The other approach to try is running npm dedupe to flatten the node_modules folder and potentially fix this issue. No successful build has been made for Windows through either method, when it does this will be updated. Dedupe adds considerable amounts of time to the builds both to run dedupe and subsequent package and make steps. Do not do this for Mac builds even if it fixes Windows.

Electron-Forge Publishing/Releasing

We don't use this as we want to let this be done via our continuous integration services.

Continuous Integration

Continuous Integration (CI) allows us to use git hooks to run things like automated tests on our code on their servers and run our package/build/publishing automagically via our configurations.

Continuous Integration Services

  • Travis-CI for Mac/Linux (travis-ci.org)
  • Appveyor for Windows (appveyor.com)

Travis-CI

Travis-CI is the standard in Mac/Linux CI services. Here is a sample .travis.yml configuration file that can run tests and package/build/publish the sample app.

Travis Builds timing out

Travis times out by default after not receiving output for 10 minutes. This can be increased by prepending travis_wait before the command that needs to take up to 20 minutes. If you need more time, add a number afterwards, travis_wait 30 npm run make.

Appveyor

Appveyor is the standard in Windows CI services. Here is a sample appveyor.yml configuration file that can run tests and package/build/publish the sample app.

Headless Testing

Testing on CI servers requires a "headless" virtual display since there is no monitor attached to the servers. Tests will fail to run on Linux/Mac but Windows should be fine.

Deploying/Publishing Artifacts

To Deploy we are using Github personal Access tokens. Before using them they must be encrypted. During encryption, they will only usable for the specified repository. Not updating these values may result in 401 Authentication errors from Github API.

  • Create Github Personal Access Token.
  • Encrypt Access Token with Travis: travis encrypt [paste token].
  • Replace the api.secure value in Travis config with output after removing line breaks.
  • Set/replace the GH_TOKEN environment variable in the settings of Travis to the same encrypted token.

Tag/Version

Before you make a release, the first step is making sure your tests pass and you have a working version of your app. After you are sure you have your codebase ready for primetime or at least QA testing, you can now create a tag to trigger all of the above automagically.

The sample script is aliased in the package.json so it can be run as npm run update-version x.x.x-beta.x. Basically what it does is updates the version of your app via npm version command and then after committing to your branch, creates a tag that is then pushed up to github to trigger continuous integration services to package/build/deploy for you. Version numbers aren't arbitrary and NPM/Github/Travis/Appveyor all use the same conventions for versioning including namespaces for major.minor.patch-[alpha/beta].build.